- * CamelCase denotes the convention of writing compound names without spaces,
- * and capitalizing every term. This function recognizes both upper and lower
- * CamelCase, depending whether the leading character is capitalized or not.
- * The leading part of an upper CamelCase pattern is assumed to contain a
- * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
- * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
- * uses a lowercase first character. In Java, type names follow the upper
- * CamelCase convention, whereas method or field names follow the lower
- * CamelCase convention.
- *
- * The pattern may contain lowercase characters, which will be matched in a case
- * sensitive way. These characters must appear in sequence in the name.
- * For instance, 'NPExcep' will match 'NullPointerException', but not
- * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
- * 'NoPointerException'.
- *
- * Digit characters are treated in a special way. They can be used in the pattern
- * but are not always considered as leading character. For instance, both
- * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
- *
- * Using this method allows matching names to have more parts than the specified
- * pattern (see {@link #camelCaseMatch(char[], char[], boolean)}).
- * For instance, 'HM' , 'HaMa' and 'HMap' patterns will match 'HashMap',
- * 'HatMapper' and also 'HashMapEntry'.
- *
- * CamelCase denotes the convention of writing compound names without spaces,
- * and capitalizing every term. This function recognizes both upper and lower
- * CamelCase, depending whether the leading character is capitalized or not.
- * The leading part of an upper CamelCase pattern is assumed to contain a
- * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
- * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
- * uses a lowercase first character. In Java, type names follow the upper
- * CamelCase convention, whereas method or field names follow the lower
- * CamelCase convention.
- *
- * The pattern may contain lowercase characters, which will be matched in a case
- * sensitive way. These characters must appear in sequence in the name.
- * For instance, 'NPExcep' will match 'NullPointerException', but not
- * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
- * 'NoPointerException'.
- *
- * Digit characters are treated in a special way. They can be used in the pattern
- * but are not always considered as leading character. For instance, both
- * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
- *
- * CamelCase can be restricted to match only the same count of parts. When this
- * restriction is specified the given pattern and the given name must have exactly
- * the same number of parts (i.e. the same number of uppercase characters).
- * For instance, 'HM' , 'HaMa' and 'HMap' patterns will match 'HashMap' and
- * 'HatMapper' but not 'HashMapEntry'.
- *
- * CamelCase denotes the convention of writing compound names without spaces,
- * and capitalizing every term. This function recognizes both upper and lower
- * CamelCase, depending whether the leading character is capitalized or not.
- * The leading part of an upper CamelCase pattern is assumed to contain a
- * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
- * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
- * uses a lowercase first character. In Java, type names follow the upper
- * CamelCase convention, whereas method or field names follow the lower
- * CamelCase convention.
- *
- * The pattern may contain lowercase characters, which will be matched in a case
- * sensitive way. These characters must appear in sequence in the name.
- * For instance, 'NPExcep' will match 'NullPointerException', but not
- * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
- * 'NoPointerException'.
- *
- * Digit characters are treated in a special way. They can be used in the pattern
- * but are not always considered as leading character. For instance, both
- * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
- *
- * Digit characters are treated in a special way. They can be used in the pattern
- * but are not always considered as leading character. For instance, both
- * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
- *
- * Using this method allows matching names to have more parts than the specified
- * pattern (see {@link #camelCaseMatch(char[], int, int, char[], int, int, boolean)}).
- * For instance, 'HM' , 'HaMa' and 'HMap' patterns will match 'HashMap',
- * 'HatMapper' and also 'HashMapEntry'.
- *
- * CamelCase denotes the convention of writing compound names without spaces,
- * and capitalizing every term. This function recognizes both upper and lower
- * CamelCase, depending whether the leading character is capitalized or not.
- * The leading part of an upper CamelCase pattern is assumed to contain
- * a sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
- * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
- * uses a lowercase first character. In Java, type names follow the upper
- * CamelCase convention, whereas method or field names follow the lower
- * CamelCase convention.
- *
- * The pattern may contain lowercase characters, which will be matched in a case
- * sensitive way. These characters must appear in sequence in the name.
- * For instance, 'NPExcep' will match 'NullPointerException', but not
- * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
- * 'NoPointerException'.
- *
- * Digit characters are treated in a special way. They can be used in the pattern
- * but are not always considered as leading character. For instance, both
- * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
- *
- * CamelCase can be restricted to match only the same count of parts. When this
- * restriction is specified the given pattern and the given name must have exactly
- * the same number of parts (i.e. the same number of uppercase characters).
- * For instance, 'HM' , 'HaMa' and 'HMap' patterns will match 'HashMap' and
- * 'HatMapper' but not 'HashMapEntry'.
- *
- * 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 int
- * which therefore always has an even length.
- *
- * Note that each region is disjointed from the following one.
- * E.g. if the regions are { start1, length1, start2, length2 },
- * then start1+length1 will always be smaller than
- * start2.
- *
stringList) {
- if (stringList == null)
- return null;
- char[][] result = new char[stringList.size()][];
- for (int i = 0; i < result.length; i++)
- result[i] = stringList.get(i).toCharArray();
- return result;
-}
-/**
- * Answers a new array adding the second array at the end of first array.
- * It answers null if the first and second are null.
- * If the first array is null, then a new array char[][] is created with second.
- * If the second array is null, then the first array is returned.
- *
- *
- * For example:
- *
- *
- * first = null
- * second = { 'a' }
- * => result = { { ' a' } }
- *
- *
- * first = { { ' a' } }
- * second = null
- * => result = { { ' a' } }
- *
- *
- *
- * first = { { ' a' } }
- * second = { ' b' }
- * => result = { { ' a' } , { ' b' } }
- *
- *
- *
- *
- * @param first the first array to concatenate
- * @param second the array to add at the end of the first array
- * @return a new array adding the second array at the end of first array, or null if the two arrays are null.
- */
-public static final char[][] arrayConcat(char[][] first, char[] second) {
- if (second == null)
- return first;
- if (first == null)
- return new char[][] { second };
-
- int length = first.length;
- char[][] result = new char[length + 1][];
- System.arraycopy(first, 0, result, 0, length);
- result[length] = second;
- return result;
-}
-/**
- * Compares the two char arrays lexicographically.
- *
- * Returns a negative integer if array1 lexicographically precedes the array2,
- * a positive integer if this array1 lexicographically follows the array2, or
- * zero if both arrays are equal.
- *
- * @param array1 the first given array
- * @param array2 the second given array
- * @return the returned value of the comparison between array1 and array2
- * @throws NullPointerException if one of the arrays is null
- * @since 3.3
- */
-public static final int compareTo(char[] array1, char[] array2) {
- int length1 = array1.length;
- int length2 = array2.length;
- int min = Math.min(length1, length2);
- for (int i = 0; i < min; i++) {
- if (array1[i] != array2[i]) {
- return array1[i] - array2[i];
- }
- }
- return length1 - length2;
-}
-/**
- * Compares the two char arrays lexicographically between the given start and end positions.
- *
- * Returns a negative integer if array1 lexicographically precedes the array2,
- * a positive integer if this array1 lexicographically follows the array2, or
- * zero if both arrays are equal.
- * The comparison is done between start and end positions.
- *
- * @param array1 the first given array
- * @param array2 the second given array
- * @param start the starting position to compare (inclusive)
- * @param end the ending position to compare (exclusive)
- *
- * @return the returned value of the comparison between array1 and array2
- * @throws NullPointerException if one of the arrays is null
- * @since 3.7.1
- */
-public static final int compareTo(char[] array1, char[] array2, int start, int end) {
- int length1 = array1.length;
- int length2 = array2.length;
- int min = Math.min(length1, length2);
- min = Math.min(min, end);
- for (int i = start; i < min; i++) {
- if (array1[i] != array2[i]) {
- return array1[i] - array2[i];
- }
- }
- return length1 - length2;
-}
-/**
- * Compares the contents of the two arrays array and prefix. Returns
- *
- * zero if the array starts with the prefix contents
- * the difference between the first two characters that are not equal
- * one if array length is lower than the prefix length and that the prefix starts with the
- * array contents.
- *
- *
- * For example:
- *
- *
- * array = null
- * prefix = null
- * => result = NullPointerException
- *
- *
- *
- * array = { 'a', 'b', 'c', 'd', 'e' }
- * prefix = { 'a', 'b', 'c'}
- * => result = 0
- *
- *
- *
- * array = { 'a', 'b', 'c', 'd', 'e' }
- * prefix = { 'a', 'B', 'c'}
- * => result = 32
- *
- *
- *
- * array = { 'd', 'b', 'c', 'd', 'e' }
- * prefix = { 'a', 'b', 'c'}
- * => result = 3
- *
- *
- *
- * array = { 'a', 'b', 'c', 'd', 'e' }
- * prefix = { 'd', 'b', 'c'}
- * => result = -3
- *
- *
- *
- * array = { 'a', 'a', 'c', 'd', 'e' }
- * prefix = { 'a', 'e', 'c'}
- * => result = -4
- *
- *
- *
- *
- * @param array the given array
- * @param prefix the given prefix
- * @return the result of the comparison (>=0 if array>prefix)
- * @throws NullPointerException if either array or prefix is null
- */
-public static final int compareWith(char[] array, char[] prefix) {
- int arrayLength = array.length;
- int prefixLength = prefix.length;
- int min = Math.min(arrayLength, prefixLength);
- int i = 0;
- while (min-- != 0) {
- char c1 = array[i];
- char c2 = prefix[i++];
- if (c1 != c2)
- return c1 - c2;
- }
- if (prefixLength == i)
- return 0;
- return -1; // array is shorter than prefix (e.g. array:'ab' < prefix:'abc').
-}
-
-/**
- * Answers the concatenation of the two arrays. It answers null if the two arrays are null.
- * If the first array is null, then the second array is returned.
- * If the second array is null, then the first array is returned.
- *
- *
- * For example:
- *
- *
- * first = null
- * second = { 'a' }
- * => result = { ' a' }
- *
- *
- *
- * first = { ' a' }
- * second = null
- * => result = { ' a' }
- *
- *
- *
- * first = { ' a' }
- * second = { ' b' }
- * => result = { ' a' , ' b' }
- *
- *
- *
- *
- * @param first the first array to concatenate
- * @param second the second array to concatenate
- * @return the concatenation of the two arrays, or null if the two arrays are null.
- */
-public static final char[] concat(char[] first, char[] second) {
- if (first == null)
- return second;
- if (second == null)
- return first;
-
- int length1 = first.length;
- int length2 = second.length;
- char[] result = new char[length1 + length2];
- System.arraycopy(first, 0, result, 0, length1);
- System.arraycopy(second, 0, result, length1, length2);
- return result;
-}
-
-/**
- * Answers the concatenation of the three arrays. It answers null if the three arrays are null.
- * If first is null, it answers the concatenation of second and third.
- * If second is null, it answers the concatenation of first and third.
- * If third is null, it answers the concatenation of first and second.
- *
- *
- * For example:
- *
- *
- * first = null
- * second = { 'a' }
- * third = { 'b' }
- * => result = { ' a', 'b' }
- *
- *
- *
- * first = { 'a' }
- * second = null
- * third = { 'b' }
- * => result = { ' a', 'b' }
- *
- *
- *
- * first = { 'a' }
- * second = { 'b' }
- * third = null
- * => result = { ' a', 'b' }
- *
- *
- *
- * first = null
- * second = null
- * third = null
- * => result = null
- *
- *
- *
- * first = { 'a' }
- * second = { 'b' }
- * third = { 'c' }
- * => result = { 'a', 'b', 'c' }
- *
- *
- *
- *
- * @param first the first array to concatenate
- * @param second the second array to concatenate
- * @param third the third array to concatenate
- *
- * @return the concatenation of the three arrays, or null if the three arrays are null.
- */
-public static final char[] concat(
- char[] first,
- char[] second,
- char[] third) {
- if (first == null)
- return concat(second, third);
- if (second == null)
- return concat(first, third);
- if (third == null)
- return concat(first, second);
-
- int length1 = first.length;
- int length2 = second.length;
- int length3 = third.length;
- char[] result = new char[length1 + length2 + length3];
- System.arraycopy(first, 0, result, 0, length1);
- System.arraycopy(second, 0, result, length1, length2);
- System.arraycopy(third, 0, result, length1 + length2, length3);
- return result;
-}
-
-/**
- * Answers the concatenation of the two arrays inserting the separator character between the two arrays.
- * It answers null if the two arrays are null.
- * If the first array is null, then the second array is returned.
- * If the second array is null, then the first array is returned.
- *
- *
- * For example:
- *
- *
- * first = null
- * second = { 'a' }
- * separator = '/'
- * => result = { ' a' }
- *
- *
- *
- * first = { ' a' }
- * second = null
- * separator = '/'
- * => result = { ' a' }
- *
- *
- *
- * first = { ' a' }
- * second = { ' b' }
- * separator = '/'
- * => result = { ' a' , '/', 'b' }
- *
- *
- *
- *
- * @param first the first array to concatenate
- * @param second the second array to concatenate
- * @param separator the character to insert
- * @return the concatenation of the two arrays inserting the separator character
- * between the two arrays , or null if the two arrays are null.
- */
-public static final char[] concat(
- char[] first,
- char[] second,
- char separator) {
- if (first == null)
- return second;
- if (second == null)
- return first;
-
- int length1 = first.length;
- if (length1 == 0)
- return second;
- int length2 = second.length;
- if (length2 == 0)
- return first;
-
- char[] result = new char[length1 + length2 + 1];
- System.arraycopy(first, 0, result, 0, length1);
- result[length1] = separator;
- System.arraycopy(second, 0, result, length1 + 1, length2);
- return result;
-}
-
-/**
- * Answers the concatenation of the two arrays inserting the separator character between the two arrays. Differs from
- * {@link CharOperation#contains(char, char[])} in case second array is a zero length array.
- * It answers null if the two arrays are null.
- * If the first array is null, then the second array is returned.
- * If the second array is null, then the first array is returned.
- * if the second array is zero length array, the separator is appended.
- *
- *
- * For example:
- *
- *
- * first = null
- * second = { 'a' }
- * separator = '/'
- * => result = { ' a' }
- *
- *
- *
- * first = { ' a' }
- * second = null
- * separator = '/'
- * => result = { ' a' }
- *
- *
- *
- * first = { ' a' }
- * second = { ' b' }
- * separator = '/'
- * => result = { ' a' , '/', 'b' }
- *
- *
- *
- * first = { ' a' }
- * second = { '' }
- * separator = '.'
- * => result = { ' a' , '.', }
- *
- *
- *
- *
- * @param first the first array to concatenate
- * @param second the second array to concatenate
- * @param separator the character to insert
- * @return the concatenation of the two arrays inserting the separator character
- * between the two arrays , or null if the two arrays are null. If second array
- * is of zero length, the separator is appended to the first array and returned.
- * @since 3.14
- */
-public static final char[] concatAll(
- char[] first,
- char[] second,
- char separator) {
- if (first == null)
- return second;
- if (second == null)
- return first;
-
- int length1 = first.length;
- if (length1 == 0)
- return second;
- int length2 = second.length;
-
- char[] result = new char[length1 + length2 + 1];
- System.arraycopy(first, 0, result, 0, length1);
- result[length1] = separator;
- if (length2 > 0)
- System.arraycopy(second, 0, result, length1 + 1, length2);
- return result;
-}
-
-/**
- * Answers the concatenation of the three arrays inserting the sep1 character between the
- * first two arrays and sep2 between the last two.
- * It answers null if the three arrays are null.
- * If the first array is null, then it answers the concatenation of second and third inserting
- * the sep2 character between them.
- * If the second array is null, then it answers the concatenation of first and third inserting
- * the sep1 character between them.
- * If the third array is null, then it answers the concatenation of first and second inserting
- * the sep1 character between them.
- *
- *
- * For example:
- *
- *
- * first = null
- * sep1 = '/'
- * second = { 'a' }
- * sep2 = ':'
- * third = { 'b' }
- * => result = { ' a' , ':', 'b' }
- *
- *
- *
- * first = { 'a' }
- * sep1 = '/'
- * second = null
- * sep2 = ':'
- * third = { 'b' }
- * => result = { ' a' , '/', 'b' }
- *
- *
- *
- * first = { 'a' }
- * sep1 = '/'
- * second = { 'b' }
- * sep2 = ':'
- * third = null
- * => result = { ' a' , '/', 'b' }
- *
- *
- *
- * first = { 'a' }
- * sep1 = '/'
- * second = { 'b' }
- * sep2 = ':'
- * third = { 'c' }
- * => result = { ' a' , '/', 'b' , ':', 'c' }
- *
- *
- *
- *
- * @param first the first array to concatenate
- * @param sep1 the character to insert
- * @param second the second array to concatenate
- * @param sep2 the character to insert
- * @param third the second array to concatenate
- * @return the concatenation of the three arrays inserting the sep1 character between the
- * two arrays and sep2 between the last two.
- */
-public static final char[] concat(
- char[] first,
- char sep1,
- char[] second,
- char sep2,
- char[] third) {
- if (first == null)
- return concat(second, third, sep2);
- if (second == null)
- return concat(first, third, sep1);
- if (third == null)
- return concat(first, second, sep1);
-
- int length1 = first.length;
- int length2 = second.length;
- int length3 = third.length;
- char[] result = new char[length1 + length2 + length3 + 2];
- System.arraycopy(first, 0, result, 0, length1);
- result[length1] = sep1;
- System.arraycopy(second, 0, result, length1 + 1, length2);
- result[length1 + length2 + 1] = sep2;
- System.arraycopy(third, 0, result, length1 + length2 + 2, length3);
- return result;
-}
-/**
- * Answers the concatenation of the two arrays inserting the separator character between the two arrays.
- * It answers null if the two arrays are null.
- * If the first array is null or is empty, then the second array is returned.
- * If the second array is null or is empty, then the first array is returned.
- *
- *
- * For example:
- *
- *
- * first = null
- * second = { 'a' }
- * separator = '/'
- * => result = { ' a' }
- *
- *
- *
- * first = { ' a' }
- * second = null
- * separator = '/'
- * => result = { ' a' }
- *
- *
- *
- * first = { ' a' }
- * second = { ' b' }
- * separator = '/'
- * => result = { ' a' , '/', 'b' }
- *
- *
- *
- * first = { ' a' }
- * second = { }
- * separator = '/'
- * => result = { ' a'}
- *
- *
-
- *
- *
- * @param first the first array to concatenate
- * @param second the second array to concatenate
- * @param separator the character to insert
- * @return the concatenation of the two arrays inserting the separator character
- * between the two arrays , or null if the two arrays are null.
- * @since 3.12
- */
-public static final char[] concatNonEmpty(
- char[] first,
- char[] second,
- char separator) {
- if (first == null || first.length == 0)
- return second;
- if (second == null || second.length == 0)
- return first;
- return concat(first, second, separator);
-}
-/**
- * Answers the concatenation of the three arrays inserting the sep1 character between the
- * first two arrays and sep2 between the last two.
- * It answers null if the three arrays are null.
- * If the first array is null or empty, then it answers the concatenation of second and third inserting
- * the sep2 character between them.
- * If the second array is null or empty, then it answers the concatenation of first and third inserting
- * the sep1 character between them.
- * If the third array is null or empty, then it answers the concatenation of first and second inserting
- * the sep1 character between them.
- *
- *
- * For example:
- *
- *
- * first = null
- * sep1 = '/'
- * second = { 'a' }
- * sep2 = ':'
- * third = { 'b' }
- * => result = { ' a' , ':', 'b' }
- *
- *
- *
- * first = { 'a' }
- * sep1 = '/'
- * second = null
- * sep2 = ':'
- * third = { 'b' }
- * => result = { ' a' , '/', 'b' }
- *
- *
- *
- * first = { 'a' }
- * sep1 = '/'
- * second = { 'b' }
- * sep2 = ':'
- * third = null
- * => result = { ' a' , '/', 'b' }
- *
- *
- *
- * first = { 'a' }
- * sep1 = '/'
- * second = { 'b' }
- * sep2 = ':'
- * third = { 'c' }
- * => result = { ' a' , '/', 'b' , ':', 'c' }
- *
- *
- *
- * first = { 'a' }
- * sep1 = '/'
- * second = { }
- * sep2 = ':'
- * third = { 'c' }
- * => result = { ' a', ':', 'c' }
- *
- *
- *
- *
- * @param first the first array to concatenate
- * @param sep1 the character to insert
- * @param second the second array to concatenate
- * @param sep2 the character to insert
- * @param third the second array to concatenate
- * @return the concatenation of the three arrays inserting the sep1 character between the
- * two arrays and sep2 between the last two.
- * @since 3.12
- */
-public static final char[] concatNonEmpty(
- char[] first,
- char sep1,
- char[] second,
- char sep2,
- char[] third) {
- if (first == null || first.length == 0)
- return concatNonEmpty(second, third, sep2);
- if (second == null || second.length == 0)
- return concatNonEmpty(first, third, sep1);
- if (third == null || third.length == 0)
- return concatNonEmpty(first, second, sep1);
-
- return concat(first, sep1, second, sep2, third);
-}
-
-/**
- * Answers a new array with prepending the prefix character and appending the suffix
- * character at the end of the array. If array is null, it answers a new array containing the
- * prefix and the suffix characters.
- *
- *
- * For example:
- *
- *
- * prefix = 'a'
- * array = { 'b' }
- * suffix = 'c'
- * => result = { 'a', 'b' , 'c' }
- *
- *
- *
- * prefix = 'a'
- * array = null
- * suffix = 'c'
- * => result = { 'a', 'c' }
- *
- *
- *
- * @param prefix the prefix character
- * @param array the array that is concatenated with the prefix and suffix characters
- * @param suffix the suffix character
- * @return the new array
- */
-public static final char[] concat(char prefix, char[] array, char suffix) {
- if (array == null)
- return new char[] { prefix, suffix };
-
- int length = array.length;
- char[] result = new char[length + 2];
- result[0] = prefix;
- System.arraycopy(array, 0, result, 1, length);
- result[length + 1] = suffix;
- return result;
-}
-
-/**
- * Answers the concatenation of the given array parts using the given separator between each
- * part and prepending the given name at the beginning.
- *
- *
- * For example:
- *
- *
- * name = { 'c' }
- * array = { { 'a' }, { 'b' } }
- * separator = '.'
- * => result = { 'a', '.', 'b' , '.', 'c' }
- *
- *
- *
- * name = null
- * array = { { 'a' }, { 'b' } }
- * separator = '.'
- * => result = { 'a', '.', 'b' }
- *
- *
- * name = { ' c' }
- * array = null
- * separator = '.'
- * => result = { 'c' }
- *
- *
- *
- * @param name the given name
- * @param array the given array
- * @param separator the given separator
- * @return the concatenation of the given array parts using the given separator between each
- * part and prepending the given name at the beginning
- */
-public static final char[] concatWith(
- char[] name,
- char[][] array,
- char separator) {
- int nameLength = name == null ? 0 : name.length;
- if (nameLength == 0)
- return concatWith(array, separator);
-
- int length = array == null ? 0 : array.length;
- if (length == 0)
- return name;
-
- int size = nameLength;
- int index = length;
- while (--index >= 0)
- if (array[index].length > 0)
- size += array[index].length + 1;
- char[] result = new char[size];
- index = size;
- for (int i = length - 1; i >= 0; i--) {
- int subLength = array[i].length;
- if (subLength > 0) {
- index -= subLength;
- System.arraycopy(array[i], 0, result, index, subLength);
- result[--index] = separator;
- }
- }
- System.arraycopy(name, 0, result, 0, nameLength);
- return result;
-}
-
-/**
- * Answers the concatenation of the given array parts using the given separator between each
- * part and appending the given name at the end.
- *
- *
- * For example:
- *
- *
- * name = { 'c' }
- * array = { { 'a' }, { 'b' } }
- * separator = '.'
- * => result = { 'a', '.', 'b' , '.', 'c' }
- *
- *
- *
- * name = null
- * array = { { 'a' }, { 'b' } }
- * separator = '.'
- * => result = { 'a', '.', 'b' }
- *
- *
- * name = { ' c' }
- * array = null
- * separator = '.'
- * => result = { 'c' }
- *
- *
- *
- * @param array the given array
- * @param name the given name
- * @param separator the given separator
- * @return the concatenation of the given array parts using the given separator between each
- * part and appending the given name at the end
- */
-public static final char[] concatWith(
- char[][] array,
- char[] name,
- char separator) {
- int nameLength = name == null ? 0 : name.length;
- if (nameLength == 0)
- return concatWith(array, separator);
-
- int length = array == null ? 0 : array.length;
- if (length == 0)
- return name;
-
- int size = nameLength;
- int index = length;
- while (--index >= 0)
- if (array[index].length > 0)
- size += array[index].length + 1;
- char[] result = new char[size];
- index = 0;
- for (int i = 0; i < length; i++) {
- int subLength = array[i].length;
- if (subLength > 0) {
- System.arraycopy(array[i], 0, result, index, subLength);
- index += subLength;
- result[index++] = separator;
- }
- }
- System.arraycopy(name, 0, result, index, nameLength);
- return result;
-}
-
-/**
- * Answers the concatenation of the given array parts using the given separator between each part.
- *
- *
- * For example:
- *
- *
- * array = { { 'a' }, { 'b' } }
- * separator = '.'
- * => result = { 'a', '.', 'b' }
- *
- *
- *
- * array = null
- * separator = '.'
- * => result = { }
- *
- *
- *
- * @param array the given array
- * @param separator the given separator
- * @return the concatenation of the given array parts using the given separator between each part
- */
-public static final char[] concatWith(char[][] array, char separator) {
- int length = array == null ? 0 : array.length;
- if (length == 0)
- return CharOperation.NO_CHAR;
-
- int size = length - 1;
- int index = length;
- while (--index >= 0) {
- if (array[index].length == 0)
- size--;
- else
- size += array[index].length;
- }
- if (size <= 0)
- return CharOperation.NO_CHAR;
- char[] result = new char[size];
- index = length;
- while (--index >= 0) {
- length = array[index].length;
- if (length > 0) {
- System.arraycopy(
- array[index],
- 0,
- result,
- (size -= length),
- length);
- if (--size >= 0)
- result[size] = separator;
- }
- }
- return result;
-}
-
-/**
- * Answers the concatenation of the given array parts using the given separator between each part
- * irrespective of whether an element is a zero length array or not.
- *
- *
- * For example:
- *
- *
- * array = { { 'a' }, {}, { 'b' } }
- * separator = ''
- * => result = { 'a', '/', '/', 'b' }
- *
- *
- *
- * array = { { 'a' }, { 'b' } }
- * separator = '.'
- * => result = { 'a', '.', 'b' }
- *
- *
- *
- * array = null
- * separator = '.'
- * => result = { }
- *
- *
- *
- * @param array the given array
- * @param separator the given separator
- * @return the concatenation of the given array parts using the given separator between each part
- * @since 3.12
- */
-public static final char[] concatWithAll(char[][] array, char separator) {
- int length = array == null ? 0 : array.length;
- if (length == 0)
- return CharOperation.NO_CHAR;
-
- int size = length - 1;
- int index = length;
- while (--index >= 0) {
- size += array[index].length;
- }
- char[] result = new char[size];
- index = length;
- while (--index >= 0) {
- length = array[index].length;
- if (length > 0) {
- System.arraycopy(
- array[index],
- 0,
- result,
- (size -= length),
- length);
- }
- if (--size >= 0)
- result[size] = separator;
- }
- return result;
-}
-
-/**
- * Answers true if the array contains an occurrence of character, false otherwise.
- *
- *
- *
- * For example:
- *
- *
- * character = 'c'
- * array = { { ' a' }, { ' b' } }
- * result => false
- *
- *
- *
- * character = 'a'
- * array = { { ' a' }, { ' b' } }
- * result => true
- *
- *
- *
- *
- * @param character the character to search
- * @param array the array in which the search is done
- * @return true if the array contains an occurrence of character, false otherwise.
- * @throws NullPointerException if array is null.
- */
-public static final boolean contains(char character, char[][] array) {
- for (int i = array.length; --i >= 0;) {
- char[] subarray = array[i];
- for (int j = subarray.length; --j >= 0;)
- if (subarray[j] == character)
- return true;
- }
- return false;
-}
-
-/**
- * Answers true if the array contains an occurrence of character, false otherwise.
- *
- *
- *
- * For example:
- *
- *
- * character = 'c'
- * array = { ' b' }
- * result => false
- *
- *
- *
- * character = 'a'
- * array = { ' a' , ' b' }
- * result => true
- *
- *
- *
- *
- * @param character the character to search
- * @param array the array in which the search is done
- * @return true if the array contains an occurrence of character, false otherwise.
- * @throws NullPointerException if array is null.
- */
-public static final boolean contains(char character, char[] array) {
- for (int i = array.length; --i >= 0;)
- if (array[i] == character)
- return true;
- return false;
-}
-
-/**
- * Answers true if the array contains an occurrence of one of the characters, false otherwise.
- *
- *
- *
- * For example:
- *
- *
- * characters = { 'c', 'd' }
- * array = { 'a', ' b' }
- * result => false
- *
- *
- *
- * characters = { 'c', 'd' }
- * array = { 'a', ' b', 'c' }
- * result => true
- *
- *
- *
- *
- * @param characters the characters to search
- * @param array the array in which the search is done
- * @return true if the array contains an occurrence of one of the characters, false otherwise.
- * @throws NullPointerException if array is null.
- * @since 3.1
- */
-public static final boolean contains(char[] characters, char[] array) {
- for (int i = array.length; --i >= 0;)
- for (int j = characters.length; --j >= 0;)
- if (array[i] == characters[j])
- return true;
- return false;
-}
-
-/**
- * Does the given array contain a char sequence that is equal to the give sequence?
- * @return true if sequence is equal to an element in array
- * @since 3.14
- */
-public static boolean containsEqual(char[][] array, char[] sequence) {
- for (int i = 0; i < array.length; i++) {
- if (equals(array[i], sequence))
- return true;
- }
- return false;
-}
-
-/**
- * Answers a deep copy of the toCopy array.
- *
- * @param toCopy the array to copy
- * @return a deep copy of the toCopy array.
- */
-
-public static final char[][] deepCopy(char[][] toCopy) {
- int toCopyLength = toCopy.length;
- char[][] result = new char[toCopyLength][];
- for (int i = 0; i < toCopyLength; i++) {
- char[] toElement = toCopy[i];
- int toElementLength = toElement.length;
- char[] resultElement = new char[toElementLength];
- System.arraycopy(toElement, 0, resultElement, 0, toElementLength);
- result[i] = resultElement;
- }
- return result;
-}
-
-/**
- * Return true if array ends with the sequence of characters contained in toBeFound,
- * otherwise false.
- *
- *
- * For example:
- *
- *
- * array = { 'a', 'b', 'c', 'd' }
- * toBeFound = { 'b', 'c' }
- * result => false
- *
- *
- *
- * array = { 'a', 'b', 'c' }
- * toBeFound = { 'b', 'c' }
- * result => true
- *
- *
- *
- *
- * @param array the array to check
- * @param toBeFound the array to find
- * @return true if array ends with the sequence of characters contained in toBeFound,
- * otherwise false.
- * @throws NullPointerException if array is null or toBeFound is null
- */
-public static final boolean endsWith(char[] array, char[] toBeFound) {
- int i = toBeFound.length;
- int j = array.length - i;
-
- if (j < 0)
- return false;
- while (--i >= 0)
- if (toBeFound[i] != array[i + j])
- return false;
- return true;
-}
-
-/**
- * Answers true if the two arrays are identical character by character, otherwise false.
- * The equality is case sensitive.
- *
- *
- * For example:
- *
- *
- * first = null
- * second = null
- * result => true
- *
- *
- *
- * first = { { } }
- * second = null
- * result => false
- *
- *
- *
- * first = { { 'a' } }
- * second = { { 'a' } }
- * result => true
- *
- *
- *
- * first = { { 'A' } }
- * second = { { 'a' } }
- * result => false
- *
- *
- *
- * @param first the first array
- * @param second the second array
- * @return true if the two arrays are identical character by character, otherwise false
- */
-public static final boolean equals(char[][] first, char[][] second) {
- if (first == second)
- return true;
- if (first == null || second == null)
- return false;
- if (first.length != second.length)
- return false;
-
- for (int i = first.length; --i >= 0;)
- if (!equals(first[i], second[i]))
- return false;
- return true;
-}
-
-/**
- * If isCaseSensite is true, answers true if the two arrays are identical character
- * by character, otherwise false.
- * If it is false, answers true if the two arrays are identical character by
- * character without checking the case, otherwise false.
- *
- *
- * For example:
- *
- *
- * first = null
- * second = null
- * isCaseSensitive = true
- * result => true
- *
- *
- *
- * first = { { } }
- * second = null
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- * first = { { 'A' } }
- * second = { { 'a' } }
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- * first = { { 'A' } }
- * second = { { 'a' } }
- * isCaseSensitive = false
- * result => true
- *
- *
- *
- *
- * @param first the first array
- * @param second the second array
- * @param isCaseSensitive check whether or not the equality should be case sensitive
- * @return true if the two arrays are identical character by character according to the value
- * of isCaseSensitive, otherwise false
- */
-public static final boolean equals(
- char[][] first,
- char[][] second,
- boolean isCaseSensitive) {
-
- if (isCaseSensitive) {
- return equals(first, second);
- }
- if (first == second)
- return true;
- if (first == null || second == null)
- return false;
- if (first.length != second.length)
- return false;
-
- for (int i = first.length; --i >= 0;)
- if (!equals(first[i], second[i], false))
- return false;
- return true;
-}
-
-/**
- * Answers true if the two arrays are identical character by character, otherwise false.
- * The equality is case sensitive.
- *
- *
- * For example:
- *
- *
- * first = null
- * second = null
- * result => true
- *
- *
- *
- * first = { }
- * second = null
- * result => false
- *
- *
- *
- * first = { 'a' }
- * second = { 'a' }
- * result => true
- *
- *
- *
- * first = { 'a' }
- * second = { 'A' }
- * result => false
- *
- *
- *
- * @param first the first array
- * @param second the second array
- * @return true if the two arrays are identical character by character, otherwise false
- */
-public static final boolean equals(char[] first, char[] second) {
- return Arrays.equals(first, second);
-}
-
-/**
- * Answers true if the first array is identical character by character to a portion of the second array
- * delimited from position secondStart (inclusive) to secondEnd(exclusive), otherwise false.
- * The equality is case sensitive.
- *
- *
- * For example:
- *
- *
- * first = null
- * second = null
- * secondStart = 0
- * secondEnd = 0
- * result => true
- *
- *
- *
- * first = { }
- * second = null
- * secondStart = 0
- * secondEnd = 0
- * result => false
- *
- *
- *
- * first = { 'a' }
- * second = { 'a' }
- * secondStart = 0
- * secondEnd = 1
- * result => true
- *
- *
- *
- * first = { 'a' }
- * second = { 'A' }
- * secondStart = 0
- * secondEnd = 1
- * result => false
- *
- *
- *
- * @param first the first array
- * @param second the second array
- * @param secondStart inclusive start position in the second array to compare
- * @param secondEnd exclusive end position in the second array to compare
- * @return true if the first array is identical character by character to fragment of second array ranging from secondStart to secondEnd-1, otherwise false
- * @since 3.0
- */
-public static final boolean equals(char[] first, char[] second, int secondStart, int secondEnd) {
- return equals(first, second, secondStart, secondEnd, true);
-}
-/**
- * Answers true if the first array is identical character by character to a portion of the second array
- * delimited from position secondStart (inclusive) to secondEnd(exclusive), otherwise false. The equality could be either
- * case sensitive or case insensitive according to the value of the isCaseSensitive parameter.
- *
- * For example:
- *
- *
- * first = null
- * second = null
- * secondStart = 0
- * secondEnd = 0
- * isCaseSensitive = false
- * result => true
- *
- *
- *
- * first = { }
- * second = null
- * secondStart = 0
- * secondEnd = 0
- * isCaseSensitive = false
- * result => false
- *
- *
- *
- * first = { 'a' }
- * second = { 'a' }
- * secondStart = 0
- * secondEnd = 1
- * isCaseSensitive = true
- * result => true
- *
- *
- *
- * first = { 'a' }
- * second = { 'A' }
- * secondStart = 0
- * secondEnd = 1
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- * first = { 'a' }
- * second = { 'A' }
- * secondStart = 0
- * secondEnd = 1
- * isCaseSensitive = false
- * result => true
- *
- *
- *
- * @param first the first array
- * @param second the second array
- * @param secondStart inclusive start position in the second array to compare
- * @param secondEnd exclusive end position in the second array to compare
- * @param isCaseSensitive check whether or not the equality should be case sensitive
- * @return true if the first array is identical character by character to fragment of second array ranging from secondStart to secondEnd-1, otherwise false
- * @since 3.2
- */
-public static final boolean equals(char[] first, char[] second, int secondStart, int secondEnd, boolean isCaseSensitive) {
- if (first == second)
- return true;
- if (first == null || second == null)
- return false;
- if (first.length != secondEnd - secondStart)
- return false;
- if (isCaseSensitive) {
- for (int i = first.length; --i >= 0;)
- if (first[i] != second[i+secondStart])
- return false;
- } else {
- for (int i = first.length; --i >= 0;)
- if (ScannerHelper.toLowerCase(first[i]) != ScannerHelper.toLowerCase(second[i+secondStart]))
- return false;
- }
- return true;
-}
-
-/**
- * If isCaseSensite is true, answers true if the two arrays are identical character
- * by character, otherwise false.
- * If it is false, answers true if the two arrays are identical character by
- * character without checking the case, otherwise false.
- *
- *
- * For example:
- *
- *
- * first = null
- * second = null
- * isCaseSensitive = true
- * result => true
- *
- *
- *
- * first = { }
- * second = null
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- * first = { 'A' }
- * second = { 'a' }
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- * first = { 'A' }
- * second = { 'a' }
- * isCaseSensitive = false
- * result => true
- *
- *
- *
- *
- * @param first the first array
- * @param second the second array
- * @param isCaseSensitive check whether or not the equality should be case sensitive
- * @return true if the two arrays are identical character by character according to the value
- * of isCaseSensitive, otherwise false
- */
-public static final boolean equals(
- char[] first,
- char[] second,
- boolean isCaseSensitive) {
-
- if (isCaseSensitive) {
- return equals(first, second);
- }
- if (first == second)
- return true;
- if (first == null || second == null)
- return false;
- if (first.length != second.length)
- return false;
-
- for (int i = first.length; --i >= 0;)
- if (ScannerHelper.toLowerCase(first[i])
- != ScannerHelper.toLowerCase(second[i]))
- return false;
- return true;
-}
-
-/**
- * If isCaseSensite is true, the equality is case sensitive, otherwise it is case insensitive.
- *
- * Answers true if the name contains the fragment at the starting index startIndex, otherwise false.
- *
- *
- * For example:
- *
- *
- * fragment = { 'b', 'c' , 'd' }
- * name = { 'a', 'b', 'c' , 'd' }
- * startIndex = 1
- * isCaseSensitive = true
- * result => true
- *
- *
- *
- * fragment = { 'b', 'c' , 'd' }
- * name = { 'a', 'b', 'C' , 'd' }
- * startIndex = 1
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- * fragment = { 'b', 'c' , 'd' }
- * name = { 'a', 'b', 'C' , 'd' }
- * startIndex = 0
- * isCaseSensitive = false
- * result => false
- *
- *
- *
- * fragment = { 'b', 'c' , 'd' }
- * name = { 'a', 'b'}
- * startIndex = 0
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- *
- * @param fragment the fragment to check
- * @param name the array to check
- * @param startIndex the starting index
- * @param isCaseSensitive check whether or not the equality should be case sensitive
- * @return true if the name contains the fragment at the starting index startIndex according to the
- * value of isCaseSensitive, otherwise false.
- * @throws NullPointerException if fragment or name is null.
- */
-public static final boolean fragmentEquals(
- char[] fragment,
- char[] name,
- int startIndex,
- boolean isCaseSensitive) {
-
- int max = fragment.length;
- if (name.length < max + startIndex)
- return false;
- if (isCaseSensitive) {
- for (int i = max;
- --i >= 0;
- ) // assumes the prefix is not larger than the name
- if (fragment[i] != name[i + startIndex])
- return false;
- return true;
- }
- for (int i = max;
- --i >= 0;
- ) // assumes the prefix is not larger than the name
- if (ScannerHelper.toLowerCase(fragment[i])
- != ScannerHelper.toLowerCase(name[i + startIndex]))
- return false;
- return true;
-}
-
-/**
- * Answers a hashcode for the array
- *
- * @param array the array for which a hashcode is required
- * @return the hashcode
- */
-public static final int hashCode(char[] array) {
- int hash = Arrays.hashCode(array);
- return hash & 0x7FFFFFFF;
-}
-
-/**
- * Answers true if c is a whitespace according to the JLS (\u0009, \u000a, \u000c, \u000d, \u0020), otherwise false.
- *
- *
- * For example:
- *
- *
- * c = ' '
- * result => true
- *
- *
- *
- * c = '\u3000'
- * result => false
- *
- *
- *
- *
- * @param c the character to check
- * @return true if c is a whitespace according to the JLS, otherwise false.
- */
-public static boolean isWhitespace(char c) {
- return c < ScannerHelper.MAX_OBVIOUS && ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_JLS_SPACE) != 0);
-}
-
-/**
- * Answers the first index in the array for which the corresponding character is
- * equal to toBeFound. Answers -1 if no occurrence of this character is found.
- *
- *
- * For example:
- *
- *
- * toBeFound = 'c'
- * array = { ' a', 'b', 'c', 'd' }
- * result => 2
- *
- *
- *
- * toBeFound = 'e'
- * array = { ' a', 'b', 'c', 'd' }
- * result => -1
- *
- *
- *
- *
- * @param toBeFound the character to search
- * @param array the array to be searched
- * @return the first index in the array for which the corresponding character is
- * equal to toBeFound, -1 otherwise
- * @throws NullPointerException if array is null
- */
-public static final int indexOf(char toBeFound, char[] array) {
- return indexOf(toBeFound, array, 0);
-}
-
-/**
- * Answers the first index in the array for which the toBeFound array is a matching
- * subarray following the case rule. Answers -1 if no match is found.
- *
- *
- * For example:
- *
- *
- * toBeFound = { 'c' }
- * array = { ' a', 'b', 'c', 'd' }
- * result => 2
- *
- *
- *
- * toBeFound = { 'e' }
- * array = { ' a', 'b', 'c', 'd' }
- * result => -1
- *
- *
- *
- *
- * @param toBeFound the subarray to search
- * @param array the array to be searched
- * @param isCaseSensitive flag to know if the matching should be case sensitive
- * @return the first index in the array for which the toBeFound array is a matching
- * subarray following the case rule, -1 otherwise
- * @throws NullPointerException if array is null or toBeFound is null
- * @since 3.2
- */
-public static final int indexOf(char[] toBeFound, char[] array, boolean isCaseSensitive) {
- return indexOf(toBeFound, array, isCaseSensitive, 0);
-}
-
-/**
- * Answers the first index in the array for which the toBeFound array is a matching
- * subarray following the case rule starting at the index start. Answers -1 if no match is found.
- *
- *
- * For example:
- *
- *
- * toBeFound = { 'c' }
- * array = { ' a', 'b', 'c', 'd' }
- * result => 2
- *
- *
- *
- * toBeFound = { 'e' }
- * array = { ' a', 'b', 'c', 'd' }
- * result => -1
- *
- *
- *
- *
- * @param toBeFound the subarray to search
- * @param array the array to be searched
- * @param isCaseSensitive flag to know if the matching should be case sensitive
- * @param start the starting index
- * @return the first index in the array for which the toBeFound array is a matching
- * subarray following the case rule starting at the index start, -1 otherwise
- * @throws NullPointerException if array is null or toBeFound is null
- * @since 3.2
- */
-public static final int indexOf(final char[] toBeFound, final char[] array, final boolean isCaseSensitive, final int start) {
- return indexOf(toBeFound, array, isCaseSensitive, start, array.length);
-}
-
-/**
- * Answers the first index in the array for which the toBeFound array is a matching
- * subarray following the case rule starting at the index start. Answers -1 if no match is found.
- *
- *
- * For example:
- *
- *
- * toBeFound = { 'c' }
- * array = { ' a', 'b', 'c', 'd' }
- * result => 2
- *
- *
- *
- * toBeFound = { 'e' }
- * array = { ' a', 'b', 'c', 'd' }
- * result => -1
- *
- *
- *
- *
- * @param toBeFound the subarray to search
- * @param array the array to be searched
- * @param isCaseSensitive flag to know if the matching should be case sensitive
- * @param start the starting index (inclusive)
- * @param end the end index (exclusive)
- * @return the first index in the array for which the toBeFound array is a matching
- * subarray following the case rule starting at the index start, -1 otherwise
- * @throws NullPointerException if array is null or toBeFound is null
- * @since 3.2
- */
-public static final int indexOf(final char[] toBeFound, final char[] array, final boolean isCaseSensitive, final int start, final int end) {
- final int arrayLength = end;
- final int toBeFoundLength = toBeFound.length;
- if (toBeFoundLength > arrayLength || start < 0) return -1;
- if (toBeFoundLength == 0) return 0;
- if (toBeFoundLength == arrayLength) {
- if (isCaseSensitive) {
- for (int i = start; i < arrayLength; i++) {
- if (array[i] != toBeFound[i]) return -1;
- }
- return 0;
- } else {
- for (int i = start; i < arrayLength; i++) {
- if (ScannerHelper.toLowerCase(array[i]) != ScannerHelper.toLowerCase(toBeFound[i])) return -1;
- }
- return 0;
- }
- }
- if (isCaseSensitive) {
- arrayLoop: for (int i = start, max = arrayLength - toBeFoundLength + 1; i < max; i++) {
- if (array[i] == toBeFound[0]) {
- for (int j = 1; j < toBeFoundLength; j++) {
- if (array[i + j] != toBeFound[j]) continue arrayLoop;
- }
- return i;
- }
- }
- } else {
- arrayLoop: for (int i = start, max = arrayLength - toBeFoundLength + 1; i < max; i++) {
- if (ScannerHelper.toLowerCase(array[i]) == ScannerHelper.toLowerCase(toBeFound[0])) {
- for (int j = 1; j < toBeFoundLength; j++) {
- if (ScannerHelper.toLowerCase(array[i + j]) != ScannerHelper.toLowerCase(toBeFound[j])) continue arrayLoop;
- }
- return i;
- }
- }
- }
- return -1;
-}
-
-/**
- * Answers the first index in the array for which the corresponding character is
- * equal to toBeFound starting the search at index start.
- * Answers -1 if no occurrence of this character is found.
- *
- *
- * For example:
- *
- *
- * toBeFound = 'c'
- * array = { ' a', 'b', 'c', 'd' }
- * start = 2
- * result => 2
- *
- *
- *
- * toBeFound = 'c'
- * array = { ' a', 'b', 'c', 'd' }
- * start = 3
- * result => -1
- *
- *
- *
- * toBeFound = 'e'
- * array = { ' a', 'b', 'c', 'd' }
- * start = 1
- * result => -1
- *
- *
- *
- *
- * @param toBeFound the character to search
- * @param array the array to be searched
- * @param start the starting index
- * @return the first index in the array for which the corresponding character is
- * equal to toBeFound, -1 otherwise
- * @throws NullPointerException if array is null
- * @throws ArrayIndexOutOfBoundsException if start is lower than 0
- */
-public static final int indexOf(char toBeFound, char[] array, int start) {
- for (int i = start; i < array.length; i++)
- if (toBeFound == array[i])
- return i;
- return -1;
-}
-
-/**
- * Answers the first index in the array for which the corresponding character is
- * equal to toBeFound starting the search at index start and before the ending index.
- * Answers -1 if no occurrence of this character is found.
- *
- *
- * For example:
- *
- *
- * toBeFound = 'c'
- * array = { ' a', 'b', 'c', 'd' }
- * start = 2
- * result => 2
- *
- *
- *
- * toBeFound = 'c'
- * array = { ' a', 'b', 'c', 'd' }
- * start = 3
- * result => -1
- *
- *
- *
- * toBeFound = 'e'
- * array = { ' a', 'b', 'c', 'd' }
- * start = 1
- * result => -1
- *
- *
- *
- *
- * @param toBeFound the character to search
- * @param array the array to be searched
- * @param start the starting index (inclusive)
- * @param end the ending index (exclusive)
- * @return the first index in the array for which the corresponding character is
- * equal to toBeFound, -1 otherwise
- * @throws NullPointerException if array is null
- * @throws ArrayIndexOutOfBoundsException if start is lower than 0 or ending greater than array length
- * @since 3.2
- */
-public static final int indexOf(char toBeFound, char[] array, int start, int end) {
- for (int i = start; i < end; i++)
- if (toBeFound == array[i])
- return i;
- return -1;
-}
-
-/**
- * Answers the last index in the array for which the corresponding character is
- * equal to toBeFound starting from the end of the array.
- * Answers -1 if no occurrence of this character is found.
- *
- *
- * For example:
- *
- *
- * toBeFound = 'c'
- * array = { ' a', 'b', 'c', 'd' , 'c', 'e' }
- * result => 4
- *
- *
- *
- * toBeFound = 'e'
- * array = { ' a', 'b', 'c', 'd' }
- * result => -1
- *
- *
- *
- *
- * @param toBeFound the character to search
- * @param array the array to be searched
- * @return the last index in the array for which the corresponding character is
- * equal to toBeFound starting from the end of the array, -1 otherwise
- * @throws NullPointerException if array is null
- */
-public static final int lastIndexOf(char toBeFound, char[] array) {
- for (int i = array.length; --i >= 0;)
- if (toBeFound == array[i])
- return i;
- return -1;
-}
-
-/**
- * Answers the last index in the array for which the corresponding character is
- * equal to toBeFound stopping at the index startIndex.
- * Answers -1 if no occurrence of this character is found.
- *
- *
- * For example:
- *
- *
- * toBeFound = 'c'
- * array = { ' a', 'b', 'c', 'd' }
- * startIndex = 2
- * result => 2
- *
- *
- *
- * toBeFound = 'c'
- * array = { ' a', 'b', 'c', 'd', 'e' }
- * startIndex = 3
- * result => -1
- *
- *
- *
- * toBeFound = 'e'
- * array = { ' a', 'b', 'c', 'd' }
- * startIndex = 0
- * result => -1
- *
- *
- *
- *
- * @param toBeFound the character to search
- * @param array the array to be searched
- * @param startIndex the stopping index
- * @return the last index in the array for which the corresponding character is
- * equal to toBeFound stopping at the index startIndex, -1 otherwise
- * @throws NullPointerException if array is null
- * @throws ArrayIndexOutOfBoundsException if startIndex is lower than 0
- */
-public static final int lastIndexOf(
- char toBeFound,
- char[] array,
- int startIndex) {
- for (int i = array.length; --i >= startIndex;)
- if (toBeFound == array[i])
- return i;
- return -1;
-}
-
-/**
- * Answers the last index in the array for which the corresponding character is
- * equal to toBeFound starting from endIndex to startIndex.
- * Answers -1 if no occurrence of this character is found.
- *
- *
- * For example:
- *
- *
- * toBeFound = 'c'
- * array = { ' a', 'b', 'c', 'd' }
- * startIndex = 2
- * endIndex = 2
- * result => 2
- *
- *
- *
- * toBeFound = 'c'
- * array = { ' a', 'b', 'c', 'd', 'e' }
- * startIndex = 3
- * endIndex = 4
- * result => -1
- *
- *
- *
- * toBeFound = 'e'
- * array = { ' a', 'b', 'c', 'd' }
- * startIndex = 0
- * endIndex = 3
- * result => -1
- *
- *
- *
- *
- * @param toBeFound the character to search
- * @param array the array to be searched
- * @param startIndex the stopping index
- * @param endIndex the starting index
- * @return the last index in the array for which the corresponding character is
- * equal to toBeFound starting from endIndex to startIndex, -1 otherwise
- * @throws NullPointerException if array is null
- * @throws ArrayIndexOutOfBoundsException if endIndex is greater or equals to array length or starting is lower than 0
- */
-public static final int lastIndexOf(
- char toBeFound,
- char[] array,
- int startIndex,
- int endIndex) {
- for (int i = endIndex; --i >= startIndex;)
- if (toBeFound == array[i])
- return i;
- return -1;
-}
-
-/**
- * Answers the last portion of a name given a separator.
- *
- *
- * For example,
- *
- * lastSegment("java.lang.Object".toCharArray(),'.') --> Object
- *
- *
- * @param array the array
- * @param separator the given separator
- * @return the last portion of a name given a separator
- * @throws NullPointerException if array is null
- */
-final static public char[] lastSegment(char[] array, char separator) {
- int pos = lastIndexOf(separator, array);
- if (pos < 0)
- return array;
- return subarray(array, pos + 1, array.length);
-}
-
-/**
- * Answers true if the pattern matches the given name, false otherwise. This char[] pattern matching
- * accepts wild-cards '*' and '?'.
- *
- * When not case sensitive, the pattern is assumed to already be lowercased, the
- * name will be lowercased character per character as comparing.
- * If name is null, the answer is false.
- * If pattern is null, the answer is true if name is not null.
- *
- * For example:
- *
- *
- * pattern = { '?', 'b', '*' }
- * name = { 'a', 'b', 'c' , 'd' }
- * isCaseSensitive = true
- * result => true
- *
- *
- *
- * pattern = { '?', 'b', '?' }
- * name = { 'a', 'b', 'c' , 'd' }
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- * pattern = { 'b', '*' }
- * name = { 'a', 'b', 'c' , 'd' }
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- *
- * @param pattern the given pattern
- * @param name the given name
- * @param isCaseSensitive flag to know whether or not the matching should be case sensitive
- * @return true if the pattern matches the given name, false otherwise
- */
-public static final boolean match(
- char[] pattern,
- char[] name,
- boolean isCaseSensitive) {
-
- if (name == null)
- return false; // null name cannot match
- if (pattern == null)
- return true; // null pattern is equivalent to '*'
-
- return match(
- pattern,
- 0,
- pattern.length,
- name,
- 0,
- name.length,
- isCaseSensitive);
-}
-
-/**
- * Answers true if a sub-pattern matches the subpart of the given name, false otherwise.
- * char[] pattern matching, accepting wild-cards '*' and '?'. Can match only subset of name/pattern.
- * end positions are non-inclusive.
- * The subpattern is defined by the patternStart and pattternEnd positions.
- * When not case sensitive, the pattern is assumed to already be lowercased, the
- * name will be lowercased character per character as comparing.
- *
- *
- * For example:
- *
- *
- * pattern = { '?', 'b', '*' }
- * patternStart = 1
- * patternEnd = 3
- * name = { 'a', 'b', 'c' , 'd' }
- * nameStart = 1
- * nameEnd = 4
- * isCaseSensitive = true
- * result => true
- *
- *
- *
- * pattern = { '?', 'b', '*' }
- * patternStart = 1
- * patternEnd = 2
- * name = { 'a', 'b', 'c' , 'd' }
- * nameStart = 1
- * nameEnd = 4
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- *
- * @param pattern the given pattern
- * @param patternStart the given pattern start
- * @param patternEnd the given pattern end
- * @param name the given name
- * @param nameStart the given name start
- * @param nameEnd the given name end
- * @param isCaseSensitive flag to know if the matching should be case sensitive
- * @return true if a sub-pattern matches the subpart of the given name, false otherwise
- */
-public static final boolean match(
- char[] pattern,
- int patternStart,
- int patternEnd,
- char[] name,
- int nameStart,
- int nameEnd,
- boolean isCaseSensitive) {
-
- if (name == null)
- return false; // null name cannot match
- if (pattern == null)
- return true; // null pattern is equivalent to '*'
- int iPattern = patternStart;
- int iName = nameStart;
-
- if (patternEnd < 0)
- patternEnd = pattern.length;
- if (nameEnd < 0)
- nameEnd = name.length;
-
- /* check first segment */
- char patternChar = 0;
- while (true) {
- if (iPattern == patternEnd) {
- if (iName == nameEnd) return true; // the chars match
- return false; // pattern has ended but not the name, no match
- }
- if ((patternChar = pattern[iPattern]) == '*') {
- break;
- }
- if (iName == nameEnd) {
- return false; // name has ended but not the pattern
- }
- if (patternChar
- != (isCaseSensitive
- ? name[iName]
- : ScannerHelper.toLowerCase(name[iName]))
- && patternChar != '?') {
- return false;
- }
- iName++;
- iPattern++;
- }
- /* check sequence of star+segment */
- int segmentStart;
- if (patternChar == '*') {
- segmentStart = ++iPattern; // skip star
- } else {
- segmentStart = 0; // force iName check
- }
- int prefixStart = iName;
- checkSegment : while (iName < nameEnd) {
- if (iPattern == patternEnd) {
- iPattern = segmentStart; // mismatch - restart current segment
- iName = ++prefixStart;
- continue checkSegment;
- }
- /* segment is ending */
- if ((patternChar = pattern[iPattern]) == '*') {
- segmentStart = ++iPattern; // skip start
- if (segmentStart == patternEnd) {
- return true;
- }
- prefixStart = iName;
- continue checkSegment;
- }
- /* check current name character */
- if ((isCaseSensitive ? name[iName] : ScannerHelper.toLowerCase(name[iName]))
- != patternChar
- && patternChar != '?') {
- iPattern = segmentStart; // mismatch - restart current segment
- iName = ++prefixStart;
- continue checkSegment;
- }
- iName++;
- iPattern++;
- }
-
- return (segmentStart == patternEnd)
- || (iName == nameEnd && iPattern == patternEnd)
- || (iPattern == patternEnd - 1 && pattern[iPattern] == '*');
-}
-
-/**
- * Answers true if the pattern matches the filepath using the pathSepatator, false otherwise.
- *
- * Path char[] pattern matching, accepting wild-cards '**', '*' and '?' (using Ant directory tasks
- * conventions, also see "http://jakarta.apache.org/ant/manual/dirtasks.html#defaultexcludes").
- * Path pattern matching is enhancing regular pattern matching in supporting extra rule where '**' represent
- * any folder combination.
- * Special rule:
- * - foo\ is equivalent to foo\**
- * When not case sensitive, the pattern is assumed to already be lowercased, the
- * name will be lowercased character per character as comparing.
- *
- * @param pattern the given pattern
- * @param filepath the given path
- * @param isCaseSensitive to find out whether or not the matching should be case sensitive
- * @param pathSeparator the given path separator
- * @return true if the pattern matches the filepath using the pathSepatator, false otherwise
- */
-public static final boolean pathMatch(
- char[] pattern,
- char[] filepath,
- boolean isCaseSensitive,
- char pathSeparator) {
-
- if (filepath == null)
- return false; // null name cannot match
- if (pattern == null)
- return true; // null pattern is equivalent to '*'
-
- // offsets inside pattern
- int pSegmentStart = pattern[0] == pathSeparator ? 1 : 0;
- int pLength = pattern.length;
- int pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, pSegmentStart+1);
- if (pSegmentEnd < 0) pSegmentEnd = pLength;
-
- // special case: pattern foo\ is equivalent to foo\**
- boolean freeTrailingDoubleStar = pattern[pLength - 1] == pathSeparator;
-
- // offsets inside filepath
- int fSegmentStart, fLength = filepath.length;
- if (filepath[0] != pathSeparator){
- fSegmentStart = 0;
- } else {
- fSegmentStart = 1;
- }
- if (fSegmentStart != pSegmentStart) {
- return false; // both must start with a separator or none.
- }
- int fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, fSegmentStart+1);
- if (fSegmentEnd < 0) fSegmentEnd = fLength;
-
- // first segments
- while (pSegmentStart < pLength
- && !(pSegmentEnd == pLength && freeTrailingDoubleStar
- || (pSegmentEnd == pSegmentStart + 2
- && pattern[pSegmentStart] == '*'
- && pattern[pSegmentStart + 1] == '*'))) {
-
- if (fSegmentStart >= fLength)
- return false;
- if (!CharOperation
- .match(
- pattern,
- pSegmentStart,
- pSegmentEnd,
- filepath,
- fSegmentStart,
- fSegmentEnd,
- isCaseSensitive)) {
- return false;
- }
-
- // jump to next segment
- pSegmentEnd =
- CharOperation.indexOf(
- pathSeparator,
- pattern,
- pSegmentStart = pSegmentEnd + 1);
- // skip separator
- if (pSegmentEnd < 0)
- pSegmentEnd = pLength;
-
- fSegmentEnd =
- CharOperation.indexOf(
- pathSeparator,
- filepath,
- fSegmentStart = fSegmentEnd + 1);
- // skip separator
- if (fSegmentEnd < 0) fSegmentEnd = fLength;
- }
-
- /* check sequence of doubleStar+segment */
- int pSegmentRestart;
- if ((pSegmentStart >= pLength && freeTrailingDoubleStar)
- || (pSegmentEnd == pSegmentStart + 2
- && pattern[pSegmentStart] == '*'
- && pattern[pSegmentStart + 1] == '*')) {
- pSegmentEnd =
- CharOperation.indexOf(
- pathSeparator,
- pattern,
- pSegmentStart = pSegmentEnd + 1);
- // skip separator
- if (pSegmentEnd < 0) pSegmentEnd = pLength;
- pSegmentRestart = pSegmentStart;
- } else {
- if (pSegmentStart >= pLength) return fSegmentStart >= fLength; // true if filepath is done too.
- pSegmentRestart = 0; // force fSegmentStart check
- }
- int fSegmentRestart = fSegmentStart;
- checkSegment : while (fSegmentStart < fLength) {
-
- if (pSegmentStart >= pLength) {
- if (freeTrailingDoubleStar) return true;
- // mismatch - restart current path segment
- pSegmentEnd =
- CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentRestart);
- if (pSegmentEnd < 0) pSegmentEnd = pLength;
-
- fSegmentRestart =
- CharOperation.indexOf(pathSeparator, filepath, fSegmentRestart + 1);
- // skip separator
- if (fSegmentRestart < 0) {
- fSegmentRestart = fLength;
- } else {
- fSegmentRestart++;
- }
- fSegmentEnd =
- CharOperation.indexOf(pathSeparator, filepath, fSegmentStart = fSegmentRestart);
- if (fSegmentEnd < 0) fSegmentEnd = fLength;
- continue checkSegment;
- }
-
- /* path segment is ending */
- if (pSegmentEnd == pSegmentStart + 2
- && pattern[pSegmentStart] == '*'
- && pattern[pSegmentStart + 1] == '*') {
- pSegmentEnd =
- CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentEnd + 1);
- // skip separator
- if (pSegmentEnd < 0) pSegmentEnd = pLength;
- pSegmentRestart = pSegmentStart;
- fSegmentRestart = fSegmentStart;
- if (pSegmentStart >= pLength) return true;
- continue checkSegment;
- }
- /* chech current path segment */
- if (!CharOperation.match(
- pattern,
- pSegmentStart,
- pSegmentEnd,
- filepath,
- fSegmentStart,
- fSegmentEnd,
- isCaseSensitive)) {
- // mismatch - restart current path segment
- pSegmentEnd =
- CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentRestart);
- if (pSegmentEnd < 0) pSegmentEnd = pLength;
-
- fSegmentRestart =
- CharOperation.indexOf(pathSeparator, filepath, fSegmentRestart + 1);
- // skip separator
- if (fSegmentRestart < 0) {
- fSegmentRestart = fLength;
- } else {
- fSegmentRestart++;
- }
- fSegmentEnd =
- CharOperation.indexOf(pathSeparator, filepath, fSegmentStart = fSegmentRestart);
- if (fSegmentEnd < 0) fSegmentEnd = fLength;
- continue checkSegment;
- }
- // jump to next segment
- pSegmentEnd =
- CharOperation.indexOf(
- pathSeparator,
- pattern,
- pSegmentStart = pSegmentEnd + 1);
- // skip separator
- if (pSegmentEnd < 0)
- pSegmentEnd = pLength;
-
- fSegmentEnd =
- CharOperation.indexOf(
- pathSeparator,
- filepath,
- fSegmentStart = fSegmentEnd + 1);
- // skip separator
- if (fSegmentEnd < 0)
- fSegmentEnd = fLength;
- }
-
- return (pSegmentRestart >= pSegmentEnd)
- || (fSegmentStart >= fLength && pSegmentStart >= pLength)
- || (pSegmentStart == pLength - 2
- && pattern[pSegmentStart] == '*'
- && pattern[pSegmentStart + 1] == '*')
- || (pSegmentStart == pLength && freeTrailingDoubleStar);
-}
-
-/**
- * Answers the number of occurrences of the given character in the given array, 0 if any.
- *
- *
- *
- * For example:
- *
- *
- * toBeFound = 'b'
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * result => 3
- *
- *
- *
- * toBeFound = 'c'
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * result => 0
- *
- *
- *
- *
- * @param toBeFound the given character
- * @param array the given array
- * @return the number of occurrences of the given character in the given array, 0 if any
- * @throws NullPointerException if array is null
- */
-public static final int occurencesOf(char toBeFound, char[] array) {
- int count = 0;
- for (int i = 0; i < array.length; i++)
- if (toBeFound == array[i])
- count++;
- return count;
-}
-
-/**
- * Answers the number of occurrences of the given character in the given array starting
- * at the given index, 0 if any.
- *
- *
- *
- * For example:
- *
- *
- * toBeFound = 'b'
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * start = 2
- * result => 2
- *
- *
- *
- * toBeFound = 'c'
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * start = 0
- * result => 0
- *
- *
- *
- *
- * @param toBeFound the given character
- * @param array the given array
- * @param start the given index
- * @return the number of occurrences of the given character in the given array, 0 if any
- * @throws NullPointerException if array is null
- * @throws ArrayIndexOutOfBoundsException if start is lower than 0
- */
-public static final int occurencesOf(
- char toBeFound,
- char[] array,
- int start) {
- int count = 0;
- for (int i = start; i < array.length; i++)
- if (toBeFound == array[i])
- count++;
- return count;
-}
-/**
- * Return the int value represented by the designated subpart of array. The
- * calculation of the result for single-digit positive integers is optimized in
- * time.
- * @param array the array within which the int value is to be parsed
- * @param start first character of the int value in array
- * @param length length of the int value in array
- * @return the int value of a subpart of array
- * @throws NumberFormatException if the designated subpart of array does not
- * parse to an int
- * @since 3.4
- */
-public static final int parseInt(char[] array, int start, int length) throws NumberFormatException {
- if (length == 1) {
- int result = array[start] - '0';
- if (result < 0 || result > 9) {
- throw new NumberFormatException("invalid digit"); //$NON-NLS-1$
- }
- return result;
- } else {
- return Integer.parseInt(new String(array, start, length));
- }
-}
-/**
- * Answers true if the given name starts with the given prefix, false otherwise.
- * The comparison is case sensitive.
- *
- *
- * For example:
- *
- *
- * prefix = { 'a' , 'b' }
- * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * result => true
- *
- *
- *
- * prefix = { 'a' , 'c' }
- * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * result => false
- *
- *
- *
- *
- * @param prefix the given prefix
- * @param name the given name
- * @return true if the given name starts with the given prefix, false otherwise
- * @throws NullPointerException if the given name is null or if the given prefix is null
- */
-public static final boolean prefixEquals(char[] prefix, char[] name) {
-
- int max = prefix.length;
- if (name.length < max)
- return false;
- for (int i = max;
- --i >= 0;
- ) // assumes the prefix is not larger than the name
- if (prefix[i] != name[i])
- return false;
- return true;
-}
-
-/**
- * Answers true if the given name starts with the given prefix, false otherwise.
- * isCaseSensitive is used to find out whether or not the comparison should be case sensitive.
- *
- *
- * For example:
- *
- *
- * prefix = { 'a' , 'B' }
- * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * isCaseSensitive = false
- * result => true
- *
- *
- *
- * prefix = { 'a' , 'B' }
- * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- *
- * @param prefix the given prefix
- * @param name the given name
- * @param isCaseSensitive to find out whether or not the comparison should be case sensitive
- * @return true if the given name starts with the given prefix, false otherwise
- * @throws NullPointerException if the given name is null or if the given prefix is null
- */
-public static final boolean prefixEquals(
- char[] prefix,
- char[] name,
- boolean isCaseSensitive) {
- return prefixEquals(prefix, name, isCaseSensitive, 0);
-}
-
-/**
- * Answers true if the given name, starting from the given index, starts with the given prefix,
- * false otherwise. isCaseSensitive is used to find out whether or not the comparison should be
- * case sensitive.
- *
- *
- * For example:
- *
- *
- * prefix = { 'a' , 'B' }
- * name = { 'c', 'd', 'a' , 'b', 'b', 'a', 'b', 'a' }
- * startIndex = 2
- * isCaseSensitive = false
- * result => true
- *
- *
- *
- * prefix = { 'a' , 'B' }
- * name = { 'c', 'd', 'a' , 'b', 'b', 'a', 'b', 'a' }
- * startIndex = 2
- * isCaseSensitive = true
- * result => false
- *
- *
- *
- *
- * @param prefix the given prefix
- * @param name the given name
- * @param isCaseSensitive to find out whether or not the comparison should be case sensitive
- * @param startIndex index from which the prefix should be searched in the name
- * @return true if the given name starts with the given prefix, false otherwise
- * @throws NullPointerException if the given name is null or if the given prefix is null
- * @since 3.7
- */
-public static final boolean prefixEquals(
- char[] prefix,
- char[] name,
- boolean isCaseSensitive,
- int startIndex) {
-
- int max = prefix.length;
- if (name.length - startIndex < max)
- return false;
- if (isCaseSensitive) {
- for (int i = max; --i >= 0;) // assumes the prefix is not larger than the name
- if (prefix[i] != name[startIndex + i])
- return false;
- return true;
- }
-
- for (int i = max; --i >= 0;) // assumes the prefix is not larger than the name
- if (ScannerHelper.toLowerCase(prefix[i])
- != ScannerHelper.toLowerCase(name[startIndex + i]))
- return false;
- return true;
-}
-
-/**
- * Answers a new array removing a given character. Answers the given array if there is
- * no occurrence of the character to remove.
- *
- *
- * For example:
- *
- *
- * array = { 'a' , 'b', 'b', 'c', 'b', 'a' }
- * toBeRemoved = 'b'
- * return { 'a' , 'c', 'a' }
- *
- *
- *
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * toBeRemoved = 'c'
- * return array
- *
- *
- *
- *
- * @param array the given array
- * @param toBeRemoved the character to be removed
- * @return a new array removing given character
- * @since 3.2
- */
-public static final char[] remove(char[] array, char toBeRemoved) {
-
- if (array == null) return null;
- int length = array.length;
- if (length == 0) return array;
- char[] result = null;
- int count = 0;
- for (int i = 0; i < length; i++) {
- char c = array[i];
- if (c == toBeRemoved) {
- if (result == null) {
- result = new char[length];
- System.arraycopy(array, 0, result, 0, i);
- count = i;
- }
- } else if (result != null) {
- result[count++] = c;
- }
- }
- if (result == null) return array;
- System.arraycopy(result, 0, result = new char[count], 0, count);
- return result;
-}
-
-/**
- * Replace all occurrence of the character to be replaced with the replacement character in the
- * given array.
- *
- *
- * For example:
- *
- *
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * toBeReplaced = 'b'
- * replacementChar = 'a'
- * result => No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a' }
- *
- *
- *
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * toBeReplaced = 'c'
- * replacementChar = 'a'
- * result => No returned value, but array is now equals to { 'a' , 'b', 'b', 'a', 'b', 'a' }
- *
- *
- *
- *
- * @param array the given array
- * @param toBeReplaced the character to be replaced
- * @param replacementChar the replacement character
- * @throws NullPointerException if the given array is null
- */
-public static final void replace(
- char[] array,
- char toBeReplaced,
- char replacementChar) {
- if (toBeReplaced != replacementChar) {
- for (int i = 0, max = array.length; i < max; i++) {
- if (array[i] == toBeReplaced)
- array[i] = replacementChar;
- }
- }
-}
-
-/**
- * Replace all occurrences of characters to be replaced with the replacement character in the
- * given array.
- *
- *
- * For example:
- *
- *
- * array = { 'a' , 'b', 'b', 'c', 'a', 'b', 'c', 'a' }
- * toBeReplaced = { 'b', 'c' }
- * replacementChar = 'a'
- * result => No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a', 'a', 'a' }
- *
- *
- *
- *
- * @param array the given array
- * @param toBeReplaced characters to be replaced
- * @param replacementChar the replacement character
- * @throws NullPointerException if arrays are null.
- * @since 3.1
- */
-public static final void replace(char[] array, char[] toBeReplaced, char replacementChar) {
- replace(array, toBeReplaced, replacementChar, 0, array.length);
-}
-
-/**
- * Replace all occurrences of characters to be replaced with the replacement character in the
- * given array from the start position (inclusive) to the end position (exclusive).
- *
- *
- * For example:
- *
- *
- * array = { 'a' , 'b', 'b', 'c', 'a', 'b', 'c', 'a' }
- * toBeReplaced = { 'b', 'c' }
- * replacementChar = 'a'
- * start = 4
- * end = 8
- * result => No returned value, but array is now equals to { 'a' , 'b', 'b', 'c', 'a', 'a', 'a', 'a' }
- *
- *
- *
- *
- * @param array the given array
- * @param toBeReplaced characters to be replaced
- * @param replacementChar the replacement character
- * @param start the given start position (inclusive)
- * @param end the given end position (exclusive)
- * @throws NullPointerException if arrays are null.
- * @since 3.2
- */
-public static final void replace(char[] array, char[] toBeReplaced, char replacementChar, int start, int end) {
- for (int i = end; --i >= start;)
- for (int j = toBeReplaced.length; --j >= 0;)
- if (array[i] == toBeReplaced[j])
- array[i] = replacementChar;
-}
-/**
- * Answers a new array of characters with substitutions. No side-effect is operated on the original
- * array, in case no substitution happened, then the result is the same as the
- * original one.
- *
- *
- * For example:
- *
- *
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * toBeReplaced = { 'b' }
- * replacementChar = { 'a', 'a' }
- * result => { 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a' }
- *
- *
- *
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * toBeReplaced = { 'c' }
- * replacementChar = { 'a' }
- * result => { 'a' , 'b', 'b', 'a', 'b', 'a' }
- *
- *
- *
- *
- * @param array the given array
- * @param toBeReplaced characters to be replaced
- * @param replacementChars the replacement characters
- * @return a new array of characters with substitutions or the given array if none
- * @throws NullPointerException if the given array is null
- */
-public static final char[] replace(
- char[] array,
- char[] toBeReplaced,
- char[] replacementChars) {
-
- int max = array.length;
- int replacedLength = toBeReplaced.length;
- int replacementLength = replacementChars.length;
-
- int[] starts = new int[5];
- int occurrenceCount = 0;
-
- if (!equals(toBeReplaced, replacementChars)) {
-
- next : for (int i = 0; i < max;) {
- int index = indexOf(toBeReplaced, array, true, i);
- if (index == -1) {
- i++;
- continue next;
- }
- if (occurrenceCount == starts.length) {
- System.arraycopy(
- starts,
- 0,
- starts = new int[occurrenceCount * 2],
- 0,
- occurrenceCount);
- }
- starts[occurrenceCount++] = index;
- i = index + replacedLength;
- }
- }
- if (occurrenceCount == 0)
- return array;
- char[] result =
- new char[max
- + occurrenceCount * (replacementLength - replacedLength)];
- int inStart = 0, outStart = 0;
- for (int i = 0; i < occurrenceCount; i++) {
- int offset = starts[i] - inStart;
- System.arraycopy(array, inStart, result, outStart, offset);
- inStart += offset;
- outStart += offset;
- System.arraycopy(
- replacementChars,
- 0,
- result,
- outStart,
- replacementLength);
- inStart += replacedLength;
- outStart += replacementLength;
- }
- System.arraycopy(array, inStart, result, outStart, max - inStart);
- return result;
-}
-
-/**
- * Replace all occurrence of the character to be replaced with the replacement character
- * in a copy of the given array. Returns the given array if no occurrences of the character
- * to be replaced are found.
- *
- *
- * For example:
- *
- *
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * toBeReplaced = 'b'
- * replacementChar = 'a'
- * result => A new array that is equals to { 'a' , 'a', 'a', 'a', 'a', 'a' }
- *
- *
- *
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * toBeReplaced = 'c'
- * replacementChar = 'a'
- * result => The original array that remains unchanged.
- *
- *
- *
- *
- * @param array the given array
- * @param toBeReplaced the character to be replaced
- * @param replacementChar the replacement character
- * @throws NullPointerException if the given array is null
- * @since 3.1
- */
-public static final char[] replaceOnCopy(
- char[] array,
- char toBeReplaced,
- char replacementChar) {
-
- char[] result = null;
- for (int i = 0, length = array.length; i < length; i++) {
- char c = array[i];
- if (c == toBeReplaced) {
- if (result == null) {
- result = new char[length];
- System.arraycopy(array, 0, result, 0, i);
- }
- result[i] = replacementChar;
- } else if (result != null) {
- result[i] = c;
- }
- }
- if (result == null) return array;
- return result;
-}
-
-/**
- * Return a new array which is the split of the given array using the given divider and trimming each subarray to remove
- * whitespaces equals to ' '.
- *
- *
- * For example:
- *
- *
- * divider = 'b'
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * result => { { 'a' }, { }, { 'a' }, { 'a' } }
- *
- *
- *
- * divider = 'c'
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
- *
- *
- *
- * divider = 'b'
- * array = { 'a' , ' ', 'b', 'b', 'a', 'b', 'a' }
- * result => { { 'a' }, { }, { 'a' }, { 'a' } }
- *
- *
- *
- * divider = 'c'
- * array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
- * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
- *
- *
- *
- *
- * @param divider the given divider
- * @param array the given array
- * @return a new array which is the split of the given array using the given divider and trimming each subarray to remove
- * whitespaces equals to ' '
- */
-public static final char[][] splitAndTrimOn(char divider, char[] array) {
- int length = array == null ? 0 : array.length;
- if (length == 0)
- return NO_CHAR_CHAR;
-
- int wordCount = 1;
- for (int i = 0; i < length; i++)
- if (array[i] == divider)
- wordCount++;
- char[][] split = new char[wordCount][];
- int last = 0, currentWord = 0;
- for (int i = 0; i < length; i++) {
- if (array[i] == divider) {
- int start = last, end = i - 1;
- while (start < i && array[start] == ' ')
- start++;
- while (end > start && array[end] == ' ')
- end--;
- split[currentWord] = new char[end - start + 1];
- System.arraycopy(
- array,
- start,
- split[currentWord++],
- 0,
- end - start + 1);
- last = i + 1;
- }
- }
- int start = last, end = length - 1;
- while (start < length && array[start] == ' ')
- start++;
- while (end > start && array[end] == ' ')
- end--;
- split[currentWord] = new char[end - start + 1];
- System.arraycopy(
- array,
- start,
- split[currentWord++],
- 0,
- end - start + 1);
- return split;
-}
-
-/**
- * Return a new array which is the split of the given array using the given divider.
- *
- *
- * For example:
- *
- *
- * divider = 'b'
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * result => { { 'a' }, { }, { 'a' }, { 'a' } }
- *
- *
- *
- * divider = 'c'
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
- *
- *
- *
- * divider = 'c'
- * array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
- * result => { { ' ', 'a', 'b', 'b', 'a', 'b', 'a', ' ' } }
- *
- *
- *
- *
- * @param divider the given divider
- * @param array the given array
- * @return a new array which is the split of the given array using the given divider
- */
-public static final char[][] splitOn(char divider, char[] array) {
- int length = array == null ? 0 : array.length;
- if (length == 0)
- return NO_CHAR_CHAR;
-
- int wordCount = 1;
- for (int i = 0; i < length; i++)
- if (array[i] == divider)
- wordCount++;
- char[][] split = new char[wordCount][];
- int last = 0, currentWord = 0;
- for (int i = 0; i < length; i++) {
- if (array[i] == divider) {
- split[currentWord] = new char[i - last];
- System.arraycopy(
- array,
- last,
- split[currentWord++],
- 0,
- i - last);
- last = i + 1;
- }
- }
- split[currentWord] = new char[length - last];
- System.arraycopy(array, last, split[currentWord], 0, length - last);
- return split;
-}
-
-/**
- * Return a new array which is the split of the given array using the given divider. The given end
- * is exclusive and the given start is inclusive.
- *
- *
- * For example:
- *
- *
- * divider = 'b'
- * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
- * start = 2
- * end = 5
- * result => { { }, { 'a' }, { } }
- *
- *
- *
- *
- * @param divider the given divider
- * @param array the given array
- * @param start the given starting index
- * @param end the given ending index
- * @return a new array which is the split of the given array using the given divider
- * @throws ArrayIndexOutOfBoundsException if start is lower than 0 or end is greater than the array length
- */
-public static final char[][] splitOn(
- char divider,
- char[] array,
- int start,
- int end) {
- int length = array == null ? 0 : array.length;
- if (length == 0 || start > end)
- return NO_CHAR_CHAR;
-
- int wordCount = 1;
- for (int i = start; i < end; i++)
- if (array[i] == divider)
- wordCount++;
- char[][] split = new char[wordCount][];
- int last = start, currentWord = 0;
- for (int i = start; i < end; i++) {
- if (array[i] == divider) {
- split[currentWord] = new char[i - last];
- System.arraycopy(
- array,
- last,
- split[currentWord++],
- 0,
- i - last);
- last = i + 1;
- }
- }
- split[currentWord] = new char[end - last];
- System.arraycopy(array, last, split[currentWord], 0, end - last);
- return split;
-}
-
-/**
- * Return a new array which is the split of the given array using the given divider ignoring the
- * text between (possibly nested) openEncl and closingEncl. If there are no openEncl in the code
- * this is identical to {@link CharOperation#splitOn(char, char[], int, int)}. The given end
- * is exclusive and the given start is inclusive.
- *
- *
- * For example:
- *
- *
- * {@code
- * divider = ','
- * array = { 'A' , '<', 'B', ',', 'C', '>', ',', 'D' }
- * start = 0
- * end = 8
- * result => { { 'A' , '<', 'B', ',', 'C', '>'}, { 'D' }}
- * }
- *
- *
- *
- *
- * @param divider the given divider
- * @param openEncl the opening enclosure
- * @param closeEncl the closing enclosure
- * @param array the given array
- * @param start the given starting index
- * @param end the given ending index
- * @return a new array which is the split of the given array using the given divider
- * @throws ArrayIndexOutOfBoundsException if start is lower than 0 or end is greater than the array length
- * @since 3.12
- */
-public static final char[][] splitOnWithEnclosures(
- char divider,
- char openEncl,
- char closeEncl,
- char[] array,
- int start,
- int end) {
- int length = array == null ? 0 : array.length;
- if (length == 0 || start > end)
- return NO_CHAR_CHAR;
-
- int wordCount = 1;
- int enclCount = 0;
- for (int i = start; i < end; i++) {
- if (array[i] == openEncl)
- enclCount++;
- else if (array[i] == divider)
- wordCount++;
- }
- if (enclCount == 0)
- return CharOperation.splitOn(divider, array, start, end);
-
- int nesting = 0;
- if (openEncl == divider || closeEncl == divider) // divider should be distinct
- return CharOperation.NO_CHAR_CHAR;
-
- int[][] splitOffsets = new int[wordCount][2]; //maximum
- int last = start, currentWord = 0, prevOffset = start;
- for (int i = start; i < end; i++) {
- if (array[i] == openEncl) {
- ++nesting;
- continue;
- }
- if (array[i] == closeEncl) {
- if (nesting > 0)
- --nesting;
- continue;
- }
- if (array[i] == divider && nesting == 0) {
- splitOffsets[currentWord][0] = prevOffset;
- last = splitOffsets[currentWord++][1] = i;
- prevOffset = last + 1;
- }
- }
- if (last < end - 1) {
- splitOffsets[currentWord][0] = prevOffset;
- splitOffsets[currentWord++][1] = end;
- }
- char[][] split = new char[currentWord][];
- for (int i = 0; i < currentWord; ++i) {
- int sStart = splitOffsets[i][0];
- int sEnd = splitOffsets[i][1];
- int size = sEnd - sStart;
- split[i] = new char[size];
- System.arraycopy(array, sStart, split[i], 0, size);
- }
- return split;
- }
-
-/**
- * Answers a new array which is a copy of the given array starting at the given start and
- * ending at the given end. The given start is inclusive and the given end is exclusive.
- * Answers null if start is greater than end, if start is lower than 0 or if end is greater
- * than the length of the given array. If end equals -1, it is converted to the array length.
- *
- *
- * For example:
- *
- *
- * array = { { 'a' } , { 'b' } }
- * start = 0
- * end = 1
- * result => { { 'a' } }
- *
- *
- *
- * array = { { 'a' } , { 'b' } }
- * start = 0
- * end = -1
- * result => { { 'a' }, { 'b' } }
- *
- *
- *
- *
- * @param array the given array
- * @param start the given starting index
- * @param end the given ending index
- * @return a new array which is a copy of the given array starting at the given start and
- * ending at the given end
- * @throws NullPointerException if the given array is null
- */
-public static final char[][] subarray(char[][] array, int start, int end) {
- if (end == -1)
- end = array.length;
- if (start > end)
- return null;
- if (start < 0)
- return null;
- if (end > array.length)
- return null;
-
- char[][] result = new char[end - start][];
- System.arraycopy(array, start, result, 0, end - start);
- return result;
-}
-
-/**
- * Answers a new array which is a copy of the given array starting at the given start and
- * ending at the given end. The given start is inclusive and the given end is exclusive.
- * Answers null if start is greater than end, if start is lower than 0 or if end is greater
- * than the length of the given array. If end equals -1, it is converted to the array length.
- *
- *
- * For example:
- *
- *
- * array = { 'a' , 'b' }
- * start = 0
- * end = 1
- * result => { 'a' }
- *
- *
- *
- * array = { 'a', 'b' }
- * start = 0
- * end = -1
- * result => { 'a' , 'b' }
- *
- *
- *
- *
- * @param array the given array
- * @param start the given starting index
- * @param end the given ending index
- * @return a new array which is a copy of the given array starting at the given start and
- * ending at the given end
- * @throws NullPointerException if the given array is null
- */
-public static final char[] subarray(char[] array, int start, int end) {
- if (end == -1)
- end = array.length;
- if (start > end)
- return null;
- if (start < 0)
- return null;
- if (end > array.length)
- return null;
-
- char[] result = new char[end - start];
- System.arraycopy(array, start, result, 0, end - start);
- return result;
-}
-
-/**
- * Answers the result of a char[] conversion to lowercase. Answers null if the given chars array is null.
- *
- * NOTE: If no conversion was necessary, then answers back the argument one.
- *
- *
- * For example:
- *
- *
- * chars = { 'a' , 'b' }
- * result => { 'a' , 'b' }
- *
- *
- *
- * array = { 'A', 'b' }
- * result => { 'a' , 'b' }
- *
- *
- *
- *
- * @param chars the chars to convert
- * @return the result of a char[] conversion to lowercase
- */
-final static public char[] toLowerCase(char[] chars) {
- if (chars == null)
- return null;
- int length = chars.length;
- char[] lowerChars = null;
- for (int i = 0; i < length; i++) {
- char c = chars[i];
- char lc = ScannerHelper.toLowerCase(c);
- if ((c != lc) || (lowerChars != null)) {
- if (lowerChars == null) {
- System.arraycopy(
- chars,
- 0,
- lowerChars = new char[length],
- 0,
- i);
- }
- lowerChars[i] = lc;
- }
- }
- return lowerChars == null ? chars : lowerChars;
-}
-
-/**
- * Answers the result of a char[] conversion to uppercase. Answers null if the given chars array is null.
- *
- * NOTE: If no conversion was necessary, then answers back the argument one.
- *
- *
- * For example:
- *
- *
- * chars = { 'A' , 'B' }
- * result => { 'A' , 'B' }
- *
- *
- *
- * array = { 'a', 'B' }
- * result => { 'A' , 'B' }
- *
- *
- *
- *
- * @param chars the chars to convert
- * @return the result of a char[] conversion to uppercase
- *
- * @since 3.5
- */
-final static public char[] toUpperCase(char[] chars) {
- if (chars == null)
- return null;
- int length = chars.length;
- char[] upperChars = null;
- for (int i = 0; i < length; i++) {
- char c = chars[i];
- char lc = ScannerHelper.toUpperCase(c);
- if ((c != lc) || (upperChars != null)) {
- if (upperChars == null) {
- System.arraycopy(
- chars,
- 0,
- upperChars = new char[length],
- 0,
- i);
- }
- upperChars[i] = lc;
- }
- }
- return upperChars == null ? chars : upperChars;
-}
-
-/**
- * Answers a new array removing leading and trailing spaces (' '). Answers the given array if there is no
- * space characters to remove.
- *
- *
- * For example:
- *
- *
- * chars = { ' ', 'a' , 'b', ' ', ' ' }
- * result => { 'a' , 'b' }
- *
- *
- *
- * array = { 'A', 'b' }
- * result => { 'A' , 'b' }
- *
- *
- *
- *
- * @param chars the given array
- * @return a new array removing leading and trailing spaces (' ')
- */
-final static public char[] trim(char[] chars) {
-
- if (chars == null)
- return null;
-
- int start = 0, length = chars.length, end = length - 1;
- while (start < length && chars[start] == ' ') {
- start++;
- }
- while (end > start && chars[end] == ' ') {
- end--;
- }
- if (start != 0 || end != length - 1) {
- return subarray(chars, start, end + 1);
- }
- return chars;
-}
-
-/**
- * Answers a string which is the concatenation of the given array using the '.' as a separator.
- *
- *
- * For example:
- *
- *
- * array = { { 'a' } , { 'b' } }
- * result => "a.b"
- *
- *
- *
- * array = { { ' ', 'a' } , { 'b' } }
- * result => " a.b"
- *
- *
- *
- *
- * @param array the given array
- * @return a string which is the concatenation of the given array using the '.' as a separator
- */
-final static public String toString(char[][] array) {
- char[] result = concatWith(array, '.');
- return new String(result);
-}
-
-/**
- * Answers an array of strings from the given array of char array.
- *
- * @param array the given array
- * @return an array of strings
- * @since 3.0
- */
-final static public String[] toStrings(char[][] array) {
- if (array == null) return NO_STRINGS;
- int length = array.length;
- if (length == 0) return NO_STRINGS;
- String[] result = new String[length];
- for (int i = 0; i < length; i++)
- result[i] = new String(array[i]);
- return result;
-}
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/CompilationProgress.java b/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/CompilationProgress.java
deleted file mode 100644
index a45cb69..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/CompilationProgress.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.core.compiler;
-
-import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
-
-/**
- * A compilation progress is used by the {@link BatchCompiler} to report progress during compilation.
- * It is also used to request cancellation of the compilation.
- * Clients of the {@link BatchCompiler} should subclass this class, instantiate the subclass and pass this instance to
- * {@link BatchCompiler#compile(String, java.io.PrintWriter, java.io.PrintWriter, CompilationProgress)}.
- *
- * This class is intended to be instantiated and subclassed by clients.
- *
- *
- * @since 3.4
- */
-
-public abstract class CompilationProgress {
-
- /**
- * Notifies that the compilation is beginning. This is called exactly once per batch compilation.
- * An estimated amount of remaining work is given. This amount will change as the compilation
- * progresses. The new estimated amount of remaining work is reported using {@link #worked(int, int)}.
- *
- * Clients should not call this method.
- *
- *
- * @param remainingWork the estimated amount of remaining work.
- */
- public abstract void begin(int remainingWork);
-
- /**
- * Notifies that the work is done; that is, either the compilation is completed
- * or a cancellation was requested. This is called exactly once per batch compilation.
- *
- * Clients should not call this method.
- *
- */
- public abstract void done();
-
- /**
- * Returns whether cancellation of the compilation has been requested.
- *
- * @return true if cancellation has been requested,
- * and false otherwise
- */
- public abstract boolean isCanceled();
-
- /**
- * Reports the name (or description) of the current task.
- *
- * Clients should not call this method.
- *
- *
- * @param name the name (or description) of the current task
- */
- public abstract void setTaskName(String name);
-
-
- /**
- * Notifies that a given amount of work of the compilation
- * has been completed. Note that this amount represents an
- * installment, as opposed to a cumulative amount of work done
- * to date.
- * Also notifies an estimated amount of remaining work. Note that this
- * amount of remaining work may be greater than the previous estimated
- * amount as new compilation units are injected in the compile loop.
- *
- * Clients should not call this method.
- *
- *
- * @param workIncrement a non-negative amount of work just completed
- * @param remainingWork a non-negative amount of estimated remaining work
- */
- public abstract void worked(int workIncrement, int remainingWork);
-
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/IProblem.java b/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/IProblem.java
deleted file mode 100644
index 6f36cbb..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/IProblem.java
+++ /dev/null
@@ -1,2595 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2024 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * IBM Corporation - added the following constants
- * NonStaticAccessToStaticField
- * NonStaticAccessToStaticMethod
- * Task
- * ExpressionShouldBeAVariable
- * AssignmentHasNoEffect
- * IBM Corporation - added the following constants
- * TooManySyntheticArgumentSlots
- * TooManyArrayDimensions
- * TooManyBytesForStringConstant
- * TooManyMethods
- * TooManyFields
- * NonBlankFinalLocalAssignment
- * ObjectCannotHaveSuperTypes
- * MissingSemiColon
- * InvalidParenthesizedExpression
- * EnclosingInstanceInConstructorCall
- * BytecodeExceeds64KLimitForConstructor
- * IncompatibleReturnTypeForNonInheritedInterfaceMethod
- * UnusedPrivateMethod
- * UnusedPrivateConstructor
- * UnusedPrivateType
- * UnusedPrivateField
- * IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod
- * InvalidExplicitConstructorCall
- * IBM Corporation - added the following constants
- * PossibleAccidentalBooleanAssignment
- * SuperfluousSemicolon
- * IndirectAccessToStaticField
- * IndirectAccessToStaticMethod
- * IndirectAccessToStaticType
- * BooleanMethodThrowingException
- * UnnecessaryCast
- * UnnecessaryArgumentCast
- * UnnecessaryInstanceof
- * FinallyMustCompleteNormally
- * UnusedMethodDeclaredThrownException
- * UnusedConstructorDeclaredThrownException
- * InvalidCatchBlockSequence
- * UnqualifiedFieldAccess
- * IBM Corporation - added the following constants
- * Javadoc
- * JavadocUnexpectedTag
- * JavadocMissingParamTag
- * JavadocMissingParamName
- * JavadocDuplicateParamName
- * JavadocInvalidParamName
- * JavadocMissingReturnTag
- * JavadocDuplicateReturnTag
- * JavadocMissingThrowsTag
- * JavadocMissingThrowsClassName
- * JavadocInvalidThrowsClass
- * JavadocDuplicateThrowsClassName
- * JavadocInvalidThrowsClassName
- * JavadocMissingSeeReference
- * JavadocInvalidSeeReference
- * JavadocInvalidSeeHref
- * JavadocInvalidSeeArgs
- * JavadocMissing
- * JavadocInvalidTag
- * JavadocMessagePrefix
- * EmptyControlFlowStatement
- * IBM Corporation - added the following constants
- * IllegalUsageOfQualifiedTypeReference
- * InvalidDigit
- * IBM Corporation - added the following constants
- * ParameterAssignment
- * FallthroughCase
- * IBM Corporation - added the following constants
- * UnusedLabel
- * UnnecessaryNLSTag
- * LocalVariableMayBeNull
- * EnumConstantsCannotBeSurroundedByParenthesis
- * JavadocMissingIdentifier
- * JavadocNonStaticTypeFromStaticInvocation
- * RawTypeReference
- * NoAdditionalBoundAfterTypeVariable
- * UnsafeGenericArrayForVarargs
- * IllegalAccessFromTypeVariable
- * AnnotationValueMustBeArrayInitializer
- * InvalidEncoding
- * CannotReadSource
- * EnumStaticFieldInInInitializerContext
- * ExternalProblemNotFixable
- * ExternalProblemFixable
- * IBM Corporation - added the following constants
- * AnnotationValueMustBeAnEnumConstant
- * OverridingMethodWithoutSuperInvocation
- * MethodMustOverrideOrImplement
- * TypeHidingTypeParameterFromType
- * TypeHidingTypeParameterFromMethod
- * TypeHidingType
- * IBM Corporation - added the following constants
- * NullLocalVariableReference
- * PotentialNullLocalVariableReference
- * RedundantNullCheckOnNullLocalVariable
- * NullLocalVariableComparisonYieldsFalse
- * RedundantLocalVariableNullAssignment
- * NullLocalVariableInstanceofYieldsFalse
- * RedundantNullCheckOnNonNullLocalVariable
- * NonNullLocalVariableComparisonYieldsFalse
- * IBM Corporation - added the following constants
- * InvalidUsageOfTypeParametersForAnnotationDeclaration
- * InvalidUsageOfTypeParametersForEnumDeclaration
- * IBM Corporation - added the following constants
- * RedundantSuperinterface
- * Benjamin Muskalla - added the following constants
- * MissingSynchronizedModifierInInheritedMethod
- * Stephan Herrmann - added the following constants
- * UnusedObjectAllocation
- * PotentiallyUnclosedCloseable
- * PotentiallyUnclosedCloseableAtExit
- * UnclosedCloseable
- * UnclosedCloseableAtExit
- * ExplicitlyClosedAutoCloseable
- * RequiredNonNullButProvidedNull
- * RequiredNonNullButProvidedPotentialNull
- * RequiredNonNullButProvidedUnknown
- * NullAnnotationNameMustBeQualified
- * IllegalReturnNullityRedefinition
- * IllegalRedefinitionToNonNullParameter
- * IllegalDefinitionToNonNullParameter
- * ParameterLackingNonNullAnnotation
- * ParameterLackingNullableAnnotation
- * PotentialNullMessageSendReference
- * RedundantNullCheckOnNonNullMessageSend
- * CannotImplementIncompatibleNullness
- * RedundantNullAnnotation
- * RedundantNullDefaultAnnotation
- * RedundantNullDefaultAnnotationPackage
- * RedundantNullDefaultAnnotationType
- * RedundantNullDefaultAnnotationMethod
- * ContradictoryNullAnnotations
- * IllegalAnnotationForBaseType
- * RedundantNullCheckOnSpecdNonNullLocalVariable
- * SpecdNonNullLocalVariableComparisonYieldsFalse
- * RequiredNonNullButProvidedSpecdNullable
- * MissingDefaultCase
- * MissingEnumConstantCaseDespiteDefault
- * UninitializedLocalVariableHintMissingDefault
- * UninitializedBlankFinalFieldHintMissingDefault
- * ShouldReturnValueHintMissingDefault
- * IllegalModifierForInterfaceDefaultMethod
- * InheritedDefaultMethodConflictsWithOtherInherited
- * ConflictingNullAnnotations
- * ConflictingInheritedNullAnnotations
- * UnsafeElementTypeConversion
- * ArrayReferencePotentialNullReference
- * DereferencingNullableExpression
- * NullityMismatchingTypeAnnotation
- * NullityMismatchingTypeAnnotationSuperHint
- * NullityUncheckedTypeAnnotationDetail
- * NullityUncheckedTypeAnnotationDetailSuperHint
- * NullableFieldReference
- * UninitializedNonNullField
- * UninitializedNonNullFieldHintMissingDefault
- * NonNullMessageSendComparisonYieldsFalse
- * RedundantNullCheckOnNonNullSpecdField
- * NonNullSpecdFieldComparisonYieldsFalse
- * NonNullExpressionComparisonYieldsFalse
- * RedundantNullCheckOnNonNullExpression
- * ReferenceExpressionParameterNullityMismatch
- * ReferenceExpressionParameterNullityUnchecked
- * ReferenceExpressionReturnNullRedef
- * ReferenceExpressionReturnNullRedefUnchecked
- * DuplicateInheritedDefaultMethods
- * SuperAccessCannotBypassDirectSuper
- * SuperCallCannotBypassOverride
- * ConflictingNullAnnotations
- * ConflictingInheritedNullAnnotations
- * UnsafeElementTypeConversion
- * PotentialNullUnboxing
- * NullUnboxing
- * NullExpressionReference
- * PotentialNullExpressionReference
- * RedundantNullCheckAgainstNonNullType
- * NullAnnotationUnsupportedLocation
- * NullAnnotationUnsupportedLocationAtType
- * NullityMismatchTypeArgument
- * ContradictoryNullAnnotationsOnBound
- * UnsafeNullnessCast
- * ContradictoryNullAnnotationsInferred
- * NonNullDefaultDetailIsNotEvaluated
- * NullNotCompatibleToFreeTypeVariable
- * NullityMismatchAgainstFreeTypeVariable
- * ImplicitObjectBoundNoNullDefault
- * IllegalParameterNullityRedefinition
- * ContradictoryNullAnnotationsInferredFunctionType
- * IllegalReturnNullityRedefinitionFreeTypeVariable
- * UnlikelyCollectionMethodArgumentType
- * UnlikelyEqualsArgumentType
- * Jesper S Moller - added the following constants
- * TargetTypeNotAFunctionalInterface
- * OuterLocalMustBeEffectivelyFinal
- * IllegalModifiersForPackage
- * DuplicateAnnotationNotMarkedRepeatable
- * DisallowedTargetForContainerAnnotation
- * RepeatedAnnotationWithContainerAnnotation
- * ContainingAnnotationMustHaveValue
- * ContainingAnnotationHasNonDefaultMembers
- * ContainingAnnotationHasWrongValueType
- * ContainingAnnotationHasShorterRetention
- * RepeatableAnnotationHasTargets
- * RepeatableAnnotationTargetMismatch
- * RepeatableAnnotationIsDocumented
- * RepeatableAnnotationIsInherited
- * RepeatableAnnotationWithRepeatingContainerAnnotation
- * VarLocalMultipleDeclarators
- * VarLocalCannotBeArray
- * VarLocalReferencesItself
- * VarLocalWithoutInitizalier
- * VarLocalInitializedToNull
- * VarLocalCannotBeArrayInitalizers
- * VarLocalCannotBeLambda
- * VarLocalCannotBeMethodReference
- * VarIsReserved
- * VarIsReservedInFuture
- * VarIsNotAllowedHere
-******************************************************************************/
-package org.eclipse.jdt.core.compiler;
-
-import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
-
-/**
- * Description of a Java problem, as detected by the compiler or some of the underlying
- * technology reusing the compiler.
- * A problem provides access to:
- *
- * its location (originating source file name, source position, line number)
- * its message description
- * predicates to check its severity (error, warning, or info)
- * its ID : a number identifying the very nature of this problem. All possible IDs are listed
- * as constants on this interface.
- *
- *
- * Note: the compiler produces IProblems internally, which are turned into markers by the JavaBuilder
- * so as to persist problem descriptions. This explains why there is no API allowing to reach IProblem detected
- * when compiling. However, the Java problem markers carry equivalent information to IProblem, in particular
- * their ID (attribute "id") is set to one of the IDs defined on this interface.
- *
- * @since 2.0
- * @noimplement This interface is not intended to be implemented by clients.
- * @noextend This interface is not intended to be extended by clients.
- */
-public interface IProblem {
-
-/**
- * Answer back the original arguments recorded into the problem.
- * @return the original arguments recorded into the problem
- */
-String[] getArguments();
-
-/**
- * Returns the problem id
- *
- * @return the problem id
- */
-int getID();
-
-/**
- * Answer a localized, human-readable message string which describes the problem.
- *
- * @return a localized, human-readable message string which describes the problem
- */
-String getMessage();
-
-/**
- * Answer the file name in which the problem was found.
- *
- * @return the file name in which the problem was found
- */
-char[] getOriginatingFileName();
-
-/**
- * Answer the end position of the problem (inclusive), or -1 if unknown.
- *
- * @return the end position of the problem (inclusive), or -1 if unknown
- */
-int getSourceEnd();
-
-/**
- * Answer the line number in source where the problem begins.
- *
- * @return the line number in source where the problem begins
- */
-int getSourceLineNumber();
-
-/**
- * Answer the start position of the problem (inclusive), or -1 if unknown.
- *
- * @return the start position of the problem (inclusive), or -1 if unknown
- */
-int getSourceStart();
-
-/**
- * Returns whether the severity of this problem is 'Error'.
- *
- * @return true if the severity of this problem is 'Error', false otherwise
- */
-boolean isError();
-
-/**
- * Returns whether the severity of this problem is 'Warning'.
- *
- * @return true if the severity of this problem is 'Warning', false otherwise
- */
-boolean isWarning();
-
-/**
- * Returns whether the severity of this problem is 'Info'.
- *
- * @return true if the severity of this problem is 'Info', false otherwise
- * @since 3.12
- */
-boolean isInfo();
-
-/**
- * Set the end position of the problem (inclusive), or -1 if unknown.
- * Used for shifting problem positions.
- *
- * @param sourceEnd the given end position
- */
-void setSourceEnd(int sourceEnd);
-
-/**
- * Set the line number in source where the problem begins.
- *
- * @param lineNumber the given line number
- */
-void setSourceLineNumber(int lineNumber);
-
-/**
- * Set the start position of the problem (inclusive), or -1 if unknown.
- * Used for shifting problem positions.
- *
- * @param sourceStart the given start position
- */
-void setSourceStart(int sourceStart);
-
-
- /**
- * Problem Categories
- * The high bits of a problem ID contains information about the category of a problem.
- * For example, (problemID & TypeRelated) != 0, indicates that this problem is type related.
- *
- * A problem category can help to implement custom problem filters. Indeed, when numerous problems
- * are listed, focusing on import related problems first might be relevant.
- *
- * When a problem is tagged as Internal, it means that no change other than a local source code change
- * can fix the corresponding problem. A type related problem could be addressed by changing the type
- * involved in it.
- */
- int TypeRelated = 0x01000000;
- int FieldRelated = 0x02000000;
- int MethodRelated = 0x04000000;
- int ConstructorRelated = 0x08000000;
- int ImportRelated = 0x10000000;
- int Internal = 0x20000000;
- int Syntax = 0x40000000;
- /** @since 3.0 */
- int Javadoc = 0x80000000;
- /** @since 3.14 */
- int ModuleRelated = 0x00800000;
- /** @since 3.18 */
- int Compliance = 0x00400000;
- /** @since 3.20 */
- int PreviewRelated = 0x00200000;
-
- /**
- * Mask to use in order to filter out the category portion of the problem ID.
- */
- int IgnoreCategoriesMask = 0x1FFFFF;
-
- /*
- * Below are listed all available problem IDs. Note that this list could be augmented in the future,
- * as new features are added to the Java core implementation.
- *
- * Problem IDs must be kept unique even when their mask is stripped, since
- * the bare integer literal is used for message lookup in
- * /org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties.
- * Use this regex to find duplicates: (?s)(\+ \d+)\b.*\1\b
- */
-
- /**
- * ID reserved for referencing an internal error inside the JavaCore implementation which
- * may be surfaced as a problem associated with the compilation unit which caused it to occur.
- */
- int Unclassified = 0;
-
- /**
- * General type related problems
- */
- int ObjectHasNoSuperclass = TypeRelated + 1;
- int UndefinedType = TypeRelated + 2;
- int NotVisibleType = TypeRelated + 3;
- int AmbiguousType = TypeRelated + 4;
- int UsingDeprecatedType = TypeRelated + 5;
- int InternalTypeNameProvided = TypeRelated + 6;
- /** @since 2.1 */
- int UnusedPrivateType = Internal + TypeRelated + 7;
-
- int IncompatibleTypesInEqualityOperator = TypeRelated + 15;
- int IncompatibleTypesInConditionalOperator = TypeRelated + 16;
- int TypeMismatch = TypeRelated + 17;
- /** @since 3.0 */
- int IndirectAccessToStaticType = Internal + TypeRelated + 18;
-
- /** @since 3.10 */
- int ReturnTypeMismatch = TypeRelated + 19;
-
- /**
- * Inner types related problems
- */
- int MissingEnclosingInstanceForConstructorCall = TypeRelated + 20;
- int MissingEnclosingInstance = TypeRelated + 21;
- int IncorrectEnclosingInstanceReference = TypeRelated + 22;
- int IllegalEnclosingInstanceSpecification = TypeRelated + 23;
- int CannotDefineStaticInitializerInLocalType = Internal + 24;
- int OuterLocalMustBeFinal = Internal + 25;
- int CannotDefineInterfaceInLocalType = Internal + 26;
- int IllegalPrimitiveOrArrayTypeForEnclosingInstance = TypeRelated + 27;
- /** @since 2.1 */
- int EnclosingInstanceInConstructorCall = Internal + 28;
- int AnonymousClassCannotExtendFinalClass = TypeRelated + 29;
- /** @since 3.1 */
- int CannotDefineAnnotationInLocalType = Internal + 30;
- /** @since 3.1 */
- int CannotDefineEnumInLocalType = Internal + 31;
- /** @since 3.1 */
- int NonStaticContextForEnumMemberType = Internal + 32;
- /** @since 3.3 */
- int TypeHidingType = TypeRelated + 33;
- /** @since 3.11 */
- int NotAnnotationType = TypeRelated + 34;
-
- // variables
- int UndefinedName = Internal + FieldRelated + 50;
- int UninitializedLocalVariable = Internal + 51;
- int VariableTypeCannotBeVoid = Internal + 52;
- /** @deprecated - problem is no longer generated, use {@link #CannotAllocateVoidArray} instead */
- int VariableTypeCannotBeVoidArray = Internal + 53;
- int CannotAllocateVoidArray = Internal + 54;
- // local variables
- int RedefinedLocal = Internal + 55;
- int RedefinedArgument = Internal + 56;
- // final local variables
- int DuplicateFinalLocalInitialization = Internal + 57;
- /** @since 2.1 */
- int NonBlankFinalLocalAssignment = Internal + 58;
- /** @since 3.2 */
- int ParameterAssignment = Internal + 59;
- int FinalOuterLocalAssignment = Internal + 60;
- int LocalVariableIsNeverUsed = Internal + 61;
- int ArgumentIsNeverUsed = Internal + 62;
- int BytecodeExceeds64KLimit = Internal + 63;
- int BytecodeExceeds64KLimitForClinit = Internal + 64;
- int TooManyArgumentSlots = Internal + 65;
- int TooManyLocalVariableSlots = Internal + 66;
- /** @since 2.1 */
- int TooManySyntheticArgumentSlots = Internal + 67;
- /** @since 2.1 */
- int TooManyArrayDimensions = Internal + 68;
- /** @since 2.1 */
- int BytecodeExceeds64KLimitForConstructor = Internal + 69;
-
- // fields
- int UndefinedField = FieldRelated + 70;
- int NotVisibleField = FieldRelated + 71;
- int AmbiguousField = FieldRelated + 72;
- int UsingDeprecatedField = FieldRelated + 73;
- int NonStaticFieldFromStaticInvocation = FieldRelated + 74;
- int ReferenceToForwardField = FieldRelated + Internal + 75;
- /** @since 2.1 */
- int NonStaticAccessToStaticField = Internal + FieldRelated + 76;
- /** @since 2.1 */
- int UnusedPrivateField = Internal + FieldRelated + 77;
- /** @since 3.0 */
- int IndirectAccessToStaticField = Internal + FieldRelated + 78;
- /** @since 3.0 */
- int UnqualifiedFieldAccess = Internal + FieldRelated + 79;
- int FinalFieldAssignment = FieldRelated + 80;
- int UninitializedBlankFinalField = FieldRelated + 81;
- int DuplicateBlankFinalFieldInitialization = FieldRelated + 82;
- /** @since 3.6 */
- int UnresolvedVariable = FieldRelated + 83;
- /** @since 3.10 */
- int NonStaticOrAlienTypeReceiver = MethodRelated + 84;
-
- /** @since 3.11 */
- int ExceptionParameterIsNeverUsed = Internal + 85;
- /** @since 3.17 */
- int BytecodeExceeds64KLimitForSwitchTable = Internal + 86;
-
- // variable hiding
- /** @since 3.0 */
- int LocalVariableHidingLocalVariable = Internal + 90;
- /** @since 3.0 */
- int LocalVariableHidingField = Internal + FieldRelated + 91;
- /** @since 3.0 */
- int FieldHidingLocalVariable = Internal + FieldRelated + 92;
- /** @since 3.0 */
- int FieldHidingField = Internal + FieldRelated + 93;
- /** @since 3.0 */
- int ArgumentHidingLocalVariable = Internal + 94;
- /** @since 3.0 */
- int ArgumentHidingField = Internal + 95;
- /** @since 3.1 */
- int MissingSerialVersion = Internal + 96;
- /** @since 3.10 */
- int LambdaRedeclaresArgument = Internal + 97;
- /** @since 3.10 */
- int LambdaRedeclaresLocal = Internal + 98;
- /** @since 3.10 */
- int LambdaDescriptorMentionsUnmentionable = 99;
-
- // methods
- int UndefinedMethod = MethodRelated + 100;
- int NotVisibleMethod = MethodRelated + 101;
- int AmbiguousMethod = MethodRelated + 102;
- int UsingDeprecatedMethod = MethodRelated + 103;
- int DirectInvocationOfAbstractMethod = MethodRelated + 104;
- int VoidMethodReturnsValue = MethodRelated + 105;
- int MethodReturnsVoid = MethodRelated + 106;
- int MethodRequiresBody = Internal + MethodRelated + 107;
- int ShouldReturnValue = Internal + MethodRelated + 108;
- int MethodButWithConstructorName = MethodRelated + 110;
- int MissingReturnType = TypeRelated + 111;
- int BodyForNativeMethod = Internal + MethodRelated + 112;
- int BodyForAbstractMethod = Internal + MethodRelated + 113;
- int NoMessageSendOnBaseType = MethodRelated + 114;
- int ParameterMismatch = MethodRelated + 115;
- int NoMessageSendOnArrayType = MethodRelated + 116;
- /** @since 2.1 */
- int NonStaticAccessToStaticMethod = Internal + MethodRelated + 117;
- /** @since 2.1 */
- int UnusedPrivateMethod = Internal + MethodRelated + 118;
- /** @since 3.0 */
- int IndirectAccessToStaticMethod = Internal + MethodRelated + 119;
- /** @since 3.4 */
- int MissingTypeInMethod = MethodRelated + 120;
- /** @since 3.7 */
- int MethodCanBeStatic = Internal + MethodRelated + 121;
- /** @since 3.7 */
- int MethodCanBePotentiallyStatic = Internal + MethodRelated + 122;
- /** @since 3.10 */
- int MethodReferenceSwingsBothWays = Internal + MethodRelated + 123;
- /** @since 3.10 */
- int StaticMethodShouldBeAccessedStatically = Internal + MethodRelated + 124;
- /** @since 3.10 */
- int InvalidArrayConstructorReference = Internal + MethodRelated + 125;
- /** @since 3.10 */
- int ConstructedArrayIncompatible = Internal + MethodRelated + 126;
- /** @since 3.10 */
- int DanglingReference = Internal + MethodRelated + 127;
- /** @since 3.10 */
- int IncompatibleMethodReference = Internal + MethodRelated + 128;
-
- // constructors
- /** @since 3.4 */
- int MissingTypeInConstructor = ConstructorRelated + 129;
- int UndefinedConstructor = ConstructorRelated + 130;
- int NotVisibleConstructor = ConstructorRelated + 131;
- int AmbiguousConstructor = ConstructorRelated + 132;
- int UsingDeprecatedConstructor = ConstructorRelated + 133;
- /** @since 2.1 */
- int UnusedPrivateConstructor = Internal + MethodRelated + 134;
- // explicit constructor calls
- int InstanceFieldDuringConstructorInvocation = ConstructorRelated + 135;
- int InstanceMethodDuringConstructorInvocation = ConstructorRelated + 136;
- int RecursiveConstructorInvocation = ConstructorRelated + 137;
- int ThisSuperDuringConstructorInvocation = ConstructorRelated + 138;
- /** @since 3.0 */
- int InvalidExplicitConstructorCall = ConstructorRelated + Syntax + 139;
- // implicit constructor calls
- int UndefinedConstructorInDefaultConstructor = ConstructorRelated + 140;
- int NotVisibleConstructorInDefaultConstructor = ConstructorRelated + 141;
- int AmbiguousConstructorInDefaultConstructor = ConstructorRelated + 142;
- int UndefinedConstructorInImplicitConstructorCall = ConstructorRelated + 143;
- int NotVisibleConstructorInImplicitConstructorCall = ConstructorRelated + 144;
- int AmbiguousConstructorInImplicitConstructorCall = ConstructorRelated + 145;
- int UnhandledExceptionInDefaultConstructor = TypeRelated + 146;
- int UnhandledExceptionInImplicitConstructorCall = TypeRelated + 147;
-
- // expressions
- /** @since 3.6 */
- int UnusedObjectAllocation = Internal + 148;
- /** @since 3.5 */
- int DeadCode = Internal + 149;
- int ArrayReferenceRequired = Internal + 150;
- int NoImplicitStringConversionForCharArrayExpression = Internal + 151;
- // constant expressions
- int StringConstantIsExceedingUtf8Limit = Internal + 152;
- int NonConstantExpression = Internal + 153;
- int NumericValueOutOfRange = Internal + 154;
- // cast expressions
- int IllegalCast = TypeRelated + 156;
- // allocations
- int InvalidClassInstantiation = TypeRelated + 157;
- int CannotDefineDimensionExpressionsWithInit = Internal + 158;
- int MustDefineEitherDimensionExpressionsOrInitializer = Internal + 159;
- // operators
- int InvalidOperator = Internal + 160;
- // statements
- int CodeCannotBeReached = Internal + 161;
- int CannotReturnInInitializer = Internal + 162;
- int InitializerMustCompleteNormally = Internal + 163;
- // assert
- int InvalidVoidExpression = Internal + 164;
- // try
- int MaskedCatch = TypeRelated + 165;
- int DuplicateDefaultCase = Internal + 166;
- int UnreachableCatch = TypeRelated + MethodRelated + 167;
- int UnhandledException = TypeRelated + 168;
- // switch
- int IncorrectSwitchType = TypeRelated + 169;
- int DuplicateCase = FieldRelated + 170;
-
- // labelled
- int DuplicateLabel = Internal + 171;
- int InvalidBreak = Internal + 172;
- int InvalidContinue = Internal + 173;
- int UndefinedLabel = Internal + 174;
- //synchronized
- int InvalidTypeToSynchronized = Internal + 175;
- int InvalidNullToSynchronized = Internal + 176;
- // throw
- int CannotThrowNull = Internal + 177;
- // assignment
- /** @since 2.1 */
- int AssignmentHasNoEffect = Internal + 178;
- /** @since 3.0 */
- int PossibleAccidentalBooleanAssignment = Internal + 179;
- /** @since 3.0 */
- int SuperfluousSemicolon = Internal + 180;
- /** @since 3.0 */
- int UnnecessaryCast = Internal + TypeRelated + 181;
- /** @deprecated - no longer generated, use {@link #UnnecessaryCast} instead
- * @since 3.0 */
- int UnnecessaryArgumentCast = Internal + TypeRelated + 182;
- /** @since 3.0 */
- int UnnecessaryInstanceof = Internal + TypeRelated + 183;
- /** @since 3.0 */
- int FinallyMustCompleteNormally = Internal + 184;
- /** @since 3.0 */
- int UnusedMethodDeclaredThrownException = Internal + 185;
- /** @since 3.0 */
- int UnusedConstructorDeclaredThrownException = Internal + 186;
- /** @since 3.0 */
- int InvalidCatchBlockSequence = Internal + TypeRelated + 187;
- /** @since 3.0 */
- int EmptyControlFlowStatement = Internal + TypeRelated + 188;
- /** @since 3.0 */
- int UnnecessaryElse = Internal + 189;
-
- // inner emulation
- int NeedToEmulateFieldReadAccess = FieldRelated + 190;
- int NeedToEmulateFieldWriteAccess = FieldRelated + 191;
- int NeedToEmulateMethodAccess = MethodRelated + 192;
- int NeedToEmulateConstructorAccess = MethodRelated + 193;
-
- /** @since 3.2 */
- int FallthroughCase = Internal + 194;
-
- //inherited name hides enclosing name (sort of ambiguous)
- int InheritedMethodHidesEnclosingName = MethodRelated + 195;
- int InheritedFieldHidesEnclosingName = FieldRelated + 196;
- int InheritedTypeHidesEnclosingName = TypeRelated + 197;
-
- /** @since 3.1 */
- int IllegalUsageOfQualifiedTypeReference = Internal + Syntax + 198;
-
- // miscellaneous
- /** @since 3.2 */
- int UnusedLabel = Internal + 199;
- int ThisInStaticContext = Internal + 200;
- int StaticMethodRequested = Internal + MethodRelated + 201;
- int IllegalDimension = Internal + 202;
- /** @deprecated - problem is no longer generated */
- int InvalidTypeExpression = Internal + 203;
- int ParsingError = Syntax + Internal + 204;
- int ParsingErrorNoSuggestion = Syntax + Internal + 205;
- int InvalidUnaryExpression = Syntax + Internal + 206;
-
- // syntax errors
- int InterfaceCannotHaveConstructors = Syntax + Internal + 207;
- int ArrayConstantsOnlyInArrayInitializers = Syntax + Internal + 208;
- int ParsingErrorOnKeyword = Syntax + Internal + 209;
- int ParsingErrorOnKeywordNoSuggestion = Syntax + Internal + 210;
-
- /** @since 3.5 */
- int ComparingIdentical = Internal + 211;
-
- /** @since 3.22
- * @noreference preview feature error */
- int UnsafeCast = TypeRelated + 212;
-
- int UnmatchedBracket = Syntax + Internal + 220;
- int NoFieldOnBaseType = FieldRelated + 221;
- int InvalidExpressionAsStatement = Syntax + Internal + 222;
- /** @since 2.1 */
- int ExpressionShouldBeAVariable = Syntax + Internal + 223;
- /** @since 2.1 */
- int MissingSemiColon = Syntax + Internal + 224;
- /** @since 2.1 */
- int InvalidParenthesizedExpression = Syntax + Internal + 225;
-
- /** @since 3.10 */
- int NoSuperInInterfaceContext = Syntax + Internal + 226;
-
- /** @since 3.0 */
- int ParsingErrorInsertTokenBefore = Syntax + Internal + 230;
- /** @since 3.0 */
- int ParsingErrorInsertTokenAfter = Syntax + Internal + 231;
- /** @since 3.0 */
- int ParsingErrorDeleteToken = Syntax + Internal + 232;
- /** @since 3.0 */
- int ParsingErrorDeleteTokens = Syntax + Internal + 233;
- /** @since 3.0 */
- int ParsingErrorMergeTokens = Syntax + Internal + 234;
- /** @since 3.0 */
- int ParsingErrorInvalidToken = Syntax + Internal + 235;
- /** @since 3.0 */
- int ParsingErrorMisplacedConstruct = Syntax + Internal + 236;
- /** @since 3.0 */
- int ParsingErrorReplaceTokens = Syntax + Internal + 237;
- /** @since 3.0 */
- int ParsingErrorNoSuggestionForTokens = Syntax + Internal + 238;
- /** @since 3.0 */
- int ParsingErrorUnexpectedEOF = Syntax + Internal + 239;
- /** @since 3.0 */
- int ParsingErrorInsertToComplete = Syntax + Internal + 240;
- /** @since 3.0 */
- int ParsingErrorInsertToCompleteScope = Syntax + Internal + 241;
- /** @since 3.0 */
- int ParsingErrorInsertToCompletePhrase = Syntax + Internal + 242;
-
- // scanner errors
- int EndOfSource = Syntax + Internal + 250;
- int InvalidHexa = Syntax + Internal + 251;
- int InvalidOctal = Syntax + Internal + 252;
- int InvalidCharacterConstant = Syntax + Internal + 253;
- int InvalidEscape = Syntax + Internal + 254;
- int InvalidInput = Syntax + Internal + 255;
- int InvalidUnicodeEscape = Syntax + Internal + 256;
- int InvalidFloat = Syntax + Internal + 257;
- int NullSourceString = Syntax + Internal + 258;
- int UnterminatedString = Syntax + Internal + 259;
- int UnterminatedComment = Syntax + Internal + 260;
- int NonExternalizedStringLiteral = Internal + 261;
- /** @since 3.1 */
- int InvalidDigit = Syntax + Internal + 262;
- /** @since 3.1 */
- int InvalidLowSurrogate = Syntax + Internal + 263;
- /** @since 3.1 */
- int InvalidHighSurrogate = Syntax + Internal + 264;
- /** @since 3.2 */
- int UnnecessaryNLSTag = Internal + 265;
- /** @since 3.7.1 */
- int InvalidBinary = Syntax + Internal + 266;
- /** @since 3.7.1 */
- int BinaryLiteralNotBelow17 = Syntax + Internal + 267;
- /** @since 3.7.1 */
- int IllegalUnderscorePosition = Syntax + Internal + 268;
- /** @since 3.7.1 */
- int UnderscoresInLiteralsNotBelow17 = Syntax + Internal + 269;
- /** @since 3.7.1 */
- int IllegalHexaLiteral = Syntax + Internal + 270;
-
- /** @since 3.10 */
- int MissingTypeInLambda = MethodRelated + 271;
- /** @since 3.23 */
- int UnterminatedTextBlock = PreviewRelated + 272;
- // type related problems
- /** @since 3.1 */
- int DiscouragedReference = TypeRelated + 280;
-
- int InterfaceCannotHaveInitializers = TypeRelated + 300;
- int DuplicateModifierForType = TypeRelated + 301;
- int IllegalModifierForClass = TypeRelated + 302;
- int IllegalModifierForInterface = TypeRelated + 303;
- int IllegalModifierForMemberClass = TypeRelated + 304;
- int IllegalModifierForMemberInterface = TypeRelated + 305;
- int IllegalModifierForLocalClass = TypeRelated + 306;
- /** @since 3.1 */
- int ForbiddenReference = TypeRelated + 307;
- int IllegalModifierCombinationFinalAbstractForClass = TypeRelated + 308;
- int IllegalVisibilityModifierForInterfaceMemberType = TypeRelated + 309;
- int IllegalVisibilityModifierCombinationForMemberType = TypeRelated + 310;
- int IllegalStaticModifierForMemberType = TypeRelated + 311;
- int SuperclassMustBeAClass = TypeRelated + 312;
- int ClassExtendFinalClass = TypeRelated + 313;
- int DuplicateSuperInterface = TypeRelated + 314;
- int SuperInterfaceMustBeAnInterface = TypeRelated + 315;
- int HierarchyCircularitySelfReference = TypeRelated + 316;
- int HierarchyCircularity = TypeRelated + 317;
- int HidingEnclosingType = TypeRelated + 318;
- int DuplicateNestedType = TypeRelated + 319;
- int CannotThrowType = TypeRelated + 320;
- int PackageCollidesWithType = TypeRelated + 321;
- int TypeCollidesWithPackage = TypeRelated + 322;
- int DuplicateTypes = TypeRelated + 323;
- int IsClassPathCorrect = TypeRelated + 324; // see also IsClasspathCorrectWithReferencingType below
- int PublicClassMustMatchFileName = TypeRelated + 325;
- /** @deprecated - problem is no longer generated */
- int MustSpecifyPackage = Internal + 326;
- int HierarchyHasProblems = TypeRelated + 327;
- int PackageIsNotExpectedPackage = Internal + 328;
- /** @since 2.1 */
- int ObjectCannotHaveSuperTypes = Internal + 329;
- /** @since 3.1 */
- int ObjectMustBeClass = Internal + 330;
- /** @since 3.4 */
- int RedundantSuperinterface = TypeRelated + 331;
- /** @since 3.5 */
- int ShouldImplementHashcode = TypeRelated + 332;
- /** @since 3.5 */
- int AbstractMethodsInConcreteClass = TypeRelated + 333;
-
- /** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
- int SuperclassNotFound = TypeRelated + 329 + ProblemReasons.NotFound; // TypeRelated + 330
- /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
- int SuperclassNotVisible = TypeRelated + 329 + ProblemReasons.NotVisible; // TypeRelated + 331
- /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
- int SuperclassAmbiguous = TypeRelated + 329 + ProblemReasons.Ambiguous; // TypeRelated + 332
- /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
- int SuperclassInternalNameProvided = TypeRelated + 329 + ProblemReasons.InternalNameProvided; // TypeRelated + 333
- /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
- int SuperclassInheritedNameHidesEnclosingName = TypeRelated + 329 + ProblemReasons.InheritedNameHidesEnclosingName; // TypeRelated + 334
-
- /** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
- int InterfaceNotFound = TypeRelated + 334 + ProblemReasons.NotFound; // TypeRelated + 335
- /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
- int InterfaceNotVisible = TypeRelated + 334 + ProblemReasons.NotVisible; // TypeRelated + 336
- /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
- int InterfaceAmbiguous = TypeRelated + 334 + ProblemReasons.Ambiguous; // TypeRelated + 337
- /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
- int InterfaceInternalNameProvided = TypeRelated + 334 + ProblemReasons.InternalNameProvided; // TypeRelated + 338
- /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
- int InterfaceInheritedNameHidesEnclosingName = TypeRelated + 334 + ProblemReasons.InheritedNameHidesEnclosingName; // TypeRelated + 339
-
- // field related problems
- int DuplicateField = FieldRelated + 340;
- int DuplicateModifierForField = FieldRelated + 341;
- int IllegalModifierForField = FieldRelated + 342;
- int IllegalModifierForInterfaceField = FieldRelated + 343;
- int IllegalVisibilityModifierCombinationForField = FieldRelated + 344;
- int IllegalModifierCombinationFinalVolatileForField = FieldRelated + 345;
- int UnexpectedStaticModifierForField = FieldRelated + 346;
- /** @since 3.32 */
- int IsClassPathCorrectWithReferencingType = TypeRelated + 347;
-
- /** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
- int FieldTypeNotFound = FieldRelated + 349 + ProblemReasons.NotFound; // FieldRelated + 350
- /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
- int FieldTypeNotVisible = FieldRelated + 349 + ProblemReasons.NotVisible; // FieldRelated + 351
- /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
- int FieldTypeAmbiguous = FieldRelated + 349 + ProblemReasons.Ambiguous; // FieldRelated + 352
- /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
- int FieldTypeInternalNameProvided = FieldRelated + 349 + ProblemReasons.InternalNameProvided; // FieldRelated + 353
- /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
- int FieldTypeInheritedNameHidesEnclosingName = FieldRelated + 349 + ProblemReasons.InheritedNameHidesEnclosingName; // FieldRelated + 354
-
- // method related problems
- int DuplicateMethod = MethodRelated + 355;
- int IllegalModifierForArgument = MethodRelated + 356;
- int DuplicateModifierForMethod = MethodRelated + 357;
- int IllegalModifierForMethod = MethodRelated + 358;
- int IllegalModifierForInterfaceMethod = MethodRelated + 359;
- int IllegalVisibilityModifierCombinationForMethod = MethodRelated + 360;
- int UnexpectedStaticModifierForMethod = MethodRelated + 361;
- int IllegalAbstractModifierCombinationForMethod = MethodRelated + 362;
- int AbstractMethodInAbstractClass = MethodRelated + 363;
- int ArgumentTypeCannotBeVoid = MethodRelated + 364;
- /** @deprecated - problem is no longer generated, use {@link #CannotAllocateVoidArray} instead */
- int ArgumentTypeCannotBeVoidArray = MethodRelated + 365;
- /** @deprecated - problem is no longer generated, use {@link #CannotAllocateVoidArray} instead */
- int ReturnTypeCannotBeVoidArray = MethodRelated + 366;
- int NativeMethodsCannotBeStrictfp = MethodRelated + 367;
- int DuplicateModifierForArgument = MethodRelated + 368;
- /** @since 3.5 */
- int IllegalModifierForConstructor = MethodRelated + 369;
-
- /** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
- int ArgumentTypeNotFound = MethodRelated + 369 + ProblemReasons.NotFound; // MethodRelated + 370
- /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
- int ArgumentTypeNotVisible = MethodRelated + 369 + ProblemReasons.NotVisible; // MethodRelated + 371
- /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
- int ArgumentTypeAmbiguous = MethodRelated + 369 + ProblemReasons.Ambiguous; // MethodRelated + 372
- /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
- int ArgumentTypeInternalNameProvided = MethodRelated + 369 + ProblemReasons.InternalNameProvided; // MethodRelated + 373
- /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
- int ArgumentTypeInheritedNameHidesEnclosingName = MethodRelated + 369 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 374
-
- /** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
- int ExceptionTypeNotFound = MethodRelated + 374 + ProblemReasons.NotFound; // MethodRelated + 375
- /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
- int ExceptionTypeNotVisible = MethodRelated + 374 + ProblemReasons.NotVisible; // MethodRelated + 376
- /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
- int ExceptionTypeAmbiguous = MethodRelated + 374 + ProblemReasons.Ambiguous; // MethodRelated + 377
- /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
- int ExceptionTypeInternalNameProvided = MethodRelated + 374 + ProblemReasons.InternalNameProvided; // MethodRelated + 378
- /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
- int ExceptionTypeInheritedNameHidesEnclosingName = MethodRelated + 374 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 379
-
- /** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
- int ReturnTypeNotFound = MethodRelated + 379 + ProblemReasons.NotFound; // MethodRelated + 380
- /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
- int ReturnTypeNotVisible = MethodRelated + 379 + ProblemReasons.NotVisible; // MethodRelated + 381
- /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
- int ReturnTypeAmbiguous = MethodRelated + 379 + ProblemReasons.Ambiguous; // MethodRelated + 382
- /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
- int ReturnTypeInternalNameProvided = MethodRelated + 379 + ProblemReasons.InternalNameProvided; // MethodRelated + 383
- /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
- int ReturnTypeInheritedNameHidesEnclosingName = MethodRelated + 379 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 384
-
- // import related problems
- int ConflictingImport = ImportRelated + 385;
- int DuplicateImport = ImportRelated + 386;
- int CannotImportPackage = ImportRelated + 387;
- int UnusedImport = ImportRelated + 388;
-
- int ImportNotFound = ImportRelated + 389 + ProblemReasons.NotFound; // ImportRelated + 390
- /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
- int ImportNotVisible = ImportRelated + 389 + ProblemReasons.NotVisible; // ImportRelated + 391
- /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
- int ImportAmbiguous = ImportRelated + 389 + ProblemReasons.Ambiguous; // ImportRelated + 392
- /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
- int ImportInternalNameProvided = ImportRelated + 389 + ProblemReasons.InternalNameProvided; // ImportRelated + 393
- /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
- int ImportInheritedNameHidesEnclosingName = ImportRelated + 389 + ProblemReasons.InheritedNameHidesEnclosingName; // ImportRelated + 394
-
- /** @since 3.1 */
- int InvalidTypeForStaticImport = ImportRelated + 391;
-
- // local variable related problems
- int DuplicateModifierForVariable = MethodRelated + 395;
- int IllegalModifierForVariable = MethodRelated + 396;
- /** @deprecated - problem is no longer generated, use {@link #RedundantNullCheckOnNonNullLocalVariable} instead */
- int LocalVariableCannotBeNull = Internal + 397; // since 3.3: semantics are LocalVariableRedundantCheckOnNonNull
- /** @deprecated - problem is no longer generated, use {@link #NullLocalVariableReference}, {@link #RedundantNullCheckOnNullLocalVariable} or {@link #RedundantLocalVariableNullAssignment} instead */
- int LocalVariableCanOnlyBeNull = Internal + 398; // since 3.3: split with LocalVariableRedundantCheckOnNull depending on context
- /** @deprecated - problem is no longer generated, use {@link #PotentialNullLocalVariableReference} instead */
- int LocalVariableMayBeNull = Internal + 399;
-
- // method verifier problems
- int AbstractMethodMustBeImplemented = MethodRelated + 400;
- int FinalMethodCannotBeOverridden = MethodRelated + 401;
- int IncompatibleExceptionInThrowsClause = MethodRelated + 402;
- int IncompatibleExceptionInInheritedMethodThrowsClause = MethodRelated + 403;
- int IncompatibleReturnType = MethodRelated + 404;
- int InheritedMethodReducesVisibility = MethodRelated + 405;
- int CannotOverrideAStaticMethodWithAnInstanceMethod = MethodRelated + 406;
- int CannotHideAnInstanceMethodWithAStaticMethod = MethodRelated + 407;
- int StaticInheritedMethodConflicts = MethodRelated + 408;
- int MethodReducesVisibility = MethodRelated + 409;
- int OverridingNonVisibleMethod = MethodRelated + 410;
- int AbstractMethodCannotBeOverridden = MethodRelated + 411;
- int OverridingDeprecatedMethod = MethodRelated + 412;
- /** @since 2.1 */
- int IncompatibleReturnTypeForNonInheritedInterfaceMethod = MethodRelated + 413;
- /** @since 2.1 */
- int IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod = MethodRelated + 414;
- /** @since 3.1 */
- int IllegalVararg = MethodRelated + 415;
- /** @since 3.3 */
- int OverridingMethodWithoutSuperInvocation = MethodRelated + 416;
- /** @since 3.5 */
- int MissingSynchronizedModifierInInheritedMethod= MethodRelated + 417;
- /** @since 3.5 */
- int AbstractMethodMustBeImplementedOverConcreteMethod = MethodRelated + 418;
- /** @since 3.5 */
- int InheritedIncompatibleReturnType = MethodRelated + 419;
-
- // code snippet support
- int CodeSnippetMissingClass = Internal + 420;
- int CodeSnippetMissingMethod = Internal + 421;
- int CannotUseSuperInCodeSnippet = Internal + 422;
-
- //constant pool
- int TooManyConstantsInConstantPool = Internal + 430;
- /** @since 2.1 */
- int TooManyBytesForStringConstant = Internal + 431;
-
- // static constraints
- /** @since 2.1 */
- int TooManyFields = Internal + 432;
- /** @since 2.1 */
- int TooManyMethods = Internal + 433;
- /** @since 3.7 */
- int TooManyParametersForSyntheticMethod = Internal + 434;
-
- // 1.4 features
- // assertion warning
- int UseAssertAsAnIdentifier = Internal + 440;
-
- // 1.5 features
- int UseEnumAsAnIdentifier = Internal + 441;
- /** @since 3.2 */
- int EnumConstantsCannotBeSurroundedByParenthesis = Syntax + Internal + 442;
-
- /** @since 3.10 */
- int IllegalUseOfUnderscoreAsAnIdentifier = Syntax + Internal + 443;
- /** @since 3.10 */
- int UninternedIdentityComparison = Syntax + Internal + 444;
- /** @since 3.24 */
- int ErrorUseOfUnderscoreAsAnIdentifier = Syntax + Internal + 445;
-
- // detected task
- /** @since 2.1 */
- int Task = Internal + 450;
-
- // local variables related problems, cont'd
- /** @since 3.3 */
- int NullLocalVariableReference = Internal + 451;
- /** @since 3.3 */
- int PotentialNullLocalVariableReference = Internal + 452;
- /** @since 3.3 */
- int RedundantNullCheckOnNullLocalVariable = Internal + 453;
- /** @since 3.3 */
- int NullLocalVariableComparisonYieldsFalse = Internal + 454;
- /** @since 3.3 */
- int RedundantLocalVariableNullAssignment = Internal + 455;
- /** @since 3.3 */
- int NullLocalVariableInstanceofYieldsFalse = Internal + 456;
- /** @since 3.3 */
- int RedundantNullCheckOnNonNullLocalVariable = Internal + 457;
- /** @since 3.3 */
- int NonNullLocalVariableComparisonYieldsFalse = Internal + 458;
- /** @since 3.9 */
- int PotentialNullUnboxing = Internal + 459;
- /** @since 3.9 */
- int NullUnboxing = Internal + 461;
-
- // block
- /** @since 3.0 */
- int UndocumentedEmptyBlock = Internal + 460;
-
- /*
- * Javadoc comments
- */
- /**
- * Problem signaled on an invalid URL reference.
- * Valid syntax example: @see "http://www.eclipse.org/"
- * @since 3.4
- */
- int JavadocInvalidSeeUrlReference = Javadoc + Internal + 462;
- /**
- * Problem warned on missing tag description.
- * @since 3.4
- */
- int JavadocMissingTagDescription = Javadoc + Internal + 463;
- /**
- * Problem warned on duplicated tag.
- * @since 3.3
- */
- int JavadocDuplicateTag = Javadoc + Internal + 464;
- /**
- * Problem signaled on an hidden reference due to a too low visibility level.
- * @since 3.3
- */
- int JavadocHiddenReference = Javadoc + Internal + 465;
- /**
- * Problem signaled on an invalid qualification for member type reference.
- * @since 3.3
- */
- int JavadocInvalidMemberTypeQualification = Javadoc + Internal + 466;
- /** @since 3.2 */
- int JavadocMissingIdentifier = Javadoc + Internal + 467;
- /** @since 3.2 */
- int JavadocNonStaticTypeFromStaticInvocation = Javadoc + Internal + 468;
- /** @since 3.1 */
- int JavadocInvalidParamTagTypeParameter = Javadoc + Internal + 469;
- /** @since 3.0 */
- int JavadocUnexpectedTag = Javadoc + Internal + 470;
- /** @since 3.0 */
- int JavadocMissingParamTag = Javadoc + Internal + 471;
- /** @since 3.0 */
- int JavadocMissingParamName = Javadoc + Internal + 472;
- /** @since 3.0 */
- int JavadocDuplicateParamName = Javadoc + Internal + 473;
- /** @since 3.0 */
- int JavadocInvalidParamName = Javadoc + Internal + 474;
- /** @since 3.0 */
- int JavadocMissingReturnTag = Javadoc + Internal + 475;
- /** @since 3.0 */
- int JavadocDuplicateReturnTag = Javadoc + Internal + 476;
- /** @since 3.0 */
- int JavadocMissingThrowsTag = Javadoc + Internal + 477;
- /** @since 3.0 */
- int JavadocMissingThrowsClassName = Javadoc + Internal + 478;
- /** @since 3.0 */
- int JavadocInvalidThrowsClass = Javadoc + Internal + 479;
- /** @since 3.0 */
- int JavadocDuplicateThrowsClassName = Javadoc + Internal + 480;
- /** @since 3.0 */
- int JavadocInvalidThrowsClassName = Javadoc + Internal + 481;
- /** @since 3.0 */
- int JavadocMissingSeeReference = Javadoc + Internal + 482;
- /** @since 3.0 */
- int JavadocInvalidSeeReference = Javadoc + Internal + 483;
- /**
- * Problem signaled on an invalid URL reference that does not conform to the href syntax.
- * Valid syntax example: @see Eclipse Home Page
- * @since 3.0
- */
- int JavadocInvalidSeeHref = Javadoc + Internal + 484;
- /** @since 3.0 */
- int JavadocInvalidSeeArgs = Javadoc + Internal + 485;
- /** @since 3.0 */
- int JavadocMissing = Javadoc + Internal + 486;
- /** @since 3.0 */
- int JavadocInvalidTag = Javadoc + Internal + 487;
- /*
- * ID for field errors in Javadoc
- */
- /** @since 3.0 */
- int JavadocUndefinedField = Javadoc + Internal + 488;
- /** @since 3.0 */
- int JavadocNotVisibleField = Javadoc + Internal + 489;
- /** @since 3.0 */
- int JavadocAmbiguousField = Javadoc + Internal + 490;
- /** @since 3.0 */
- int JavadocUsingDeprecatedField = Javadoc + Internal + 491;
- /*
- * IDs for constructor errors in Javadoc
- */
- /** @since 3.0 */
- int JavadocUndefinedConstructor = Javadoc + Internal + 492;
- /** @since 3.0 */
- int JavadocNotVisibleConstructor = Javadoc + Internal + 493;
- /** @since 3.0 */
- int JavadocAmbiguousConstructor = Javadoc + Internal + 494;
- /** @since 3.0 */
- int JavadocUsingDeprecatedConstructor = Javadoc + Internal + 495;
- /*
- * IDs for method errors in Javadoc
- */
- /** @since 3.0 */
- int JavadocUndefinedMethod = Javadoc + Internal + 496;
- /** @since 3.0 */
- int JavadocNotVisibleMethod = Javadoc + Internal + 497;
- /** @since 3.0 */
- int JavadocAmbiguousMethod = Javadoc + Internal + 498;
- /** @since 3.0 */
- int JavadocUsingDeprecatedMethod = Javadoc + Internal + 499;
- /** @since 3.0 */
- int JavadocNoMessageSendOnBaseType = Javadoc + Internal + 500;
- /** @since 3.0 */
- int JavadocParameterMismatch = Javadoc + Internal + 501;
- /** @since 3.0 */
- int JavadocNoMessageSendOnArrayType = Javadoc + Internal + 502;
- /*
- * IDs for type errors in Javadoc
- */
- /** @since 3.0 */
- int JavadocUndefinedType = Javadoc + Internal + 503;
- /** @since 3.0 */
- int JavadocNotVisibleType = Javadoc + Internal + 504;
- /** @since 3.0 */
- int JavadocAmbiguousType = Javadoc + Internal + 505;
- /** @since 3.0 */
- int JavadocUsingDeprecatedType = Javadoc + Internal + 506;
- /** @since 3.0 */
- int JavadocInternalTypeNameProvided = Javadoc + Internal + 507;
- /** @since 3.0 */
- int JavadocInheritedMethodHidesEnclosingName = Javadoc + Internal + 508;
- /** @since 3.0 */
- int JavadocInheritedFieldHidesEnclosingName = Javadoc + Internal + 509;
- /** @since 3.0 */
- int JavadocInheritedNameHidesEnclosingTypeName = Javadoc + Internal + 510;
- /** @since 3.0 */
- int JavadocAmbiguousMethodReference = Javadoc + Internal + 511;
- /** @since 3.0 */
- int JavadocUnterminatedInlineTag = Javadoc + Internal + 512;
- /** @since 3.0 */
- int JavadocMalformedSeeReference = Javadoc + Internal + 513;
- /** @since 3.0 */
- int JavadocMessagePrefix = Internal + 514;
-
- /** @since 3.1 */
- int JavadocMissingHashCharacter = Javadoc + Internal + 515;
- /** @since 3.1 */
- int JavadocEmptyReturnTag = Javadoc + Internal + 516;
- /** @since 3.1 */
- int JavadocInvalidValueReference = Javadoc + Internal + 517;
- /** @since 3.1 */
- int JavadocUnexpectedText = Javadoc + Internal + 518;
- /** @since 3.1 */
- int JavadocInvalidParamTagName = Javadoc + Internal + 519;
-
- // see also JavadocNotAccessibleType below
-
- /*
- * IDs for module errors in Javadoc
- */
- /** @since 3.20 */
- int JavadocMissingUsesTag = Javadoc + Internal + 1800;
- /** @since 3.20 */
- int JavadocDuplicateUsesTag = Javadoc + Internal + 1801;
- /** @since 3.20 */
- int JavadocMissingUsesClassName = Javadoc + Internal + 1802;
- /** @since 3.20 */
- int JavadocInvalidUsesClassName = Javadoc + Internal + 1803;
- /** @since 3.20 */
- int JavadocInvalidUsesClass = Javadoc + Internal + 1804;
- /** @since 3.20 */
- int JavadocMissingProvidesTag = Javadoc + Internal + 1805;
- /** @since 3.20 */
- int JavadocDuplicateProvidesTag = Javadoc + Internal + 1806;
- /** @since 3.20 */
- int JavadocMissingProvidesClassName = Javadoc + Internal + 1807;
- /** @since 3.20 */
- int JavadocInvalidProvidesClassName = Javadoc + Internal + 1808;
- /** @since 3.20 */
- int JavadocInvalidProvidesClass = Javadoc + Internal + 1809;
- /** @since 3.24*/
- int JavadocInvalidModuleQualification = Javadoc + Internal + 1810;
- /** @since 3.29*/
- int JavadocInvalidModule = Javadoc + Internal + 1811;
- /** @since 3.30*/
- int JavadocInvalidSnippet = Javadoc + Internal + 1812;
- /** @since 3.30 */
- int JavadocInvalidSnippetMissingColon = Javadoc + Internal + 1813;
- /** @since 3.30 */
- int JavadocInvalidSnippetContentNewLine = Javadoc + Internal + 1814;
- /** @since 3.30 */
- int JavadocInvalidSnippetRegionNotClosed = Javadoc + Internal + 1815;
- /** @since 3.30 */
- int JavadocInvalidSnippetRegexSubstringTogether = Javadoc + Internal + 1816;
- /** @since 3.30 */
- int JavadocInvalidSnippetDuplicateRegions = Javadoc + Internal + 1817;
-
- /**
- * Generics
- */
- /** @since 3.1 */
- int DuplicateTypeVariable = Internal + 520;
- /** @since 3.1 */
- int IllegalTypeVariableSuperReference = Internal + 521;
- /** @since 3.1 */
- int NonStaticTypeFromStaticInvocation = Internal + 522;
- /** @since 3.1 */
- int ObjectCannotBeGeneric = Internal + 523;
- /** @since 3.1 */
- int NonGenericType = TypeRelated + 524;
- /** @since 3.1 */
- int IncorrectArityForParameterizedType = TypeRelated + 525;
- /** @since 3.1 */
- int TypeArgumentMismatch = TypeRelated + 526;
- /** @since 3.1 */
- int DuplicateMethodErasure = TypeRelated + 527;
- /** @since 3.1 */
- int ReferenceToForwardTypeVariable = TypeRelated + 528;
- /** @since 3.1 */
- int BoundMustBeAnInterface = TypeRelated + 529;
- /** @since 3.1 */
- int UnsafeRawConstructorInvocation = TypeRelated + 530;
- /** @since 3.1 */
- int UnsafeRawMethodInvocation = TypeRelated + 531;
- /** @since 3.1 */
- int UnsafeTypeConversion = TypeRelated + 532;
- /** @since 3.1 */
- int InvalidTypeVariableExceptionType = TypeRelated + 533;
- /** @since 3.1 */
- int InvalidParameterizedExceptionType = TypeRelated + 534;
- /** @since 3.1 */
- int IllegalGenericArray = TypeRelated + 535;
- /** @since 3.1 */
- int UnsafeRawFieldAssignment = TypeRelated + 536;
- /** @since 3.1 */
- int FinalBoundForTypeVariable = TypeRelated + 537;
- /** @since 3.1 */
- int UndefinedTypeVariable = Internal + 538;
- /** @since 3.1 */
- int SuperInterfacesCollide = TypeRelated + 539;
- /** @since 3.1 */
- int WildcardConstructorInvocation = TypeRelated + 540;
- /** @since 3.1 */
- int WildcardMethodInvocation = TypeRelated + 541;
- /** @since 3.1 */
- int WildcardFieldAssignment = TypeRelated + 542;
- /** @since 3.1 */
- int GenericMethodTypeArgumentMismatch = TypeRelated + 543;
- /** @since 3.1 */
- int GenericConstructorTypeArgumentMismatch = TypeRelated + 544;
- /** @since 3.1 */
- int UnsafeGenericCast = TypeRelated + 545;
- /** @since 3.1 */
- int IllegalInstanceofParameterizedType = Internal + 546;
- /** @since 3.1 */
- int IllegalInstanceofTypeParameter = Internal + 547;
- /** @since 3.1 */
- int NonGenericMethod = TypeRelated + 548;
- /** @since 3.1 */
- int IncorrectArityForParameterizedMethod = TypeRelated + 549;
- /** @since 3.1 */
- int ParameterizedMethodArgumentTypeMismatch = TypeRelated + 550;
- /** @since 3.1 */
- int NonGenericConstructor = TypeRelated + 551;
- /** @since 3.1 */
- int IncorrectArityForParameterizedConstructor = TypeRelated + 552;
- /** @since 3.1 */
- int ParameterizedConstructorArgumentTypeMismatch = TypeRelated + 553;
- /** @since 3.1 */
- int TypeArgumentsForRawGenericMethod = TypeRelated + 554;
- /** @since 3.1 */
- int TypeArgumentsForRawGenericConstructor = TypeRelated + 555;
- /** @since 3.1 */
- int SuperTypeUsingWildcard = TypeRelated + 556;
- /** @since 3.1 */
- int GenericTypeCannotExtendThrowable = TypeRelated + 557;
- /** @since 3.1 */
- int IllegalClassLiteralForTypeVariable = TypeRelated + 558;
- /** @since 3.1 */
- int UnsafeReturnTypeOverride = MethodRelated + 559;
- /** @since 3.1 */
- int MethodNameClash = MethodRelated + 560;
- /** @since 3.1 */
- int RawMemberTypeCannotBeParameterized = TypeRelated + 561;
- /** @since 3.1 */
- int MissingArgumentsForParameterizedMemberType = TypeRelated + 562;
- /** @since 3.1 */
- int StaticMemberOfParameterizedType = TypeRelated + 563;
- /** @since 3.1 */
- int BoundHasConflictingArguments = TypeRelated + 564;
- /** @since 3.1 */
- int DuplicateParameterizedMethods = MethodRelated + 565;
- /** @since 3.1 */
- int IllegalQualifiedParameterizedTypeAllocation = TypeRelated + 566;
- /** @since 3.1 */
- int DuplicateBounds = TypeRelated + 567;
- /** @since 3.1 */
- int BoundCannotBeArray = TypeRelated + 568;
- /** @since 3.1 */
- int UnsafeRawGenericConstructorInvocation = TypeRelated + 569;
- /** @since 3.1 */
- int UnsafeRawGenericMethodInvocation = TypeRelated + 570;
- /** @since 3.1 */
- int TypeParameterHidingType = TypeRelated + 571;
- /** @since 3.2 */
- int RawTypeReference = TypeRelated + 572;
- /** @since 3.2 */
- int NoAdditionalBoundAfterTypeVariable = TypeRelated + 573;
- /** @since 3.2 */
- int UnsafeGenericArrayForVarargs = MethodRelated + 574;
- /** @since 3.2 */
- int IllegalAccessFromTypeVariable = TypeRelated + 575;
- /** @since 3.3 */
- int TypeHidingTypeParameterFromType = TypeRelated + 576;
- /** @since 3.3 */
- int TypeHidingTypeParameterFromMethod = TypeRelated + 577;
- /** @since 3.3 */
- int InvalidUsageOfWildcard = Syntax + Internal + 578;
- /** @since 3.4 */
- int UnusedTypeArgumentsForMethodInvocation = MethodRelated + 579;
-
- /**
- * Foreach
- */
- /** @since 3.1 */
- int IncompatibleTypesInForeach = TypeRelated + 580;
- /** @since 3.1 */
- int InvalidTypeForCollection = Internal + 581;
- /** @since 3.6*/
- int InvalidTypeForCollectionTarget14 = Internal + 582;
-
- /** @since 3.7.1 */
- int DuplicateInheritedMethods = MethodRelated + 583;
- /** @since 3.8 */
- int MethodNameClashHidden = MethodRelated + 584;
-
- /** @since 3.9 */
- int UnsafeElementTypeConversion = TypeRelated + 585;
- /** @since 3.11 */
- int InvalidTypeArguments = MethodRelated + TypeRelated + 586;
-
- /**
- * 1.5 Syntax errors (when source level < 1.5)
- */
- /** @since 3.1 */
- int InvalidUsageOfTypeParameters = Syntax + Internal + 590;
- /** @since 3.1 */
- int InvalidUsageOfStaticImports = Syntax + Internal + 591;
- /** @since 3.1 */
- int InvalidUsageOfForeachStatements = Syntax + Internal + 592;
- /** @since 3.1 */
- int InvalidUsageOfTypeArguments = Syntax + Internal + 593;
- /** @since 3.1 */
- int InvalidUsageOfEnumDeclarations = Syntax + Internal + 594;
- /** @since 3.1 */
- int InvalidUsageOfVarargs = Syntax + Internal + 595;
- /** @since 3.1 */
- int InvalidUsageOfAnnotations = Syntax + Internal + 596;
- /** @since 3.1 */
- int InvalidUsageOfAnnotationDeclarations = Syntax + Internal + 597;
- /** @since 3.4 */
- int InvalidUsageOfTypeParametersForAnnotationDeclaration = Syntax + Internal + 598;
- /** @since 3.4 */
- int InvalidUsageOfTypeParametersForEnumDeclaration = Syntax + Internal + 599;
- /**
- * Annotation
- */
- /** @since 3.1 */
- int IllegalModifierForAnnotationMethod = MethodRelated + 600;
- /** @since 3.1 */
- int IllegalExtendedDimensions = MethodRelated + 601;
- /** @since 3.1 */
- int InvalidFileNameForPackageAnnotations = Syntax + Internal + 602;
- /** @since 3.1 */
- int IllegalModifierForAnnotationType = TypeRelated + 603;
- /** @since 3.1 */
- int IllegalModifierForAnnotationMemberType = TypeRelated + 604;
- /** @since 3.1 */
- int InvalidAnnotationMemberType = TypeRelated + 605;
- /** @since 3.1 */
- int AnnotationCircularitySelfReference = TypeRelated + 606;
- /** @since 3.1 */
- int AnnotationCircularity = TypeRelated + 607;
- /** @since 3.1 */
- int DuplicateAnnotation = TypeRelated + 608;
- /** @since 3.1 */
- int MissingValueForAnnotationMember = TypeRelated + 609;
- /** @since 3.1 */
- int DuplicateAnnotationMember = Internal + 610;
- /** @since 3.1 */
- int UndefinedAnnotationMember = MethodRelated + 611;
- /** @since 3.1 */
- int AnnotationValueMustBeClassLiteral = Internal + 612;
- /** @since 3.1 */
- int AnnotationValueMustBeConstant = Internal + 613;
- /** @deprecated - problem is no longer generated (code is legite)
- * @since 3.1 */
- int AnnotationFieldNeedConstantInitialization = Internal + 614;
- /** @since 3.1 */
- int IllegalModifierForAnnotationField = Internal + 615;
- /** @since 3.1 */
- int AnnotationCannotOverrideMethod = MethodRelated + 616;
- /** @since 3.1 */
- int AnnotationMembersCannotHaveParameters = Syntax + Internal + 617;
- /** @since 3.1 */
- int AnnotationMembersCannotHaveTypeParameters = Syntax + Internal + 618;
- /** @since 3.1 */
- int AnnotationTypeDeclarationCannotHaveSuperclass = Syntax + Internal + 619;
- /** @since 3.1 */
- int AnnotationTypeDeclarationCannotHaveSuperinterfaces = Syntax + Internal + 620;
- /** @since 3.1 */
- int DuplicateTargetInTargetAnnotation = Internal + 621;
- /** @since 3.1 */
- int DisallowedTargetForAnnotation = TypeRelated + 622;
- /** @since 3.1 */
- int MethodMustOverride = MethodRelated + 623;
- /** @since 3.1 */
- int AnnotationTypeDeclarationCannotHaveConstructor = Syntax + Internal + 624;
- /** @since 3.1 */
- int AnnotationValueMustBeAnnotation = Internal + 625;
- /** @since 3.1 */
- int AnnotationTypeUsedAsSuperInterface = TypeRelated + 626;
- /** @since 3.1 */
- int MissingOverrideAnnotation = MethodRelated + 627;
- /** @since 3.1 */
- int FieldMissingDeprecatedAnnotation = Internal + 628;
- /** @since 3.1 */
- int MethodMissingDeprecatedAnnotation = Internal + 629;
- /** @since 3.1 */
- int TypeMissingDeprecatedAnnotation = Internal + 630;
- /** @since 3.1 */
- int UnhandledWarningToken = Internal + 631;
- /** @since 3.2 */
- int AnnotationValueMustBeArrayInitializer = Internal + 632;
- /** @since 3.3 */
- int AnnotationValueMustBeAnEnumConstant = Internal + 633;
- /** @since 3.3 */
- int MethodMustOverrideOrImplement = MethodRelated + 634;
- /** @since 3.4 */
- int UnusedWarningToken = Internal + 635;
- /** @since 3.6 */
- int MissingOverrideAnnotationForInterfaceMethodImplementation = MethodRelated + 636;
- /** @since 3.10 */
- int InvalidUsageOfTypeAnnotations = Syntax + Internal + 637;
- /** @since 3.10 */
- int DisallowedExplicitThisParameter = Syntax + Internal + 638;
- /** @since 3.10 */
- int MisplacedTypeAnnotations = Syntax + Internal + 639;
- /** @since 3.10 */
- int IllegalTypeAnnotationsInStaticMemberAccess = Internal + Syntax + 640;
- /** @since 3.10 */
- int IllegalUsageOfTypeAnnotations = Internal + Syntax + 641;
- /** @since 3.10 */
- int IllegalDeclarationOfThisParameter = Internal + Syntax + 642;
- /** @since 3.10 */
- int ExplicitThisParameterNotBelow18 = Internal + Syntax + 643;
- /** @since 3.10 */
- int DefaultMethodNotBelow18 = Internal + Syntax + 644;
- /** @since 3.10 */
- int LambdaExpressionNotBelow18 = Internal + Syntax + 645;
- /** @since 3.10 */
- int MethodReferenceNotBelow18 = Internal + Syntax + 646;
- /** @since 3.10 */
- int ConstructorReferenceNotBelow18 = Internal + Syntax + 647;
- /** @since 3.10 */
- int ExplicitThisParameterNotInLambda = Internal + Syntax + 648;
- /** @since 3.10 */
- int ExplicitAnnotationTargetRequired = TypeRelated + 649;
- /** @since 3.10 */
- int IllegalTypeForExplicitThis = Internal + Syntax + 650;
- /** @since 3.10 */
- int IllegalQualifierForExplicitThis = Internal + Syntax + 651;
- /** @since 3.10 */
- int IllegalQualifierForExplicitThis2 = Internal + Syntax + 652;
- /** @since 3.10 */
- int TargetTypeNotAFunctionalInterface = Internal + TypeRelated + 653;
- /** @since 3.10 */
- int IllegalVarargInLambda = Internal + TypeRelated + 654;
- /** @since 3.10 */
- int illFormedParameterizationOfFunctionalInterface = Internal + TypeRelated + 655;
- /** @since 3.10 */
- int lambdaSignatureMismatched = Internal + TypeRelated + 656;
- /** @since 3.10 */
- int lambdaParameterTypeMismatched = Internal + TypeRelated + 657;
- /** @since 3.10 */
- int IncompatibleLambdaParameterType = Internal + TypeRelated + 658;
- /** @since 3.10 */
- int NoGenericLambda = Internal + TypeRelated + 659;
- /**
- * More problems in generics
- */
- /** @since 3.4 */
- int UnusedTypeArgumentsForConstructorInvocation = MethodRelated + 660;
- /** @since 3.9 */
- int UnusedTypeParameter = TypeRelated + 661;
- /** @since 3.9 */
- int IllegalArrayOfUnionType = TypeRelated + 662;
- /** @since 3.10 */
- int OuterLocalMustBeEffectivelyFinal = Internal + 663;
- /** @since 3.10 */
- int InterfaceNotFunctionalInterface = Internal + TypeRelated + 664;
- /** @since 3.10 */
- int ConstructionTypeMismatch = Internal + TypeRelated + 665;
- /** @since 3.10 */
- int ToleratedMisplacedTypeAnnotations = Syntax + Internal + 666;
- /** @since 3.13*/
- int InterfaceSuperInvocationNotBelow18 = Internal + Syntax + 667;
- /** @since 3.13*/
- int InterfaceStaticMethodInvocationNotBelow18 = Internal + Syntax + 668;
- /** @since 3.14 */
- int FieldMustBeFinal = Internal + 669;
-
-
- /**
- * Null analysis for other kinds of expressions, syntactically nonnull
- */
- /** @since 3.9 */
- int NonNullExpressionComparisonYieldsFalse = Internal + 670;
- /** @since 3.9 */
- int RedundantNullCheckOnNonNullExpression = Internal + 671;
- /** @since 3.9 */
- int NullExpressionReference = Internal + 672;
- /** @since 3.9 */
- int PotentialNullExpressionReference = Internal + 673;
-
- /**
- * Corrupted binaries
- */
- /** @since 3.1 */
- int CorruptedSignature = Internal + 700;
- /**
- * Corrupted source
- */
- /** @since 3.2 */
- int InvalidEncoding = Internal + 701;
- /** @since 3.2 */
- int CannotReadSource = Internal + 702;
-
- /**
- * Autoboxing
- */
- /** @since 3.1 */
- int BoxingConversion = Internal + 720;
- /** @since 3.1 */
- int UnboxingConversion = Internal + 721;
-
- /**
- * Modifiers
- * @since 3.28
- */
- int StrictfpNotRequired = Syntax + Internal + 741;
-
- /**
- * Enum
- */
- /** @since 3.1 */
- int IllegalModifierForEnum = TypeRelated + 750;
- /** @since 3.1 */
- int IllegalModifierForEnumConstant = FieldRelated + 751;
- /** @deprecated - problem could not be reported, enums cannot be local takes precedence
- * @since 3.1 */
- int IllegalModifierForLocalEnum = TypeRelated + 752;
- /** @since 3.1 */
- int IllegalModifierForMemberEnum = TypeRelated + 753;
- /** @since 3.1 */
- int CannotDeclareEnumSpecialMethod = MethodRelated + 754;
- /** @since 3.1 */
- int IllegalQualifiedEnumConstantLabel = FieldRelated + 755;
- /** @since 3.1 */
- int CannotExtendEnum = TypeRelated + 756;
- /** @since 3.1 */
- int CannotInvokeSuperConstructorInEnum = MethodRelated + 757;
- /** @since 3.1 */
- int EnumAbstractMethodMustBeImplemented = MethodRelated + 758;
- /** @since 3.1 */
- int EnumSwitchCannotTargetField = FieldRelated + 759;
- /** @since 3.1 */
- int IllegalModifierForEnumConstructor = MethodRelated + 760;
- /** @since 3.1 */
- int MissingEnumConstantCase = FieldRelated + 761;
- /** @since 3.2 */ // TODO need to fix 3.1.1 contribution (inline this constant on client side)
- int EnumStaticFieldInInInitializerContext = FieldRelated + 762;
- /** @since 3.4 */
- int EnumConstantMustImplementAbstractMethod = MethodRelated + 763;
- /** @since 3.5 */
- int EnumConstantCannotDefineAbstractMethod = MethodRelated + 764;
- /** @since 3.5 */
- int AbstractMethodInEnum = MethodRelated + 765;
- /** @since 3.8 */
- int MissingEnumDefaultCase = Internal + 766;
- /** @since 3.8 */
- int MissingDefaultCase = Internal + 767;
- /** @since 3.8 */
- int MissingEnumConstantCaseDespiteDefault = FieldRelated + 768;
- /** @since 3.8 */
- int UninitializedLocalVariableHintMissingDefault = Internal + 769;
- /** @since 3.8 */
- int UninitializedBlankFinalFieldHintMissingDefault = FieldRelated + 770;
- /** @since 3.8 */
- int ShouldReturnValueHintMissingDefault = MethodRelated + 771;
-
- /**
- * Var args
- */
- /** @since 3.1 */
- int IllegalExtendedDimensionsForVarArgs = Syntax + Internal + 800;
- /** @since 3.1 */
- int MethodVarargsArgumentNeedCast = MethodRelated + 801;
- /** @since 3.1 */
- int ConstructorVarargsArgumentNeedCast = ConstructorRelated + 802;
- /** @since 3.1 */
- int VarargsConflict = MethodRelated + 803;
- /** @since 3.7.1 */
- int SafeVarargsOnFixedArityMethod = MethodRelated + 804;
- /** @since 3.7.1 */
- int SafeVarargsOnNonFinalInstanceMethod = MethodRelated + 805;
- /** @since 3.7.1 */
- int PotentialHeapPollutionFromVararg = MethodRelated + 806;
- /** @since 3.8 */
- int VarargsElementTypeNotVisible = MethodRelated + 807;
- /** @since 3.8 */
- int VarargsElementTypeNotVisibleForConstructor = ConstructorRelated + 808;
- /** @since 3.10 */
- int ApplicableMethodOverriddenByInapplicable = MethodRelated + 809;
-
- /**
- * Javadoc Generic
- */
- /** @since 3.1 */
- int JavadocGenericMethodTypeArgumentMismatch = Javadoc + Internal + 850;
- /** @since 3.1 */
- int JavadocNonGenericMethod = Javadoc + Internal + 851;
- /** @since 3.1 */
- int JavadocIncorrectArityForParameterizedMethod = Javadoc + Internal + 852;
- /** @since 3.1 */
- int JavadocParameterizedMethodArgumentTypeMismatch = Javadoc + Internal + 853;
- /** @since 3.1 */
- int JavadocTypeArgumentsForRawGenericMethod = Javadoc + Internal + 854;
- /** @since 3.1 */
- int JavadocGenericConstructorTypeArgumentMismatch = Javadoc + Internal + 855;
- /** @since 3.1 */
- int JavadocNonGenericConstructor = Javadoc + Internal + 856;
- /** @since 3.1 */
- int JavadocIncorrectArityForParameterizedConstructor = Javadoc + Internal + 857;
- /** @since 3.1 */
- int JavadocParameterizedConstructorArgumentTypeMismatch = Javadoc + Internal + 858;
- /** @since 3.1 */
- int JavadocTypeArgumentsForRawGenericConstructor = Javadoc + Internal + 859;
-
- /**
- * Java 7 errors
- */
- /** @since 3.7.1 */
- int AssignmentToMultiCatchParameter = Internal + 870;
- /** @since 3.7.1 */
- int ResourceHasToImplementAutoCloseable = TypeRelated + 871;
- /** @since 3.7.1 */
- int AssignmentToResource = Internal + 872;
- /** @since 3.7.1 */
- int InvalidUnionTypeReferenceSequence = Internal + TypeRelated + 873;
- /** @since 3.7.1 */
- int AutoManagedResourceNotBelow17 = Syntax + Internal + 874;
- /** @since 3.7.1 */
- int MultiCatchNotBelow17 = Syntax + Internal + 875;
- /** @since 3.7.1 */
- int PolymorphicMethodNotBelow17 = MethodRelated + 876;
- /** @since 3.7.1 */
- int IncorrectSwitchType17 = TypeRelated + 877;
- /** @since 3.7.1 */
- int CannotInferElidedTypes = TypeRelated + 878;
- /** @since 3.7.1 */
- int CannotUseDiamondWithExplicitTypeArguments = TypeRelated + 879;
- /** @since 3.7.1 */
- int CannotUseDiamondWithAnonymousClasses = TypeRelated + 880;
- /** @since 3.7.1 */
- int SwitchOnStringsNotBelow17 = TypeRelated + 881; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=348492
- /** @since 3.7.1 */
- int UnhandledExceptionOnAutoClose = TypeRelated + 882;
- /** @since 3.7.1 */
- int DiamondNotBelow17 = TypeRelated + 883;
- /** @since 3.7.1 */
- int RedundantSpecificationOfTypeArguments = TypeRelated + 884;
- /** @since 3.8 */
- int PotentiallyUnclosedCloseable = Internal + 885;
- /** @since 3.8 */
- int PotentiallyUnclosedCloseableAtExit = Internal + 886;
- /** @since 3.8 */
- int UnclosedCloseable = Internal + 887;
- /** @since 3.8 */
- int UnclosedCloseableAtExit = Internal + 888;
- /** @since 3.8 */
- int ExplicitlyClosedAutoCloseable = Internal + 889;
- /** @since 3.8 */
- int SwitchOnEnumNotBelow15 = TypeRelated + 890; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=360317
- /** @since 3.10 */
- int IntersectionCastNotBelow18 = TypeRelated + 891;
- /** @since 3.10 */
- int IllegalBasetypeInIntersectionCast = TypeRelated + 892;
- /** @since 3.10 */
- int IllegalArrayTypeInIntersectionCast = TypeRelated + 893;
- /** @since 3.10 */
- int DuplicateBoundInIntersectionCast = TypeRelated + 894;
- /** @deprecated This problem is no longer reported; number Of functional interface is not an issue, number of abstract methods is.
- * @since 3.10 */
- int MultipleFunctionalInterfaces = TypeRelated + 895;
- /** @since 3.10 */
- int StaticInterfaceMethodNotBelow18 = Internal + Syntax + 896;
- /** @since 3.10 */
- int DuplicateAnnotationNotMarkedRepeatable = TypeRelated + 897;
- /** @since 3.10 */
- int DisallowedTargetForContainerAnnotationType = TypeRelated + 898;
- /** @since 3.10 */
- int RepeatedAnnotationWithContainerAnnotation = TypeRelated + 899;
-
- /** @since 3.14 */
- int AutoManagedVariableResourceNotBelow9 = Syntax + Internal + 1351;
- /**
- * External problems -- These are problems defined by other plugins
- */
-
- /** @since 3.2 */
- int ExternalProblemNotFixable = 900;
-
- // indicates an externally defined problem that has a quick-assist processor
- // associated with it
- /** @since 3.2 */
- int ExternalProblemFixable = 901;
-
- /** @since 3.10 */
- int ContainerAnnotationTypeHasWrongValueType = TypeRelated + 902;
- /** @since 3.10 */
- int ContainerAnnotationTypeMustHaveValue = TypeRelated + 903;
- /** @since 3.10 */
- int ContainerAnnotationTypeHasNonDefaultMembers = TypeRelated + 904;
- /** @since 3.10 */
- int ContainerAnnotationTypeHasShorterRetention = TypeRelated + 905;
- /** @since 3.10 */
- int RepeatableAnnotationTypeTargetMismatch = TypeRelated + 906;
- /** @since 3.10 */
- int RepeatableAnnotationTypeIsDocumented = TypeRelated + 907;
- /** @since 3.10 */
- int RepeatableAnnotationTypeIsInherited = TypeRelated + 908;
- /** @since 3.10 */
- int RepeatableAnnotationWithRepeatingContainerAnnotation = TypeRelated + 909;
-
- /**
- * Errors/warnings from annotation based null analysis
- */
- /** @since 3.8 */
- int RequiredNonNullButProvidedNull = TypeRelated + 910;
- /** @since 3.8 */
- int RequiredNonNullButProvidedPotentialNull = TypeRelated + 911;
- /** @since 3.8 */
- int RequiredNonNullButProvidedUnknown = TypeRelated + 912;
- /** @since 3.8 */
- int MissingNonNullByDefaultAnnotationOnPackage = Internal + 913; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=372012
- /** @since 3.8 */
- int IllegalReturnNullityRedefinition = MethodRelated + 914;
- /** @since 3.8 */
- int IllegalRedefinitionToNonNullParameter = MethodRelated + 915;
- /** @since 3.8 */
- int IllegalDefinitionToNonNullParameter = MethodRelated + 916;
- /** @since 3.8 */
- int ParameterLackingNonNullAnnotation = MethodRelated + 917;
- /** @since 3.8 */
- int ParameterLackingNullableAnnotation = MethodRelated + 918;
- /** @since 3.8 */
- int PotentialNullMessageSendReference = Internal + 919;
- /** @since 3.8 */
- int RedundantNullCheckOnNonNullMessageSend = Internal + 920;
- /** @since 3.8 */
- int CannotImplementIncompatibleNullness = Internal + 921;
- /** @since 3.8 */
- int RedundantNullAnnotation = MethodRelated + 922;
- /** @since 3.8 */
- int IllegalAnnotationForBaseType = TypeRelated + 923;
- /** @since 3.9 */
- int NullableFieldReference = FieldRelated + 924;
- /** @since 3.8 */
- int RedundantNullDefaultAnnotation = Internal + 925; // shouldn't actually occur any more after bug 366063
- /** @since 3.8 */
- int RedundantNullDefaultAnnotationPackage = Internal + 926;
- /** @since 3.8 */
- int RedundantNullDefaultAnnotationType = Internal + 927;
- /** @since 3.8 */
- int RedundantNullDefaultAnnotationMethod = Internal + 928;
- /** @since 3.8 */
- int ContradictoryNullAnnotations = Internal + 929;
- /** @since 3.8 */
- int MissingNonNullByDefaultAnnotationOnType = Internal + 930; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=372012
- /** @since 3.8 */
- int RedundantNullCheckOnSpecdNonNullLocalVariable = Internal + 931;
- /** @since 3.8 */
- int SpecdNonNullLocalVariableComparisonYieldsFalse = Internal + 932;
- /** @since 3.8 */
- int RequiredNonNullButProvidedSpecdNullable = Internal + 933;
- /** @since 3.9 */
- int UninitializedNonNullField = FieldRelated + 934;
- /** @since 3.9 */
- int UninitializedNonNullFieldHintMissingDefault = FieldRelated + 935;
- /** @since 3.9 */
- int NonNullMessageSendComparisonYieldsFalse = Internal + 936;
- /** @since 3.9 */
- int RedundantNullCheckOnNonNullSpecdField = Internal + 937;
- /** @since 3.9 */
- int NonNullSpecdFieldComparisonYieldsFalse = Internal + 938;
- /** @since 3.9 */
- int ConflictingNullAnnotations = MethodRelated + 939;
- /** @since 3.9 */
- int ConflictingInheritedNullAnnotations = MethodRelated + 940;
- /** @since 3.10 */
- int RedundantNullCheckOnField = Internal + 941;
- /** @since 3.10 */
- int FieldComparisonYieldsFalse = Internal + 942;
- /** @since 3.14 */
- int RedundantNullDefaultAnnotationModule = Internal + 943;
- /** @since 3.19 */
- int RedundantNullCheckOnConstNonNullField = Internal + 944;
- /** @since 3.20 */
- int ConstNonNullFieldComparisonYieldsFalse = Internal + 945;
- /** @since 3.21 */
- int InheritedParameterLackingNonNullAnnotation = MethodRelated + 946;
-
- /** @since 3.10 */
- int ArrayReferencePotentialNullReference = Internal + 951;
- /** @since 3.10 */
- int DereferencingNullableExpression = Internal + 952;
- /** @since 3.10 */
- int NullityMismatchingTypeAnnotation = Internal + 953;
- /** @since 3.10 */
- int NullityMismatchingTypeAnnotationSuperHint = Internal + 954;
- /** @since 3.10 */
- int NullityUncheckedTypeAnnotationDetail = Internal + 955; // see also NullityUncheckedTypeAnnotation
- /** @since 3.10 */
- int NullityUncheckedTypeAnnotationDetailSuperHint = Internal + 956;
- /** @since 3.10 */
- int ReferenceExpressionParameterNullityMismatch = MethodRelated + 957;
- /** @since 3.10 */
- int ReferenceExpressionParameterNullityUnchecked = MethodRelated + 958;
- /** @since 3.10 */
- int ReferenceExpressionReturnNullRedef = MethodRelated + 959;
- /** @since 3.10 */
- int ReferenceExpressionReturnNullRedefUnchecked = MethodRelated + 960;
- /** @since 3.10 */
- int RedundantNullCheckAgainstNonNullType = Internal + 961;
- /** @since 3.10 */
- int NullAnnotationUnsupportedLocation = Internal + 962;
- /** @since 3.10 */
- int NullAnnotationUnsupportedLocationAtType = Internal + 963;
- /** @since 3.10 */
- int NullityMismatchTypeArgument = Internal + 964;
- /** @since 3.10 */
- int ContradictoryNullAnnotationsOnBound = Internal + 965;
- /** @since 3.10 */
- int ContradictoryNullAnnotationsInferred = Internal + 966;
- /** @since 3.10 */
- int UnsafeNullnessCast = Internal + 967;
- /** @since 3.10 */
- int NonNullDefaultDetailIsNotEvaluated = 968; // no longer reported
- /** @since 3.10 */
- int NullNotCompatibleToFreeTypeVariable = 969;
- /** @since 3.10 */
- int NullityMismatchAgainstFreeTypeVariable = 970;
- /** @since 3.11 */
- int ImplicitObjectBoundNoNullDefault = 971;
- /** @since 3.11 */
- int IllegalParameterNullityRedefinition = MethodRelated + 972;
- /** @since 3.11 */
- int ContradictoryNullAnnotationsInferredFunctionType = MethodRelated + 973;
- /** @since 3.11 */
- int IllegalReturnNullityRedefinitionFreeTypeVariable = MethodRelated + 974;
- /** @since 3.12 */
- int IllegalRedefinitionOfTypeVariable = 975;
- /** @since 3.12 */
- int UncheckedAccessOfValueOfFreeTypeVariable = 976;
- /** @since 3.12 */
- int UninitializedFreeTypeVariableField = 977;
- /** @since 3.12 */
- int UninitializedFreeTypeVariableFieldHintMissingDefault = 978;
- /** @since 3.12 */
- int RequiredNonNullButProvidedFreeTypeVariable = TypeRelated + 979;
- /** @since 3.12 */
- int NonNullTypeVariableFromLegacyMethod = TypeRelated + 980;
- /** @since 3.12 */
- int NonNullMethodTypeVariableFromLegacyMethod = TypeRelated + 981;
- /** @since 3.21 */
- int MissingNullAnnotationImplicitlyUsed = Internal + 982;
- /** @since 3.21 */
- int AnnotatedTypeArgumentToUnannotated = Internal + 983;
- /** @since 3.21 */
- int AnnotatedTypeArgumentToUnannotatedSuperHint = Internal + 984;
- /** @since 3.32 */
- int NonNullArrayContentNotInitialized = Internal + 985;
- /**
- * Both {@link #NullityUncheckedTypeAnnotationDetail} and {@link #NullityUncheckedTypeAnnotation}
- * signal that unchecked conversion is needed to pass a value between annotated and un-annotated code.
- * In the case of {@link #NullityUncheckedTypeAnnotationDetail} the mismatch was observed only on some
- * detail of the types involved (type arguments or array components), for which the UI does not (yet)
- * offer a quick fix, whereas {@link #NullityUncheckedTypeAnnotation} affects the toplevel type and thus
- * can be easily fixed by adding the appropriate null annotation.
- *
- * @since 3.36
- */
- int NullityUncheckedTypeAnnotation = Internal + 986;
-
-
- // Java 8 work
- /** @since 3.10 */
- int IllegalModifiersForElidedType = Internal + 1001;
- /** @since 3.10 */
- int IllegalModifiers = Internal + 1002;
-
- /** @since 3.10 */
- int IllegalTypeArgumentsInRawConstructorReference = TypeRelated + 1003;
-
- // more on lambdas:
- /** @since 3.18 */
- int MissingValueFromLambda = Internal + 1004;
-
- // default methods:
- /** @since 3.10 */
- int IllegalModifierForInterfaceMethod18 = MethodRelated + 1050;
-
- /** @since 3.10 */
- int DefaultMethodOverridesObjectMethod = MethodRelated + 1051;
-
- /** @since 3.10 */
- int InheritedDefaultMethodConflictsWithOtherInherited = MethodRelated + 1052;
-
- /** @since 3.10 */
- int DuplicateInheritedDefaultMethods = MethodRelated + 1053;
-
- /** @since 3.10 */
- int SuperAccessCannotBypassDirectSuper = TypeRelated + 1054;
- /** @since 3.10 */
- int SuperCallCannotBypassOverride = MethodRelated + 1055;
- /** @since 3.10 */
- int IllegalModifierCombinationForInterfaceMethod = MethodRelated + 1056;
- /** @since 3.10 */
- int IllegalStrictfpForAbstractInterfaceMethod = MethodRelated + 1057;
- /** @since 3.10 */
- int IllegalDefaultModifierSpecification = MethodRelated + 1058;
- /** @since 3.13 */
- int CannotInferInvocationType = TypeRelated + 1059;
-
-
- /** @since 3.13 */
- int TypeAnnotationAtQualifiedName = Internal + Syntax + 1060;
-
- /** @since 3.13 */
- int NullAnnotationAtQualifyingType = Internal + Syntax + 1061;
-
- /** @since 3.14*/
- int IllegalModifierForInterfaceMethod9 = MethodRelated + 1071;
- /** @since 3.14*/
- int IllegalModifierCombinationForPrivateInterfaceMethod9 = MethodRelated + 1070;
- /** @since 3.14 */
- int UndefinedModule = ModuleRelated + 1300;
- /** @since 3.14 */
- int DuplicateRequires = ModuleRelated + 1301;
- /** @since 3.14 */
- int DuplicateExports = ModuleRelated + 1302;
- /** @since 3.14 */
- int DuplicateUses = ModuleRelated + 1303;
- /** @since 3.14 */
- int DuplicateServices = ModuleRelated + 1304;
- /** @since 3.14 */
- int CyclicModuleDependency = ModuleRelated + 1305;
- /** @since 3.14 */
- int AbstractServiceImplementation = TypeRelated + 1306;
- /** @since 3.14 */
- int ProviderMethodOrConstructorRequiredForServiceImpl = TypeRelated + 1307;
- /** @since 3.14 */
- int ServiceImplDefaultConstructorNotPublic = TypeRelated + 1308;
- /** @since 3.14 */
- int NestedServiceImpl = TypeRelated + 1309;
- /** @since 3.14 */
- int ServiceImplNotDefinedByModule = TypeRelated + 1310;
- /** @since 3.14 */
- int PackageDoesNotExistOrIsEmpty = ModuleRelated + 1311;
- /** @since 3.14 */
- int NonDenotableTypeArgumentForAnonymousDiamond = TypeRelated + 1312;
- /** @since 3.14 */
- int DuplicateOpens = ModuleRelated + 1313;
- /** @since 3.14 */
- int DuplicateModuleRef = ModuleRelated + 1314;
- /** @since 3.14 */
- int InvalidOpensStatement = ModuleRelated + 1315;
- /** @since 3.14 */
- int InvalidServiceIntfType = ModuleRelated + 1316;
- /** @since 3.14 */
- int InvalidServiceImplType = ModuleRelated + 1317;
- /** @since 3.14 */
- int IllegalModifierForModule = ModuleRelated + 1318;
- /** @since 3.18 */
- int UndefinedModuleAddReads = ModuleRelated + 1319;
- /** @since 3.20 */
- int ExportingForeignPackage = ModuleRelated + 1320;
-
-
- /** @since 3.14 */
- int DuplicateResource = Internal + 1251;
-
- /** @since 3.37 */
- int ShouldMarkMethodAsOwning = Internal + 1260;
- /** @since 3.37 */
- int MandatoryCloseNotShown = Internal + 1261;
- /** @since 3.37 */
- int MandatoryCloseNotShownAtExit = Internal + 1262;
- /** @since 3.37 */
- int NotOwningResourceField = Internal + 1263;
- /** @since 3.37 */
- int OwningFieldInNonResourceClass = Internal + 1264;
- /** @since 3.37 */
- int OwningFieldShouldImplementClose = Internal + 1265;
- /** @since 3.37 */
- int OverrideReducingParamterOwning = Internal + 1266;
- /** @since 3.37 */
- int OverrideAddingReturnOwning = Internal + 1267;
-
- // terminally
- /** @since 3.14 */
- int UsingTerminallyDeprecatedType = TypeRelated + 1400;
- /** @since 3.14 */
- int UsingTerminallyDeprecatedMethod = MethodRelated + 1401;
- /** @since 3.14 */
- int UsingTerminallyDeprecatedConstructor = MethodRelated + 1402;
- /** @since 3.14 */
- int UsingTerminallyDeprecatedField = FieldRelated + 1403;
- /** @since 3.14 */
- int OverridingTerminallyDeprecatedMethod = MethodRelated + 1404;
- // with since
- /** @since 3.14 */
- int UsingDeprecatedSinceVersionType = TypeRelated + 1405;
- /** @since 3.14 */
- int UsingDeprecatedSinceVersionMethod = MethodRelated + 1406;
- /** @since 3.14 */
- int UsingDeprecatedSinceVersionConstructor = MethodRelated + 1407;
- /** @since 3.14 */
- int UsingDeprecatedSinceVersionField = FieldRelated + 1408;
- /** @since 3.14 */
- int OverridingDeprecatedSinceVersionMethod = MethodRelated + 1409;
- // terminally with since
- /** @since 3.14 */
- int UsingTerminallyDeprecatedSinceVersionType = TypeRelated + 1410;
- /** @since 3.14 */
- int UsingTerminallyDeprecatedSinceVersionMethod = MethodRelated + 1411;
- /** @since 3.14 */
- int UsingTerminallyDeprecatedSinceVersionConstructor = MethodRelated + 1412;
- /** @since 3.14 */
- int UsingTerminallyDeprecatedSinceVersionField = FieldRelated + 1413;
- /** @since 3.14 */
- int OverridingTerminallyDeprecatedSinceVersionMethod = MethodRelated + 1414;
-
- // unused constants:
- /** @since 3.14 */
- int UsingDeprecatedPackage = ModuleRelated + 1425;
- /** @since 3.14 */
- int UsingDeprecatedSinceVersionPackage = ModuleRelated + 1426;
- /** @since 3.14 */
- int UsingTerminallyDeprecatedPackage = ModuleRelated + 1427;
- /** @since 3.14 */
- int UsingTerminallyDeprecatedSinceVersionPackage = ModuleRelated + 1428;
- // deprecation of modules:
- /** @since 3.14 */
- int UsingDeprecatedModule = ModuleRelated + 1429;
- /** @since 3.14 */
- int UsingDeprecatedSinceVersionModule = ModuleRelated + 1430;
- /** @since 3.14 */
- int UsingTerminallyDeprecatedModule = ModuleRelated + 1431;
- /** @since 3.14 */
- int UsingTerminallyDeprecatedSinceVersionModule = ModuleRelated + 1432;
-
- /** @since 3.14 */
- int NotAccessibleType = TypeRelated + 1450;
- /** @since 3.14 */
- int NotAccessibleField = FieldRelated + 1451;
- /** @since 3.14 */
- int NotAccessibleMethod = MethodRelated + 1452;
- /** @since 3.14 */
- int NotAccessibleConstructor = MethodRelated + 1453;
- /** @since 3.14 */
- int NotAccessiblePackage = ImportRelated + 1454;
- /** @since 3.14 */
- int ConflictingPackageFromModules = ModuleRelated + 1455;
- /** @since 3.14 */
- int ConflictingPackageFromOtherModules = ModuleRelated + 1456;
- /** @since 3.14 */
- int NonPublicTypeInAPI = ModuleRelated + 1457;
- /** @since 3.14 */
- int NotExportedTypeInAPI = ModuleRelated + 1458;
- /** @since 3.14 */
- int MissingRequiresTransitiveForTypeInAPI = ModuleRelated + 1459;
- /** @since 3.14 */
- int UnnamedPackageInNamedModule = ModuleRelated + 1460;
- /** @since 3.14 */
- int UnstableAutoModuleName = ModuleRelated + 1461;
- /** @since 3.24 */
- int ConflictingPackageInModules = ModuleRelated + 1462;
-
- // doc variant of an above constant:
- /** @since 3.22 */
- int JavadocNotAccessibleType = Javadoc + NotAccessibleType;
-
- /** @since 3.13 */
- int RedundantNullDefaultAnnotationLocal = Internal + 1062;
-
- /** @since 3.13 */
- int RedundantNullDefaultAnnotationField = Internal + 1063;
-
- /** @since 3.10 */
- int GenericInferenceError = 1100; // FIXME: This is just a stop-gap measure, be more specific via https://bugs.eclipse.org/404675
-
- /** @deprecated - problem is no longer generated (implementation issue has been resolved)
- * @since 3.10 */
- int LambdaShapeComputationError = 1101;
- /** @since 3.13 */
- int ProblemNotAnalysed = 1102;
- /** @since 3.18 */
- int PreviewFeatureDisabled = Compliance + 1103;
- /** @since 3.18 */
- int PreviewFeatureUsed = Compliance + 1104;
- /** @since 3.18 */
- int PreviewFeatureNotSupported = Compliance + 1105;
- /** @since 3.20*/
- int PreviewFeaturesNotAllowed = PreviewRelated + 1106;
- /** @since 3.24*/
- int FeatureNotSupported = Compliance + 1107;
- /** @since 3.26*/
- int PreviewAPIUsed = Compliance + 1108;
-
- /** @since 3.13 */
- int UnlikelyCollectionMethodArgumentType = 1200;
- /** @since 3.13 */
- int UnlikelyEqualsArgumentType = 1201;
-
- /* Local-Variable Type Inference */
- /** @since 3.14 */
- int VarLocalMultipleDeclarators = Syntax + 1500; // ''var'' is not allowed in a compound declaration
- /** @since 3.14 */
- int VarLocalCannotBeArray = Syntax + 1501; // ''var'' is not allowed as an element type of an array
- /** @since 3.14 */
- int VarLocalReferencesItself = Syntax + 1502; // Declaration using ''var'' may not contin references to itself
- /** @since 3.14 */
- int VarLocalWithoutInitizalier = Syntax + 1503; // Cannot use ''var'' on variable without initializer
- /** @since 3.14 */
- int VarLocalInitializedToNull = TypeRelated + 1504; // Variable initialized to ''null'' needs an explicit target-type
- /** @since 3.14 */
- int VarLocalInitializedToVoid = TypeRelated + 1505; // Variable initializer is ''void'' -- cannot infer variable type
- /** @since 3.14 */
- int VarLocalCannotBeArrayInitalizers = TypeRelated + 1506; // Array initializer needs an explicit target-type
- /** @since 3.14 */
- int VarLocalCannotBeLambda = TypeRelated + 1507; // Lambda expression needs an explicit target-type
- /** @since 3.14 */
- int VarLocalCannotBeMethodReference = TypeRelated + 1508; // Method reference needs an explicit target-type
- /** @since 3.14 */
- int VarIsReserved = Syntax + 1509; // ''var'' is not a valid type name
- /** @since 3.14 */
- int VarIsReservedInFuture = Syntax + 1510; // ''var'' should not be used as an type name, since it is a reserved word from source level 10 on
- /** @since 3.14 */
- int VarIsNotAllowedHere = Syntax + 1511; // ''var'' is not allowed here
- /** @since 3.16 */
- int VarCannotBeMixedWithNonVarParams = Syntax + 1512; // ''var'' cannot be mixed with explicit or implicit parameters
- /** @since 3.35 */
- int VarCannotBeUsedWithTypeArguments = Syntax + 1513; // ''var'' cannot be used with type arguments (e.g. as in ''var x = List.of(42)'')
-
- /** @since 3.18
- * @deprecated preview related error - will be removed
- * @noreference preview related error */
- int SwitchExpressionsIncompatibleResultExpressionTypes = TypeRelated + 1600;
- /** @since 3.18
- * @deprecated preview related error - will be removed
- * @noreference preview related error */
- int SwitchExpressionsEmptySwitchBlock = Internal + 1601;
- /** @since 3.18
- * @deprecated preview related error - will be removed
- * @noreference preview related error */
- int SwitchExpressionsNoResultExpression = TypeRelated + 1602;
- /** @since 3.18
- * @deprecated preview related error - will be removed
- * @noreference preview related error */
- int SwitchExpressionSwitchLabeledBlockCompletesNormally = Internal + 1603;
- /** @since 3.18
- * @deprecated preview related error - will be removed
- * @noreference preview related error */
- int SwitchExpressionLastStatementCompletesNormally = Internal + 1604;
- /** @since 3.18
- * @deprecated preview related error - will be removed
- * @noreference preview related error */
- int SwitchExpressionTrailingSwitchLabels = Internal + 1605;
- /** @since 3.18
- * @deprecated preview related error - will be removed
- * @noreference preview related error */
- int switchMixedCase = Syntax + 1606;
- /** @since 3.18
- * @deprecated preview related error - will be removed
- * @noreference preview related error */
- int SwitchExpressionMissingDefaultCase = Internal + 1607;
- /** @since 3.18
- * @deprecated preview related error - will be removed
- * @noreference preview related error */
- int SwitchExpressionBreakMissingValue = Internal + 1610;
- /** @since 3.18
- * @deprecated preview related error - will be removed
- * @noreference preview related error */
- int SwitchExpressionMissingEnumConstantCase = Internal + 1611;
- /** @since 3.18
- * @deprecated preview related error - will be removed
- * @noreference preview related error */
- int SwitchExpressionIllegalLastStatement = Internal + 1612;
-
- /* Java14 errors - begin */
- /** @since 3.21 */
- int SwitchExpressionsYieldIncompatibleResultExpressionTypes = TypeRelated + 1700;
- /** @since 3.21 */
- int SwitchExpressionsYieldEmptySwitchBlock = Syntax + 1701;
- /** @since 3.21 */
- int SwitchExpressionsYieldNoResultExpression = Internal + 1702;
- /** @since 3.21 */
- int SwitchExpressionaYieldSwitchLabeledBlockCompletesNormally = Internal + 1703;
- /** @since 3.21 */
- int SwitchExpressionsYieldLastStatementCompletesNormally = Internal + 1704;
- /** @since 3.21 */
- int SwitchExpressionsYieldTrailingSwitchLabels = Internal + 1705;
- /** @since 3.21 */
- int SwitchPreviewMixedCase = Syntax + 1706;
- /** @since 3.21 */
- int SwitchExpressionsYieldMissingDefaultCase = Syntax + 1707;
- /** @since 3.21 */
- int SwitchExpressionsYieldMissingValue = Syntax + 1708;
- /** @since 3.21 */
- int SwitchExpressionsYieldMissingEnumConstantCase = Syntax + 1709;
- /** @since 3.21 */
- int SwitchExpressionsYieldIllegalLastStatement = Internal + 1710;
- /** @since 3.21 */
- int SwitchExpressionsYieldBreakNotAllowed = Syntax + 1711;
- /** @since 3.21 */
- int SwitchExpressionsYieldUnqualifiedMethodWarning = Syntax + 1712;
- /** @since 3.21 */
- int SwitchExpressionsYieldUnqualifiedMethodError = Syntax + 1713;
- /** @since 3.21 */
- int SwitchExpressionsYieldOutsideSwitchExpression = Syntax + 1714;
- /** @since 3.21 */
- int SwitchExpressionsYieldRestrictedGeneralWarning = Internal + 1715;
- /** @since 3.21 */
- int SwitchExpressionsYieldIllegalStatement = Internal + 1716;
- /** @since 3.21 */
- int SwitchExpressionsYieldTypeDeclarationWarning = Internal + 1717;
- /** @since 3.21 */
- int SwitchExpressionsYieldTypeDeclarationError = Internal + 1718;
- /** @since 3.22 */
- int MultiConstantCaseLabelsNotSupported = Syntax + 1719;
- /** @since 3.22*/
- int ArrowInCaseStatementsNotSupported = Syntax + 1720;
- /** @since 3.22 */
- int SwitchExpressionsNotSupported = Syntax + 1721;
- /** @since 3.22 */
- int SwitchExpressionsBreakOutOfSwitchExpression = Syntax + 1722;
- /** @since 3.22 */
- int SwitchExpressionsContinueOutOfSwitchExpression = Syntax + 1723;
- /** @since 3.22 */
- int SwitchExpressionsReturnWithinSwitchExpression = Syntax + 1724;
-
- /* Java 14 errors end */
- /* Java 15 errors begin */
- /* records - begin */
-
- /** @since 3.26 */
- int RecordIllegalModifierForInnerRecord = TypeRelated + 1730;
- /** @since 3.26 */
- int RecordIllegalModifierForRecord = TypeRelated + 1731;
- /** @since 3.26
- * JLS 14 Sec 8.10.1
- * it is always a compile-time error for a record header to declare a record component with the name
- * finalize, getClass, hashCode, notify, notifyAll, or toString. */
- int RecordIllegalComponentNameInRecord = TypeRelated + 1732;
- /** @since 3.26
- */
- int RecordNonStaticFieldDeclarationInRecord = TypeRelated + 1733;
- /** @since 3.26
- */
- int RecordAccessorMethodHasThrowsClause = TypeRelated + 1734;
- /** @since 3.26
- */
- int RecordCanonicalConstructorHasThrowsClause = TypeRelated + 1735;
- /** @since 3.26
- */
- int RecordCanonicalConstructorVisibilityReduced = TypeRelated + 1736;
- /** @since 3.26
- */
- int RecordMultipleCanonicalConstructors = TypeRelated + 1737;
- /** @since 3.26
- */
- int RecordCompactConstructorHasReturnStatement = TypeRelated + 1738;
- /** @since 3.26
- */
- int RecordDuplicateComponent = TypeRelated + 1739;
- /** @since 3.26
- */
- int RecordIllegalNativeModifierInRecord = TypeRelated + 1740;
- /** @since 3.26
- */
- int RecordInstanceInitializerBlockInRecord = TypeRelated + 1741;
- /** @since 3.26
- */
- int RestrictedTypeName = TypeRelated + 1742;
- /** @since 3.26
- */
- int RecordIllegalAccessorReturnType = TypeRelated + 1743;
- /** @since 3.26
- */
- int RecordAccessorMethodShouldNotBeGeneric = TypeRelated + 1744;
- /** @since 3.26
- */
- int RecordAccessorMethodShouldBePublic = TypeRelated + 1745;
- /** @since 3.26
- */
- int RecordCanonicalConstructorShouldNotBeGeneric = TypeRelated + 1746;
- /** @since 3.26
- */
- int RecordCanonicalConstructorHasReturnStatement = TypeRelated + 1747;
- /** @since 3.26
- */
- int RecordCanonicalConstructorHasExplicitConstructorCall = TypeRelated + 1748;
- /** @since 3.26
- */
- int RecordCompactConstructorHasExplicitConstructorCall = TypeRelated + 1749;
- /** @since 3.26
- */
- int RecordNestedRecordInherentlyStatic = TypeRelated + 1750;
- /** @since 3.26
- */
- int RecordAccessorMethodShouldNotBeStatic= TypeRelated + 1751;
- /** @since 3.26
- */
- int RecordCannotExtendRecord= TypeRelated + 1752;
- /** @since 3.26
- */
- int RecordComponentCannotBeVoid= TypeRelated + 1753;
- /** @since 3.26
- */
- int RecordIllegalVararg= TypeRelated + 1754;
- /** @since 3.26
- */
- int RecordStaticReferenceToOuterLocalVariable= TypeRelated + 1755;
- /** @since 3.26
- */
- int RecordCannotDefineRecordInLocalType= TypeRelated + 1756;
- /** @since 3.26
- */
- int RecordComponentsCannotHaveModifiers= TypeRelated + 1757;
- /** @since 3.26
- */
- int RecordIllegalParameterNameInCanonicalConstructor = TypeRelated + 1758;
- /** @since 3.26
- */
- int RecordIllegalExplicitFinalFieldAssignInCompactConstructor = TypeRelated + 1759;
- /** @since 3.26
- */
- int RecordMissingExplicitConstructorCallInNonCanonicalConstructor= TypeRelated + 1760;
- /** @since 3.26
- */
- int RecordIllegalStaticModifierForLocalClassOrInterface = TypeRelated + 1761;
- /** @since 3.26
- */
- int RecordIllegalModifierForLocalRecord = TypeRelated + 1762;
- /** @since 3.26
- */
- int RecordIllegalExtendedDimensionsForRecordComponent = Syntax + Internal + 1763;
- /** @since 3.26
- */
- int SafeVarargsOnSyntheticRecordAccessor = TypeRelated + 1764;
-
-
- /* records - end */
- /* Local and Nested Static Declarations - Begin */
- /** @since 3.28 */
- int LocalStaticsIllegalVisibilityModifierForInterfaceLocalType = TypeRelated + 1765;
- /** @since 3.28 */
- int IllegalModifierForLocalEnumDeclaration = TypeRelated + 1766;
- /** @since 3.28 */
- int ClassExtendFinalRecord = TypeRelated + 1767;
- /** @since 3.29 */
- int RecordErasureIncompatibilityInCanonicalConstructor = TypeRelated + 1768;
- /* records - end */
-
-
- /* instanceof pattern: */
- /** @since 3.22
- * @deprecated problem no longer generated */
- int PatternVariableNotInScope = PreviewRelated + 1780;
- /** @since 3.26
- */
- int PatternVariableRedefined = Internal + 1781;
- /** @since 3.26
- * @deprecated
- */
- int PatternSubtypeOfExpression = Internal + 1782;
- /** @since 3.26
- */
- int IllegalModifierForPatternVariable = Internal + 1783;
- /** @since 3.26
- */
- int PatternVariableRedeclared = Internal + 1784;
-
- /** @since 3.28
- */
- int DiscouragedValueBasedTypeSynchronization = Internal + 1820;
-
- /** @since 3.28 */
- int SealedMissingClassModifier = TypeRelated + 1850;
- /** @since 3.28 */
- int SealedDisAllowedNonSealedModifierInClass = TypeRelated + 1851;
- /** @since 3.28 */
- int SealedSuperClassDoesNotPermit = TypeRelated + 1852;
- /** @since 3.28 */
- int SealedSuperInterfaceDoesNotPermit = TypeRelated + 1853;
- /** @since 3.28 */
- int SealedMissingSealedModifier = TypeRelated + 1854;
- /** @since 3.28 */
- int SealedMissingInterfaceModifier = TypeRelated + 1855;
- /** @since 3.28 */
- int SealedDuplicateTypeInPermits = TypeRelated + 1856;
- /** @since 3.28 */
- int SealedNotDirectSuperClass = TypeRelated + 1857;
- /** @since 3.28 */
- int SealedPermittedTypeOutsideOfModule = TypeRelated + 1858;
- /** @since 3.28 */
- int SealedPermittedTypeOutsideOfPackage = TypeRelated + 1859;
- /** @since 3.28 */
- int SealedSealedTypeMissingPermits = TypeRelated + 1860;
- /** @since 3.28 */
- int SealedInterfaceIsSealedAndNonSealed = TypeRelated + 1861;
- /** @since 3.28 */
- int SealedDisAllowedNonSealedModifierInInterface = TypeRelated + 1862;
- /** @since 3.28 */
- int SealedNotDirectSuperInterface = TypeRelated + 1863;
- /** @since 3.28 */
- int SealedLocalDirectSuperTypeSealed = TypeRelated + 1864;
- /** @since 3.28 */
- int SealedAnonymousClassCannotExtendSealedType = TypeRelated + 1865;
- /** @since 3.28 */
- int SealedSuperTypeInDifferentPackage = TypeRelated + 1866;
- /** @since 3.28 */
- int SealedSuperTypeDisallowed = TypeRelated + 1867;
- /* Java15 errors - end */
-
- /**
- * @since 3.28
- * @noreference preview feature error
- */
- int LocalReferencedInGuardMustBeEffectivelyFinal = PreviewRelated + 1900;
- /** @since 3.28
- * @noreference preview feature error */
- int ConstantWithPatternIncompatible = PreviewRelated + 1901;
- /**
- * @since 3.28
- * @noreference preview feature error
- */
- int IllegalFallthroughToPattern = PreviewRelated + 1902;
-
- /** @since 3.28
- * @noreference preview feature error */
- int PatternDominated = PreviewRelated + 1906;
- /** @since 3.28
- * @noreference preview feature error */
- int IllegalTotalPatternWithDefault = PreviewRelated + 1907;
- /** @since 3.28
- * @noreference preview feature error */
- int EnhancedSwitchMissingDefault = PreviewRelated + 1908;
- /** @since 3.28
- * @noreference preview feature error */
- int DuplicateTotalPattern = PreviewRelated + 1909;
-
- /** @since 3.34
- * @noreference preview feature error */
- int PatternSwitchNullOnlyOrFirstWithDefault = PreviewRelated + 1920;
-
- /** @since 3.34
- * @noreference preview feature error */
- int PatternSwitchCaseDefaultOnlyAsSecond = PreviewRelated + 1921;
-
- /**
- * @since 3.34
- * @noreference preview feature error
- */
- int IllegalFallthroughFromAPattern = PreviewRelated + 1922;
-
- /** @since 3.28
- * @noreference preview feature error */
- int UnnecessaryNullCaseInSwitchOverNonNull = PreviewRelated + 1910;
- /** @since 3.28
- * @noreference preview feature error */
- int UnexpectedTypeinSwitchPattern = PreviewRelated + 1911;
- /**
- * @since 3.32
- * @noreference preview feature
- */
- int UnexpectedTypeinRecordPattern = PreviewRelated + 1912;
- /**
- * @since 3.32
- * @noreference preview feature
- */
- int RecordPatternMismatch = PreviewRelated + 1913;
- /**
- * @since 3.32
- * @noreference preview feature
- */
- int PatternTypeMismatch = PreviewRelated + 1914;
- /**
- * @since 3.32
- * @noreference preview feature
- * @deprecated
- */
- int RawTypeInRecordPattern = PreviewRelated + 1915;
- /**
- * @since 3.36
- * @noreference preview feature
- */
- int FalseConstantInGuard = PreviewRelated + 1916;
- /**
- * @since 3.34
- * @noreference preview feature
- */
- int CannotInferRecordPatternTypes = PreviewRelated + 1940;
-
- /**
- * @since 3.36
- */
- int IllegalRecordPattern = TypeRelated + 1941;
-
-
- /**
- * @since 3.35
- */
- int SyntheticAccessorNotEnclosingMethod = MethodRelated + 1990;
-
- /**
- * @since 3.37
- * @noreference preview feature
- */
- int UnderscoreCannotBeUsedHere = PreviewRelated + 2000;
- /**
- * @since 3.37
- * @noreference preview feature
- */
- int UnnamedVariableMustHaveInitializer = PreviewRelated + 2001;
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/InvalidInputException.java b/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/InvalidInputException.java
deleted file mode 100644
index 5887161..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/InvalidInputException.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.jdt.core.compiler;
-
-/**
- * Exception thrown by a scanner when encountering lexical errors.
- *
- * @noinstantiate This class is not intended to be instantiated by clients.
- * @noextend This class is not intended to be subclassed by clients.
- */
-public class InvalidInputException extends Exception {
-
- private static final long serialVersionUID = 2909732853499731592L; // backward compatible
-
-/**
- * Creates a new exception with no detail message.
- */
-public InvalidInputException() {
- super();
-}
-
-/**
- * Creates a new exception with the given detail message.
- * @param message the detail message
- */
-public InvalidInputException(String message) {
- super(message);
-}
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/SubwordMatcher.java b/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/SubwordMatcher.java
deleted file mode 100644
index 9886aef..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/SubwordMatcher.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2020 Julian Honnen.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Julian Honnen - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.core.compiler;
-
-import java.util.Arrays;
-import java.util.BitSet;
-
-import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
-
-class SubwordMatcher {
-
- private static final int[] EMPTY_REGIONS = new int[0];
-
- private final char[] name;
- private final BitSet wordBoundaries;
-
- public SubwordMatcher(String name) {
- this.name = name.toCharArray();
- this.wordBoundaries = new BitSet(name.length());
-
- for (int i = 0; i < this.name.length; i++) {
- if (isWordBoundary(caseAt(i - 1), caseAt(i), caseAt(i + 1))) {
- this.wordBoundaries.set(i);
- }
- }
- }
-
- private Case caseAt(int index) {
- if (index < 0 || index >= this.name.length)
- return Case.SEPARATOR;
-
- char c = this.name[index];
- if (c == '_')
- return Case.SEPARATOR;
- if (ScannerHelper.isUpperCase(c))
- return Case.UPPER;
- return Case.LOWER;
- }
-
- private static boolean isWordBoundary(Case p, Case c, Case n) {
- if (p == c && c == n)
- return false; // a boundary needs some kind of gradient
-
- if (p == Case.SEPARATOR)
- return true; // boundary after every separator
-
- // the remaining cases are boundaries for capitalization changes:
- // lowerUpper, UPPERLower, lowerUPPER
- // ^ ^ ^
- return (c == Case.UPPER) && (p == Case.LOWER || n == Case.LOWER);
- }
-
- private enum Case {
- SEPARATOR, LOWER, UPPER
- }
-
- public int[] getMatchingRegions(String pattern) {
- int segmentStart = 0;
- int[] segments = EMPTY_REGIONS;
-
- // Main loop is on pattern characters
- int iName = -1;
- int iPatternWordStart = 0;
- for (int iPattern = 0; iPattern < pattern.length(); iPattern++) {
- iName++;
- if (iName == this.name.length) {
- // We have exhausted the name (and not the pattern), so it's not a match
- return null;
- }
-
- char patternChar = pattern.charAt(iPattern);
- char nameChar = this.name[iName];
-
- // For as long as we're exactly matching, bring it on
- if (patternChar == nameChar) {
- continue;
- }
- if (!isWordBoundary(iName) && equalsIgnoreCase(patternChar, nameChar)) {
- // we're not at a word boundary, case-insensitive match is fine
- continue;
- }
-
- // not matching, record previous segment and find next word match in name
- if (iName > segmentStart) {
- segments = Arrays.copyOf(segments, segments.length + 2);
- segments[segments.length - 2] = segmentStart;
- segments[segments.length - 1] = iName - segmentStart;
- }
-
- int wordStart = indexOfWordStart(iName, patternChar);
- if (wordStart < 0) {
- // no matching word found, backtrack and try to find next occurrence of current word
- int next = indexOfWordStart(iName, pattern.charAt(iPatternWordStart));
- if (next > 0) {
- wordStart = next;
- iPattern = iPatternWordStart;
- // last recorded segment was invalid -> drop it
- segments = Arrays.copyOfRange(segments, 0, segments.length - 2);
- }
- }
-
- if (wordStart < 0) {
- // We have exhausted name (and not pattern), so it's not a match
- return null;
- }
-
- segmentStart = wordStart;
- iName = wordStart;
- iPatternWordStart = iPattern;
- }
-
- // we have exhausted pattern, record final segment
- segments = Arrays.copyOf(segments, segments.length + 2);
- segments[segments.length - 2] = segmentStart;
- segments[segments.length - 1] = iName - segmentStart + 1;
-
- return segments;
- }
-
- /**
- * Returns the index of the first word after nameStart, beginning with patternChar. Returns -1 if no matching word
- * is found.
- */
- private int indexOfWordStart(int nameStart, char patternChar) {
-
- for (int iName = nameStart; iName < this.name.length; iName++) {
- char nameChar = this.name[iName];
- if (isWordBoundary(iName) && equalsIgnoreCase(nameChar, patternChar)) {
- return iName;
- }
-
- // don't match across identifiers (e.g. "index" should not match "substring(int beginIndex)")
- if (!ScannerHelper.isJavaIdentifierPart(nameChar)) {
- return -1;
- }
- }
-
- // We have exhausted name
- return -1;
- }
-
- private boolean equalsIgnoreCase(char a, char b) {
- return ScannerHelper.toLowerCase(a) == ScannerHelper.toLowerCase(b);
- }
-
- private boolean isWordBoundary(int iName) {
- return this.wordBoundaries.get(iName);
- }
-}
\ No newline at end of file
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/batch/BatchCompiler.java b/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/batch/BatchCompiler.java
deleted file mode 100644
index 7e4ca11..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/batch/BatchCompiler.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2019 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.core.compiler.batch;
-
-import java.io.PrintWriter;
-
-import org.eclipse.jdt.core.compiler.CompilationProgress;
-import org.eclipse.jdt.internal.compiler.batch.Main;
-
-/**
- * A public API for invoking the Eclipse Compiler for Java. E.g.
- *
- * BatchCompiler.compile("C:\\mySources\\X.java -d C:\\myOutput", new PrintWriter(System.out), new PrintWriter(System.err), null);
- *
- *
- * @since 3.4
- * @noinstantiate This class is not intended to be instantiated by clients.
- */
-public final class BatchCompiler {
-
- /**
- * Invokes the Eclipse Compiler for Java with the given command line arguments, using the given writers
- * to print messages, and reporting progress to the given compilation progress. Returns whether
- * the compilation completed successfully.
- *
- * Reasons for a compilation failing to complete successfully include:
- *
- * an error was reported
- * a runtime exception occurred
- * the compilation was canceled using the compilation progress
- *
- *
- * The specification of the command line arguments is defined by running the batch compiler's help
- *
BatchCompiler.compile("-help", new PrintWriter(System.out), new PrintWriter(System.err), null);
- *
- * @param commandLine the command line arguments passed to the compiler
- * @param outWriter the writer used to print standard messages
- * @param errWriter the writer used to print error messages
- * @param progress the object to report progress to and to provide cancellation, or null if no progress is needed
- * @return whether the compilation completed successfully
- */
- public static boolean compile(String commandLine, PrintWriter outWriter, PrintWriter errWriter, CompilationProgress progress) {
- return compile(Main.tokenize(commandLine), outWriter, errWriter, progress);
- }
-
- /**
- * Invokes the Eclipse Compiler for Java with the given command line arguments, using the given writers
- * to print messages, and reporting progress to the given compilation progress. Returns whether
- * the compilation completed successfully.
- *
- * Reasons for a compilation failing to complete successfully include:
- *
- * an error was reported
- * a runtime exception occurred
- * the compilation was canceled using the compilation progress
- *
- *
- * The specification of the command line arguments is defined by running the batch compiler's help
- *
BatchCompiler.compile("-help", new PrintWriter(System.out), new PrintWriter(System.err), null);
- *
- * Note that a true returned value indicates that no errors were reported, no runtime exceptions
- * occurred and that the compilation was not canceled.
- *
- * @param commandLineArguments the command line arguments passed to the compiler
- * @param outWriter the writer used to print standard messages
- * @param errWriter the writer used to print error messages
- * @param progress the object to report progress to and to provide cancellation, or null if no progress is needed
- * @return whether the compilation completed successfully
- */
- public static boolean compile(String[] commandLineArguments, PrintWriter outWriter, PrintWriter errWriter, CompilationProgress progress) {
- return Main.compile(commandLineArguments, outWriter, errWriter, progress);
- }
-
- private BatchCompiler() {
- // prevent instantiation
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/batch/package.html b/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/batch/package.html
deleted file mode 100644
index cf3bc8a..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/batch/package.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
- Package-level Javadoc
-
-
-This package contains the batch compiler API.
-
-Package Specification
-
- This package contains the batch compiler API.
-
-
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/package.html b/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/package.html
deleted file mode 100644
index b039ea2..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/core/compiler/package.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
- Package-level Javadoc
-
-
-This package contains compiler associated infrastructure APIs.
-
-Package Specification
-
- This package contains some compiler tooling APIs, allowing to perform operations at a lower-level
-than using the JavaModel.
-
-
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ASTVisitor.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ASTVisitor.java
deleted file mode 100644
index 65f9d36..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ASTVisitor.java
+++ /dev/null
@@ -1,1022 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2023 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler;
-
-import org.eclipse.jdt.core.compiler.IProblem;
-import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
-import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
-
-/**
- * A visitor for iterating through the parse tree.
- */
-public abstract class ASTVisitor {
- public void acceptProblem(IProblem problem) {
- // do nothing by default
- }
- public void endVisit(
- AllocationExpression allocationExpression,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(AND_AND_Expression and_and_Expression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- AnnotationMethodDeclaration annotationTypeDeclaration,
- ClassScope classScope) {
- // do nothing by default
- }
- public void endVisit(TypePattern anyPattern, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(Argument argument, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(Argument argument,ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(
- ArrayAllocationExpression arrayAllocationExpression,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ArrayInitializer arrayInitializer, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ArrayInitializer arrayInitializer, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(
- ArrayQualifiedTypeReference arrayQualifiedTypeReference,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- ArrayQualifiedTypeReference arrayQualifiedTypeReference,
- ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(ArrayReference arrayReference, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ArrayTypeReference arrayTypeReference, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ArrayTypeReference arrayTypeReference, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(AssertStatement assertStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(Assignment assignment, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(BinaryExpression binaryExpression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(Block block, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(BreakStatement breakStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(CaseStatement caseStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(CastExpression castExpression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(CharLiteral charLiteral, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ClassLiteralAccess classLiteral, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(Clinit clinit, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(CompactConstructorDeclaration ccd, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(
- CompilationUnitDeclaration compilationUnitDeclaration,
- CompilationUnitScope scope) {
- // do nothing by default
- }
- public void endVisit(CompoundAssignment compoundAssignment, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- ConditionalExpression conditionalExpression,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- ConstructorDeclaration constructorDeclaration,
- ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(ContinueStatement continueStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(DoStatement doStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(DoubleLiteral doubleLiteral, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(EmptyStatement emptyStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(EqualExpression equalExpression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- ExplicitConstructorCall explicitConstructor,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- ExtendedStringLiteral extendedStringLiteral,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(FakeDefaultLiteral fakeDefaultLiteral, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(FalseLiteral falseLiteral, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(FieldDeclaration fieldDeclaration, MethodScope scope) {
- // do nothing by default
- }
- public void endVisit(FieldReference fieldReference, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(FieldReference fieldReference, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(FloatLiteral floatLiteral, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ForeachStatement forStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ForStatement forStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(GuardedPattern guardedPattern, BlockScope scope) {
- // do nothing by default, keep traversing
- }
- public void endVisit(IfStatement ifStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ImportReference importRef, CompilationUnitScope scope) {
- // do nothing by default
- }
- public void endVisit(Initializer initializer, MethodScope scope) {
- // do nothing by default
- }
- public void endVisit(
- InstanceOfExpression instanceOfExpression,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(IntLiteral intLiteral, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(Javadoc javadoc, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(Javadoc javadoc, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocAllocationExpression expression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocAllocationExpression expression, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocArgumentExpression expression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocArgumentExpression expression, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocArrayQualifiedTypeReference typeRef, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocArrayQualifiedTypeReference typeRef, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocArraySingleTypeReference typeRef, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocArraySingleTypeReference typeRef, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocFieldReference fieldRef, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocFieldReference fieldRef, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocImplicitTypeReference implicitTypeReference, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocImplicitTypeReference implicitTypeReference, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocMessageSend messageSend, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocMessageSend messageSend, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocQualifiedTypeReference typeRef, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocQualifiedTypeReference typeRef, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocModuleReference moduleRef, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocModuleReference moduleRef, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocReturnStatement statement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocReturnStatement statement, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocSingleNameReference argument, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocSingleNameReference argument, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocSingleTypeReference typeRef, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(JavadocSingleTypeReference typeRef, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(LabeledStatement labeledStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(LocalDeclaration localDeclaration, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(LongLiteral longLiteral, BlockScope scope) {
- // do nothing by default
- }
- /**
- * @since 3.1
- */
- public void endVisit(MarkerAnnotation annotation, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(MarkerAnnotation annotation, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(MemberValuePair pair, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(MemberValuePair pair, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(MessageSend messageSend, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(StringLiteralConcatenation literal, BlockScope scope) {
- // do nothing by default
- }
- /**
- * @since 3.1
- */
- public void endVisit(NormalAnnotation annotation, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(NormalAnnotation annotation, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(NullLiteral nullLiteral, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(OR_OR_Expression or_or_Expression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(Pattern patternExpression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(PostfixExpression postfixExpression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(PrefixExpression prefixExpression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- QualifiedAllocationExpression qualifiedAllocationExpression,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- QualifiedNameReference qualifiedNameReference,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- QualifiedNameReference qualifiedNameReference,
- ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(
- QualifiedSuperReference qualifiedSuperReference,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- QualifiedSuperReference qualifiedSuperReference,
- ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(
- QualifiedThisReference qualifiedThisReference,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- QualifiedThisReference qualifiedThisReference,
- ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(
- QualifiedTypeReference qualifiedTypeReference,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- QualifiedTypeReference qualifiedTypeReference,
- ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(RecordPattern recordPattern, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ReturnStatement returnStatement, BlockScope scope) {
- // do nothing by default
- }
- /**
- * @since 3.1
- */
- public void endVisit(SingleMemberAnnotation annotation, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(SingleMemberAnnotation annotation, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(
- SingleNameReference singleNameReference,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- SingleNameReference singleNameReference,
- ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(
- SingleTypeReference singleTypeReference,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- SingleTypeReference singleTypeReference,
- ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(StringLiteral stringLiteral, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(SuperReference superReference, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(SwitchStatement switchStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- SynchronizedStatement synchronizedStatement,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ThisReference thisReference, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(ThisReference thisReference, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(ThrowStatement throwStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(TrueLiteral trueLiteral, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(TryStatement tryStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- TypeDeclaration localTypeDeclaration,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- TypeDeclaration memberTypeDeclaration,
- ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(
- TypeDeclaration typeDeclaration,
- CompilationUnitScope scope) {
- // do nothing by default
- }
- public void endVisit(TypeParameter typeParameter, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(TypeParameter typeParameter, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(UnaryExpression unaryExpression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- UnionTypeReference unionTypeReference,
- BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(
- UnionTypeReference unionTypeReference,
- ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(YieldStatement yieldStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(WhileStatement whileStatement, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(Wildcard wildcard, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(Wildcard wildcard, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(LambdaExpression lambdaExpression, BlockScope blockScope) {
- // do nothing by default
- }
- public void endVisit(ReferenceExpression referenceExpression, BlockScope blockScope) {
- // do nothing by default
- }
- public void endVisit(IntersectionCastTypeReference intersectionCastTypeReference, ClassScope scope) {
- // do nothing by default
- }
- public void endVisit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(SwitchExpression switchExpression, BlockScope scope) {
- // do nothing by default
- }
- public void endVisit(RecordComponent recordComponent, BlockScope scope) {
- // do nothing by default, keep traversing
- }
- public boolean visit(RecordPattern recordPattern, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- AllocationExpression allocationExpression,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(AND_AND_Expression and_and_Expression, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- AnnotationMethodDeclaration annotationTypeDeclaration,
- ClassScope classScope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(TypePattern anyPattern, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(Argument argument, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(Argument argument, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- ArrayAllocationExpression arrayAllocationExpression,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ArrayInitializer arrayInitializer, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ArrayInitializer arrayInitializer, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- ArrayQualifiedTypeReference arrayQualifiedTypeReference,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- ArrayQualifiedTypeReference arrayQualifiedTypeReference,
- ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ArrayReference arrayReference, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ArrayTypeReference arrayTypeReference, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ArrayTypeReference arrayTypeReference, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(AssertStatement assertStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(Assignment assignment, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(BinaryExpression binaryExpression, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(Block block, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(BreakStatement breakStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(CaseStatement caseStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(CastExpression castExpression, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(CharLiteral charLiteral, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ClassLiteralAccess classLiteral, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(Clinit clinit, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ModuleDeclaration module, CompilationUnitScope scope) {
- return true;
- }
- public boolean visit(CompactConstructorDeclaration ccd, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- CompilationUnitDeclaration compilationUnitDeclaration,
- CompilationUnitScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(CompoundAssignment compoundAssignment, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- ConditionalExpression conditionalExpression,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- ConstructorDeclaration constructorDeclaration,
- ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ContinueStatement continueStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(DoStatement doStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(DoubleLiteral doubleLiteral, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(EmptyStatement emptyStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(EqualExpression equalExpression, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- ExplicitConstructorCall explicitConstructor,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- ExtendedStringLiteral extendedStringLiteral,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(FakeDefaultLiteral fakeDefaultLiteral, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(FalseLiteral falseLiteral, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(FieldReference fieldReference, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(FieldReference fieldReference, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(FloatLiteral floatLiteral, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ForeachStatement forStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ForStatement forStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(GuardedPattern guardedPattern, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(IfStatement ifStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ImportReference importRef, CompilationUnitScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(Initializer initializer, MethodScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- InstanceOfExpression instanceOfExpression,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(IntLiteral intLiteral, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(Javadoc javadoc, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(Javadoc javadoc, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocAllocationExpression expression, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocAllocationExpression expression, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocArgumentExpression expression, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocArgumentExpression expression, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocArrayQualifiedTypeReference typeRef, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocArrayQualifiedTypeReference typeRef, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocArraySingleTypeReference typeRef, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocArraySingleTypeReference typeRef, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocFieldReference fieldRef, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocFieldReference fieldRef, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocImplicitTypeReference implicitTypeReference, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocImplicitTypeReference implicitTypeReference, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocMessageSend messageSend, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocMessageSend messageSend, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocQualifiedTypeReference typeRef, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocQualifiedTypeReference typeRef, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocModuleReference moduleRef, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocModuleReference moduleRef, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocReturnStatement statement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocReturnStatement statement, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocSingleNameReference argument, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocSingleNameReference argument, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocSingleTypeReference typeRef, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(JavadocSingleTypeReference typeRef, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(LabeledStatement labeledStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(LongLiteral longLiteral, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- /**
- * @since 3.1
- */
- public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
- return true;
- }
- public boolean visit(MarkerAnnotation annotation, ClassScope scope) {
- return true;
- }
- /**
- * @since 3.1
- */
- public boolean visit(MemberValuePair pair, BlockScope scope) {
- return true;
- }
- public boolean visit(MemberValuePair pair, ClassScope scope) {
- return true;
- }
- public boolean visit(MessageSend messageSend, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- StringLiteralConcatenation literal,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- /**
- * @since 3.1
- */
- public boolean visit(NormalAnnotation annotation, BlockScope scope) {
- return true;
- }
- public boolean visit(NormalAnnotation annotation, ClassScope scope) {
- return true;
- }
- public boolean visit(NullLiteral nullLiteral, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(OR_OR_Expression or_or_Expression, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(Pattern patternExpression, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(PostfixExpression postfixExpression, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(PrefixExpression prefixExpression, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- QualifiedAllocationExpression qualifiedAllocationExpression,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- QualifiedNameReference qualifiedNameReference,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- QualifiedNameReference qualifiedNameReference,
- ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- QualifiedSuperReference qualifiedSuperReference,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- QualifiedSuperReference qualifiedSuperReference,
- ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- QualifiedThisReference qualifiedThisReference,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- QualifiedThisReference qualifiedThisReference,
- ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- QualifiedTypeReference qualifiedTypeReference,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- QualifiedTypeReference qualifiedTypeReference,
- ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ReturnStatement returnStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- /**
- * @since 3.1
- */
- public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
- return true;
- }
- public boolean visit(SingleMemberAnnotation annotation, ClassScope scope) {
- return true;
- }
- public boolean visit(
- SingleNameReference singleNameReference,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- SingleNameReference singleNameReference,
- ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- SingleTypeReference singleTypeReference,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- SingleTypeReference singleTypeReference,
- ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(StringLiteral stringLiteral, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(SuperReference superReference, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(SwitchStatement switchStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- SynchronizedStatement synchronizedStatement,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ThisReference thisReference, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ThisReference thisReference, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ThrowStatement throwStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(TrueLiteral trueLiteral, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(TryStatement tryStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- TypeDeclaration localTypeDeclaration,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- TypeDeclaration memberTypeDeclaration,
- ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- TypeDeclaration typeDeclaration,
- CompilationUnitScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(TypeParameter typeParameter, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(TypeParameter typeParameter, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(UnaryExpression unaryExpression, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- UnionTypeReference unionTypeReference,
- BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(
- UnionTypeReference unionTypeReference,
- ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(YieldStatement yieldStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(WhileStatement whileStatement, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(Wildcard wildcard, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(Wildcard wildcard, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(LambdaExpression lambdaExpression, BlockScope blockScope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(ReferenceExpression referenceExpression, BlockScope blockScope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(IntersectionCastTypeReference intersectionCastTypeReference, ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(SwitchExpression switchExpression, BlockScope blockScope) {
- return true; // do nothing by default, keep traversing
- }
- public boolean visit(RecordComponent recordComponent, BlockScope scope) {
- return true; // do nothing by default, keep traversing
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/AbstractAnnotationProcessorManager.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/AbstractAnnotationProcessorManager.java
deleted file mode 100644
index 5eecab8..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/AbstractAnnotationProcessorManager.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2018 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * BEA - Patch for bug 172743
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler;
-
-import java.io.PrintWriter;
-
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-
-public abstract class AbstractAnnotationProcessorManager {
- /**
- * Configure the receiver using the given batch compiler and the given options.
- * The parameter batchCompiler is expected to be an instance of the batch compiler. This method is
- * only used for the batch mode. For the IDE mode, please see {@link #configureFromPlatform(Compiler, Object, Object, boolean)}.
- *
- * @param batchCompiler the given batch compiler object
- * @param options the given options
- */
- public abstract void configure(Object batchCompiler, String[] options);
-
- /**
- * Configure the receiver using the given compiler, the given compilationUnitLocator and
- * the given java project.
- *
- * @param compiler the given compiler
- * @param compilationUnitLocator the given compilation unit locator
- * @param javaProject the given java project
- */
- public abstract void configureFromPlatform(Compiler compiler, Object compilationUnitLocator, Object javaProject, boolean isTestCode);
-
- /**
- * Set the print writer for the standard output.
- *
- * @param out the given print writer for output
- */
- public abstract void setOut(PrintWriter out);
-
- /**
- * Set the print writer for the standard error.
- *
- * @param err the given print writer for error
- */
- public abstract void setErr(PrintWriter err);
-
- /**
- * Return the new units created in the last round.
- *
- * @return the new units created in the last round
- */
- public abstract ICompilationUnit[] getNewUnits();
-
- /**
- * Return the new binary bindings created in the last round.
- *
- * @return the new binary bindings created in the last round
- */
- public abstract ReferenceBinding[] getNewClassFiles();
-
- /**
- * Returns the deleted units.
- * @return the deleted units
- */
- public abstract ICompilationUnit[] getDeletedUnits();
-
- /**
- * Reinitialize the receiver
- */
- public abstract void reset();
-
- /**
- * Final cleanup after all rounds have completed.
- */
- protected void cleanUp() {
- // default: do nothing, because reset() already did the common work
- }
-
- /**
- * Run a new annotation processing round on the given values.
- *
- * @param units the given source type
- * @param referenceBindings the given binary types
- * @param isLastRound flag to notify the last round
- */
- public abstract void processAnnotations(CompilationUnitDeclaration[] units, ReferenceBinding[] referenceBindings, boolean isLastRound);
-
- /**
- * Set the processors for annotation processing.
- *
- * @param processors the given processors
- */
- public abstract void setProcessors(Object[] processors);
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ClassFile.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ClassFile.java
deleted file mode 100644
index 5d7b9d3..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ /dev/null
@@ -1,7962 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2023 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * Jesper S Moller - Contributions for
- * Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
- * Bug 406982 - [1.8][compiler] Generation of MethodParameters Attribute in classfile
- * Bug 416885 - [1.8][compiler]IncompatibleClassChange error (edit)
- * Bug 412149 - [1.8][compiler] Emit repeated annotations into the designated container
- * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
- * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
- * Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
- * Bug 409246 - [1.8][compiler] Type annotations on catch parameters not handled properly
- * Bug 415541 - [1.8][compiler] Type annotations in the body of static initializer get dropped
- * Bug 415399 - [1.8][compiler] Type annotations on constructor results dropped by the code generator
- * Bug 415470 - [1.8][compiler] Type annotations on class declaration go vanishing
- * Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
- * Bug 434556 - Broken class file generated for incorrect annotation usage
- * Bug 442416 - $deserializeLambda$ missing cases for nested lambdas
- * Stephan Herrmann - Contribution for
- * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
- * Olivier Tardieu tardieu@us.ibm.com - Contributions for
- * Bug 442416 - $deserializeLambda$ missing cases for nested lambdas
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-import org.eclipse.jdt.core.compiler.CategorizedProblem;
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.core.compiler.IProblem;
-import org.eclipse.jdt.internal.compiler.ast.ASTNode;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Annotation;
-import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
-import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
-import org.eclipse.jdt.internal.compiler.ast.CaseStatement.ResolvedCase;
-import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.ExportsStatement;
-import org.eclipse.jdt.internal.compiler.ast.Expression;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.FunctionalExpression;
-import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
-import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
-import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
-import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
-import org.eclipse.jdt.internal.compiler.ast.OpensStatement;
-import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
-import org.eclipse.jdt.internal.compiler.ast.Receiver;
-import org.eclipse.jdt.internal.compiler.ast.RecordComponent;
-import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
-import org.eclipse.jdt.internal.compiler.ast.RequiresStatement;
-import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
-import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
-import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
-import org.eclipse.jdt.internal.compiler.ast.StringTemplate;
-import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
-import org.eclipse.jdt.internal.compiler.ast.TypeReference;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.codegen.AnnotationContext;
-import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
-import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
-import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
-import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
-import org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel;
-import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
-import org.eclipse.jdt.internal.compiler.codegen.StackMapFrame;
-import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream;
-import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.ExceptionMarker;
-import org.eclipse.jdt.internal.compiler.codegen.TypeAnnotationCodeStream;
-import org.eclipse.jdt.internal.compiler.codegen.VerificationTypeInfo;
-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.compiler.impl.Constant;
-import org.eclipse.jdt.internal.compiler.impl.StringConstant;
-import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
-import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.PolymorphicMethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
-import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.RecordComponentBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Scope;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TagBits;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
-import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
-import org.eclipse.jdt.internal.compiler.problem.AbortType;
-import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
-import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
-import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement;
-import org.eclipse.jdt.internal.compiler.util.Messages;
-import org.eclipse.jdt.internal.compiler.util.Util;
-
-/**
- * Represents a class file wrapper on bytes, it is aware of its actual
- * type name.
- *
- * Public APIs are listed below:
- *
- * byte[] getBytes();
- * Answer the actual bytes of the class file
- *
- * char[][] getCompoundName();
- * Answer the compound name of the class file.
- * For example, {{java}, {util}, {Hashtable}}.
- *
- * byte[] getReducedBytes();
- * Answer a smaller byte format, which is only contains some structural
- * information. Those bytes are decodable with a regular class file reader,
- * such as DietClassFileReader
- */
-public class ClassFile implements TypeConstants, TypeIds {
-
- private byte[] bytes;
- public CodeStream codeStream;
- public ConstantPool constantPool;
-
- public int constantPoolOffset;
-
- // the header contains all the bytes till the end of the constant pool
- public byte[] contents;
-
- public int contentsOffset;
-
- protected boolean creatingProblemType;
-
- public ClassFile enclosingClassFile;
- public byte[] header;
- // that collection contains all the remaining bytes of the .class file
- public int headerOffset;
- public Map innerClassesBindings;
- public Set nestMembers;
- public List bootstrapMethods = null;
- public int methodCount;
- public int methodCountOffset;
- // pool managment
- boolean isShared = false;
- // used to generate private access methods
- // debug and stack map attributes
- public int produceAttributes;
- public SourceTypeBinding referenceBinding;
- public boolean isNestedType;
- public long targetJDK;
-
- public List missingTypes = null;
-
- public Set visitedTypes;
-
- public static final int INITIAL_CONTENTS_SIZE = 400;
- public static final int INITIAL_HEADER_SIZE = 1500;
- public static final int INNER_CLASSES_SIZE = 5;
- public static final int NESTED_MEMBER_SIZE = 5;
-
- // TODO: Move these to an enum?
- public static final String ALTMETAFACTORY_STRING = new String(ConstantPool.ALTMETAFACTORY);
- public static final String METAFACTORY_STRING = new String(ConstantPool.METAFACTORY);
- public static final String BOOTSTRAP_STRING = new String(ConstantPool.BOOTSTRAP);
- public static final String TYPESWITCH_STRING = new String(ConstantPool.TYPESWITCH);
- public static final String ENUMSWITCH_STRING = new String(ConstantPool.ENUMSWITCH);
- public static final String CONCAT_CONSTANTS = new String(ConstantPool.ConcatWithConstants);
- public static final String INVOKE_STRING = new String(ConstantPool.INVOKE_METHOD_METHOD_NAME);
- public static final String ENUMDESC_OF = "EnumDesc.of"; //$NON-NLS-1$
- public static final String CLASSDESC = "ClassDesc"; //$NON-NLS-1$
- public static final String CLASSDESC_OF = "ClassDesc.of"; //$NON-NLS-1$
- public static final String PROCESS_STRING = "process"; //$NON-NLS-1$
- public static final String NEW_STRING_TEMPLATE = "newStringTemplate"; //$NON-NLS-1$
- public static final String[] BOOTSTRAP_METHODS = { ALTMETAFACTORY_STRING, METAFACTORY_STRING, BOOTSTRAP_STRING,
- TYPESWITCH_STRING, ENUMSWITCH_STRING, CONCAT_CONSTANTS, INVOKE_STRING, ENUMDESC_OF, CLASSDESC, CLASSDESC_OF, PROCESS_STRING, NEW_STRING_TEMPLATE};
- /**
- * INTERNAL USE-ONLY
- * Request the creation of a ClassFile compatible representation of a problematic type
- *
- * @param typeDeclaration org.eclipse.jdt.internal.compiler.ast.TypeDeclaration
- * @param unitResult org.eclipse.jdt.internal.compiler.CompilationUnitResult
- */
- public static void createProblemType(TypeDeclaration typeDeclaration, CompilationResult unitResult) {
- createProblemType(typeDeclaration, null, unitResult);
- }
-
- private static void createProblemType(TypeDeclaration typeDeclaration, ClassFile parentClassFile, CompilationResult unitResult) {
- SourceTypeBinding typeBinding = typeDeclaration.binding;
- ClassFile classFile = ClassFile.getNewInstance(typeBinding);
- classFile.initialize(typeBinding, parentClassFile, true);
-
- if (typeBinding.hasMemberTypes()) {
- // see bug 180109
- ReferenceBinding[] members = typeBinding.memberTypes;
- for (int i = 0, l = members.length; i < l; i++)
- classFile.recordInnerClasses(members[i]);
- }
- // TODO (olivier) handle cases where a field cannot be generated (name too long)
- // TODO (olivier) handle too many methods
- // inner attributes
- if (typeBinding.isNestedType()) {
- classFile.recordInnerClasses(typeBinding);
- }
- TypeVariableBinding[] typeVariables = typeBinding.typeVariables();
- for (int i = 0, max = typeVariables.length; i < max; i++) {
- TypeVariableBinding typeVariableBinding = typeVariables[i];
- if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
- Util.recordNestedType(classFile, typeVariableBinding);
- }
- }
- // add its fields
- FieldBinding[] fields = typeBinding.fields();
- if ((fields != null) && (fields != Binding.NO_FIELDS)) {
- classFile.addFieldInfos();
- } else {
- // we have to set the number of fields to be equals to 0
- if (classFile.contentsOffset + 2 >= classFile.contents.length) {
- classFile.resizeContents(2);
- }
- classFile.contents[classFile.contentsOffset++] = 0;
- classFile.contents[classFile.contentsOffset++] = 0;
- }
- // leave some space for the methodCount
- classFile.setForMethodInfos();
- // add its user defined methods
- int problemsLength;
- CategorizedProblem[] problems = unitResult.getErrors();
- if (problems == null) {
- problems = new CategorizedProblem[0];
- }
- CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
- System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
-
- AbstractMethodDeclaration[] methodDecls = typeDeclaration.methods;
- boolean abstractMethodsOnly = false;
- if (methodDecls != null) {
- if (typeBinding.isInterface()) {
- if (typeBinding.scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8)
- abstractMethodsOnly = true;
- // We generate a clinit which contains all the problems, since we may not be able to generate problem methods (< 1.8) and problem constructors (all levels).
- classFile.addProblemClinit(problemsCopy);
- }
- for (int i = 0, length = methodDecls.length; i < length; i++) {
- AbstractMethodDeclaration methodDecl = methodDecls[i];
- MethodBinding method = methodDecl.binding;
- if (method == null) continue;
- if (abstractMethodsOnly) {
- method.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract;
- }
- if (method.isConstructor()) {
- if (typeBinding.isInterface()) continue;
- classFile.addProblemConstructor(methodDecl, method, problemsCopy);
- } else if (method.isAbstract()) {
- classFile.addAbstractMethod(methodDecl, method);
- } else {
- classFile.addProblemMethod(methodDecl, method, problemsCopy);
- }
- }
- // add abstract methods
- classFile.addDefaultAbstractMethods();
- }
-
- // propagate generation of (problem) member types
- if (typeDeclaration.memberTypes != null) {
- for (int i = 0, max = typeDeclaration.memberTypes.length; i < max; i++) {
- TypeDeclaration memberType = typeDeclaration.memberTypes[i];
- if (memberType.binding != null) {
- ClassFile.createProblemType(memberType, classFile, unitResult);
- }
- }
- }
- classFile.addAttributes();
- unitResult.record(typeBinding.constantPoolName(), classFile);
- }
- public static ClassFile getNewInstance(SourceTypeBinding typeBinding) {
- LookupEnvironment env = typeBinding.scope.environment();
- return env.classFilePool.acquire(typeBinding);
- }
- /**
- * INTERNAL USE-ONLY
- * This methods creates a new instance of the receiver.
- */
- protected ClassFile() {
- // default constructor for subclasses
- }
-
- public ClassFile(SourceTypeBinding typeBinding) {
- // default constructor for subclasses
- this.constantPool = new ConstantPool(this);
- final CompilerOptions options = typeBinding.scope.compilerOptions();
- this.targetJDK = options.targetJDK;
- this.produceAttributes = options.produceDebugAttributes;
- this.referenceBinding = typeBinding;
- this.isNestedType = typeBinding.isNestedType();
- if (this.targetJDK >= ClassFileConstants.JDK1_6) {
- this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
- if (this.targetJDK >= ClassFileConstants.JDK1_8) {
- this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
- this.codeStream = new TypeAnnotationCodeStream(this);
- if (options.produceMethodParameters) {
- this.produceAttributes |= ClassFileConstants.ATTR_METHOD_PARAMETERS;
- }
- } else {
- this.codeStream = new StackMapFrameCodeStream(this);
- }
- } else if (this.targetJDK == ClassFileConstants.CLDC_1_1) {
- this.targetJDK = ClassFileConstants.JDK1_1; // put back 45.3
- this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP;
- this.codeStream = new StackMapFrameCodeStream(this);
- } else {
- this.codeStream = new CodeStream(this);
- }
- initByteArrays(this.referenceBinding.methods().length + this.referenceBinding.fields().length);
- }
-
- public ClassFile(ModuleBinding moduleBinding, CompilerOptions options) {
- this.constantPool = new ConstantPool(this);
- this.targetJDK = options.targetJDK;
- this.produceAttributes = ClassFileConstants.ATTR_SOURCE;
- this.isNestedType = false;
- this.codeStream = new StackMapFrameCodeStream(this);
- initByteArrays(0);
- }
-
- /**
- * INTERNAL USE-ONLY
- * Generate the byte for a problem method info that correspond to a bogus method.
- *
- * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
- * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
- */
- public void addAbstractMethod(
- AbstractMethodDeclaration method,
- MethodBinding methodBinding) {
-
- this.generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- int attributeNumber = this.generateMethodInfoAttributes(methodBinding);
- completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
- }
-
- /**
- * INTERNAL USE-ONLY
- * This methods generate all the attributes for the receiver.
- * For a class they could be:
- * - source file attribute
- * - inner classes attribute
- * - deprecated attribute
- */
- public void addAttributes() {
- // update the method count
- this.contents[this.methodCountOffset++] = (byte) (this.methodCount >> 8);
- this.contents[this.methodCountOffset] = (byte) this.methodCount;
-
- int attributesNumber = 0;
- // leave two bytes for the number of attributes and store the current offset
- int attributeOffset = this.contentsOffset;
- this.contentsOffset += 2;
-
- // source attribute
- if ((this.produceAttributes & ClassFileConstants.ATTR_SOURCE) != 0) {
- String fullFileName =
- new String(this.referenceBinding.scope.referenceCompilationUnit().getFileName());
- fullFileName = fullFileName.replace('\\', '/');
- int lastIndex = fullFileName.lastIndexOf('/');
- if (lastIndex != -1) {
- fullFileName = fullFileName.substring(lastIndex + 1, fullFileName.length());
- }
- attributesNumber += generateSourceAttribute(fullFileName);
- }
- // Deprecated attribute
- if (this.referenceBinding.isDeprecated()) {
- // check that there is enough space to write all the bytes for the field info corresponding
- // to the @fieldBinding
- attributesNumber += generateDeprecatedAttribute();
- }
- // add signature attribute
- char[] genericSignature = this.referenceBinding.genericSignature();
- if (genericSignature != null) {
- attributesNumber += generateSignatureAttribute(genericSignature);
- }
- if (this.targetJDK >= ClassFileConstants.JDK1_5
- && this.referenceBinding.isNestedType()
- && !this.referenceBinding.isMemberType()) {
- // add enclosing method attribute (1.5 mode only)
- attributesNumber += generateEnclosingMethodAttribute();
- }
- if (this.targetJDK >= ClassFileConstants.JDK1_4) {
- TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
- if (typeDeclaration != null) {
- final Annotation[] annotations = typeDeclaration.annotations;
- if (annotations != null) {
- long targetMask;
- if (typeDeclaration.isPackageInfo())
- targetMask = TagBits.AnnotationForPackage;
- else if (this.referenceBinding.isAnnotationType())
- targetMask = TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType;
- else
- targetMask = TagBits.AnnotationForType | TagBits.AnnotationForTypeUse; // 9.7.4 ... applicable to type declarations or in type contexts
- attributesNumber += generateRuntimeAnnotations(annotations, targetMask);
- }
- }
- }
-
- if (this.referenceBinding.isHierarchyInconsistent()) {
- ReferenceBinding superclass = this.referenceBinding.superclass;
- if (superclass != null) {
- this.missingTypes = superclass.collectMissingTypes(this.missingTypes);
- }
- ReferenceBinding[] superInterfaces = this.referenceBinding.superInterfaces();
- for (int i = 0, max = superInterfaces.length; i < max; i++) {
- this.missingTypes = superInterfaces[i].collectMissingTypes(this.missingTypes);
- }
- attributesNumber += generateHierarchyInconsistentAttribute();
- }
- // Functional expression, lambda bootstrap methods and record bootstrap methods
- if (this.bootstrapMethods != null && !this.bootstrapMethods.isEmpty()) {
- attributesNumber += generateBootstrapMethods(this.bootstrapMethods);
- }
- if (this.targetJDK >= ClassFileConstants.JDK17) {
- // add record attributes
- attributesNumber += generatePermittedTypeAttributes();
- }
- // Inner class attribute
- int numberOfInnerClasses = this.innerClassesBindings == null ? 0 : this.innerClassesBindings.size();
- if (numberOfInnerClasses != 0) {
- ReferenceBinding[] innerClasses = new ReferenceBinding[numberOfInnerClasses];
- this.innerClassesBindings.keySet().toArray(innerClasses);
- Arrays.sort(innerClasses, new Comparator() {
- @Override
- public int compare(ReferenceBinding o1, ReferenceBinding o2) {
- Boolean onBottom1 = ClassFile.this.innerClassesBindings.get(o1);
- Boolean onBottom2 = ClassFile.this.innerClassesBindings.get(o2);
- if (onBottom1) {
- if (!onBottom2) {
- return 1;
- }
- } else {
- if (onBottom2) {
- return -1;
- }
- }
- return CharOperation.compareTo(o1.constantPoolName(), o2.constantPoolName());
- }
- });
- attributesNumber += generateInnerClassAttribute(numberOfInnerClasses, innerClasses);
- }
- if (this.missingTypes != null) {
- generateMissingTypesAttribute();
- attributesNumber++;
- }
-
- attributesNumber += generateTypeAnnotationAttributeForTypeDeclaration();
-
- if (this.targetJDK >= ClassFileConstants.JDK11) {
- // add nestMember and nestHost attributes
- attributesNumber += generateNestAttributes();
- }
- if (this.targetJDK >= ClassFileConstants.JDK14) {
- // add record attributes
- attributesNumber += generateRecordAttributes();
- }
- // update the number of attributes
- if (attributeOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- this.contents[attributeOffset++] = (byte) (attributesNumber >> 8);
- this.contents[attributeOffset] = (byte) attributesNumber;
-
- // resynchronize all offsets of the classfile
- this.header = this.constantPool.poolContent;
- this.headerOffset = this.constantPool.currentOffset;
- int constantPoolCount = this.constantPool.currentIndex;
- this.header[this.constantPoolOffset++] = (byte) (constantPoolCount >> 8);
- this.header[this.constantPoolOffset] = (byte) constantPoolCount;
- }
-
- /**
- * INTERNAL USE-ONLY
- * This methods generate all the module attributes for the receiver.
- */
- public void addModuleAttributes(ModuleBinding module, Annotation[] annotations, CompilationUnitDeclaration cud) {
- int attributesNumber = 0;
- // leave two bytes for the number of attributes and store the current offset
- int attributeOffset = this.contentsOffset;
- this.contentsOffset += 2;
-
- // source attribute
- if ((this.produceAttributes & ClassFileConstants.ATTR_SOURCE) != 0) {
- String fullFileName =
- new String(cud.getFileName());
- fullFileName = fullFileName.replace('\\', '/');
- int lastIndex = fullFileName.lastIndexOf('/');
- if (lastIndex != -1) {
- fullFileName = fullFileName.substring(lastIndex + 1, fullFileName.length());
- }
- attributesNumber += generateSourceAttribute(fullFileName);
- }
- attributesNumber += generateModuleAttribute(cud.moduleDeclaration);
- if (annotations != null) {
- long targetMask = TagBits.AnnotationForModule;
- attributesNumber += generateRuntimeAnnotations(annotations, targetMask);
- }
- char[] mainClass = cud.moduleDeclaration.binding.mainClassName;
- if (mainClass != null) {
- attributesNumber += generateModuleMainClassAttribute(CharOperation.replaceOnCopy(mainClass, '.', '/'));
- }
- char[][] packageNames = cud.moduleDeclaration.binding.getPackageNamesForClassFile();
- if (packageNames != null) {
- attributesNumber += generateModulePackagesAttribute(packageNames);
- }
-
- // update the number of attributes
- if (attributeOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- this.contents[attributeOffset++] = (byte) (attributesNumber >> 8);
- this.contents[attributeOffset] = (byte) attributesNumber;
-
- // resynchronize all offsets of the classfile
- this.header = this.constantPool.poolContent;
- this.headerOffset = this.constantPool.currentOffset;
- int constantPoolCount = this.constantPool.currentIndex;
- this.header[this.constantPoolOffset++] = (byte) (constantPoolCount >> 8);
- this.header[this.constantPoolOffset] = (byte) constantPoolCount;
- }
-
- /**
- * INTERNAL USE-ONLY
- * This methods generate all the default abstract method infos that correpond to
- * the abstract methods inherited from superinterfaces.
- */
- public void addDefaultAbstractMethods() { // default abstract methods
- MethodBinding[] defaultAbstractMethods =
- this.referenceBinding.getDefaultAbstractMethods();
- for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
- MethodBinding methodBinding = defaultAbstractMethods[i];
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
- }
- }
-
- private int addFieldAttributes(FieldBinding fieldBinding, int fieldAttributeOffset) {
- int attributesNumber = 0;
- // 4.7.2 only static constant fields get a ConstantAttribute
- // Generate the constantValueAttribute
- Constant fieldConstant = fieldBinding.constant();
- if (fieldConstant != Constant.NotAConstant){
- attributesNumber += generateConstantValueAttribute(fieldConstant, fieldBinding, fieldAttributeOffset);
- }
- if (this.targetJDK < ClassFileConstants.JDK1_5 && fieldBinding.isSynthetic()) {
- attributesNumber += generateSyntheticAttribute();
- }
- if (fieldBinding.isDeprecated()) {
- attributesNumber += generateDeprecatedAttribute();
- }
- // add signature attribute
- char[] genericSignature = fieldBinding.genericSignature();
- if (genericSignature != null) {
- attributesNumber += generateSignatureAttribute(genericSignature);
- }
- if (this.targetJDK >= ClassFileConstants.JDK1_4) {
- FieldDeclaration fieldDeclaration = fieldBinding.sourceField();
- if (fieldDeclaration != null) {
- try {
- if (fieldDeclaration.isARecordComponent) {
- long rcMask = TagBits.AnnotationForField | TagBits.AnnotationForTypeUse;
- RecordComponent comp = getRecordComponent(fieldBinding.declaringClass, fieldBinding.name);
- if (comp != null)
- fieldDeclaration.annotations = ASTNode.getRelevantAnnotations(comp.annotations, rcMask, null);
- }
- Annotation[] annotations = fieldDeclaration.annotations;
- if (annotations != null) {
- attributesNumber += generateRuntimeAnnotations(annotations, TagBits.AnnotationForField);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
- List allTypeAnnotationContexts = new ArrayList<>();
- if (annotations != null && (fieldDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) {
- fieldDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts);
- }
- TypeReference fieldType = fieldDeclaration.type;
- if (fieldType != null && ((fieldType.bits & ASTNode.HasTypeAnnotations) != 0)) {
- fieldType.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts);
- }
- int size = allTypeAnnotationContexts.size();
- attributesNumber = completeRuntimeTypeAnnotations(attributesNumber,
- null,
- node -> size > 0,
- () -> allTypeAnnotationContexts);
- }
- } finally {
- if (fieldDeclaration.isARecordComponent) {
- fieldDeclaration.annotations = null;
- }
- }
- }
- }
- if ((fieldBinding.tagBits & TagBits.HasMissingType) != 0) {
- this.missingTypes = fieldBinding.type.collectMissingTypes(this.missingTypes);
- }
- return attributesNumber;
- }
- private RecordComponent getRecordComponent(ReferenceBinding declaringClass, char[] name) {
- if (declaringClass instanceof SourceTypeBinding) {
- SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) declaringClass;
- RecordComponentBinding rcb = sourceTypeBinding.getRecordComponent(name);
- if (rcb != null) {
- RecordComponent recordComponent = rcb.sourceRecordComponent();
- return recordComponent;
- }
- }
- return null;
- }
- private int addComponentAttributes(RecordComponentBinding recordComponentBinding, int componetAttributeOffset) {
- // See JVMS 14 Table 4.7-C - Record Preview for allowed attributes
- int attributesNumber = 0;
- // add signature attribute
- char[] genericSignature = recordComponentBinding.genericSignature();
- if (genericSignature != null) {
- attributesNumber += generateSignatureAttribute(genericSignature);
- }
- RecordComponent recordComponent = recordComponentBinding.sourceRecordComponent();
- if (recordComponent != null) {
- Annotation[] annotations = recordComponent.annotations;
- if (annotations != null) {
- attributesNumber += generateRuntimeAnnotations(annotations, TagBits.AnnotationForRecordComponent);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
- List allTypeAnnotationContexts = new ArrayList<>();
- if (annotations != null && (recordComponent.bits & ASTNode.HasTypeAnnotations) != 0) {
- recordComponent.getAllAnnotationContexts(AnnotationTargetTypeConstants.RECORD_COMPONENT, allTypeAnnotationContexts);
- }
- TypeReference recordComponentType = recordComponent.type;
- if (recordComponentType != null && ((recordComponentType.bits & ASTNode.HasTypeAnnotations) != 0)) {
- recordComponentType.getAllAnnotationContexts(AnnotationTargetTypeConstants.RECORD_COMPONENT, allTypeAnnotationContexts);
- }
- int size = allTypeAnnotationContexts.size();
- attributesNumber = completeRuntimeTypeAnnotations(attributesNumber,
- null,
- node -> size > 0,
- () -> allTypeAnnotationContexts);
-
- }
- }
- if ((recordComponentBinding.tagBits & TagBits.HasMissingType) != 0) {
- this.missingTypes = recordComponentBinding.type.collectMissingTypes(this.missingTypes);
- }
- return attributesNumber;
- }
-
- private void addComponentInfo(RecordComponentBinding recordComponentBinding) {
- // check that there is enough space to write all the bytes for the field info corresponding
- // to the @fieldBinding sans accessflags for component
- /* record_component_info {
- * u2 name_index;
- * u2 descriptor_index;
- * u2 attributes_count;
- * attribute_info attributes[attributes_count];
- } */
- if (this.contentsOffset + 6 >= this.contents.length) {
- resizeContents(6);
- }
- // Now we can generate all entries into the byte array
- int nameIndex = this.constantPool.literalIndex(recordComponentBinding.name);
- this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) nameIndex;
- // Then the descriptorIndex
- int descriptorIndex = this.constantPool.literalIndex(recordComponentBinding.type);
- this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) descriptorIndex;
- int componentAttributeOffset = this.contentsOffset;
- int attributeNumber = 0;
- // leave some space for the number of attributes
- this.contentsOffset += 2;
- attributeNumber += addComponentAttributes(recordComponentBinding, componentAttributeOffset);
- if (this.contentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- this.contents[componentAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[componentAttributeOffset] = (byte) attributeNumber;
- }
-
- /**
- * INTERNAL USE-ONLY
- * This methods generates the bytes for the given field binding
- * @param fieldBinding the given field binding
- */
- private void addFieldInfo(FieldBinding fieldBinding) {
- // check that there is enough space to write all the bytes for the field info corresponding
- // to the @fieldBinding
- if (this.contentsOffset + 8 >= this.contents.length) {
- resizeContents(8);
- }
- // Now we can generate all entries into the byte array
- // First the accessFlags
- int accessFlags = fieldBinding.getAccessFlags();
- if (this.targetJDK < ClassFileConstants.JDK1_5) {
- // pre 1.5, synthetic was an attribute, not a modifier
- accessFlags &= ~ClassFileConstants.AccSynthetic;
- }
- this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
- this.contents[this.contentsOffset++] = (byte) accessFlags;
- // Then the nameIndex
- int nameIndex = this.constantPool.literalIndex(fieldBinding.name);
- this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) nameIndex;
- // Then the descriptorIndex
- int descriptorIndex = this.constantPool.literalIndex(fieldBinding.type);
- this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) descriptorIndex;
- int fieldAttributeOffset = this.contentsOffset;
- int attributeNumber = 0;
- // leave some space for the number of attributes
- this.contentsOffset += 2;
- attributeNumber += addFieldAttributes(fieldBinding, fieldAttributeOffset);
- if (this.contentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- this.contents[fieldAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[fieldAttributeOffset] = (byte) attributeNumber;
- }
-
- /**
- * INTERNAL USE-ONLY
- * This methods generate all the fields infos for the receiver.
- * This includes:
- * - a field info for each defined field of that class
- * - a field info for each synthetic field (e.g. this$0)
- */
- /**
- * INTERNAL USE-ONLY
- * This methods generate all the fields infos for the receiver.
- * This includes:
- * - a field info for each defined field of that class
- * - a field info for each synthetic field (e.g. this$0)
- */
- public void addFieldInfos() {
- SourceTypeBinding currentBinding = this.referenceBinding;
- FieldBinding[] syntheticFields = currentBinding.syntheticFields();
- int fieldCount = currentBinding.fieldCount() + (syntheticFields == null ? 0 : syntheticFields.length);
-
- // write the number of fields
- if (fieldCount > 0xFFFF) {
- this.referenceBinding.scope.problemReporter().tooManyFields(this.referenceBinding.scope.referenceType());
- }
- if (this.contentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- this.contents[this.contentsOffset++] = (byte) (fieldCount >> 8);
- this.contents[this.contentsOffset++] = (byte) fieldCount;
-
- FieldDeclaration[] fieldDecls = currentBinding.scope.referenceContext.fields;
- for (int i = 0, max = fieldDecls == null ? 0 : fieldDecls.length; i < max; i++) {
- FieldDeclaration fieldDecl = fieldDecls[i];
- if (fieldDecl.binding != null) {
- addFieldInfo(fieldDecl.binding);
- }
- }
-
- if (syntheticFields != null) {
- for (int i = 0, max = syntheticFields.length; i < max; i++) {
- addFieldInfo(syntheticFields[i]);
- }
- }
- }
-
- private void addMissingAbstractProblemMethod(MethodDeclaration methodDeclaration, MethodBinding methodBinding, CategorizedProblem problem, CompilationResult compilationResult) {
- // always clear the strictfp/native/abstract bit for a problem method
- generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
- int methodAttributeOffset = this.contentsOffset;
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
-
- // Code attribute
- attributeNumber++;
-
- int codeAttributeOffset = this.contentsOffset;
- generateCodeAttributeHeader();
- StringBuilder buffer = new StringBuilder(25);
- buffer.append("\t" + problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
- buffer.insert(0, Messages.compilation_unresolvedProblem);
- String problemString = buffer.toString();
-
- this.codeStream.init(this);
- this.codeStream.preserveUnusedLocals = true;
- this.codeStream.initializeMaxLocals(methodBinding);
-
- // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
- this.codeStream.generateCodeAttributeForProblemMethod(problemString);
-
- completeCodeAttributeForMissingAbstractProblemMethod(
- methodBinding,
- codeAttributeOffset,
- compilationResult.getLineSeparatorPositions(),
- problem.getSourceLineNumber());
-
- completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
- }
-
- /**
- * INTERNAL USE-ONLY
- * Generate the byte for a problem clinit method info that correspond to a boggus method.
- *
- * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
- */
- public void addProblemClinit(CategorizedProblem[] problems) {
- generateMethodInfoHeaderForClinit();
- // leave two spaces for the number of attributes
- this.contentsOffset -= 2;
- int attributeOffset = this.contentsOffset;
- this.contentsOffset += 2;
- int attributeNumber = 0;
-
- int codeAttributeOffset = this.contentsOffset;
- generateCodeAttributeHeader();
- this.codeStream.resetForProblemClinit(this);
- String problemString = "" ; //$NON-NLS-1$
- int problemLine = 0;
- if (problems != null) {
- int max = problems.length;
- StringBuilder buffer = new StringBuilder(25);
- int count = 0;
- for (int i = 0; i < max; i++) {
- CategorizedProblem problem = problems[i];
- if ((problem != null) && (problem.isError())) {
- buffer.append("\t" +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
- count++;
- if (problemLine == 0) {
- problemLine = problem.getSourceLineNumber();
- }
- problems[i] = null;
- }
- } // insert the top line afterwards, once knowing how many problems we have to consider
- if (count > 1) {
- buffer.insert(0, Messages.compilation_unresolvedProblems);
- } else {
- buffer.insert(0, Messages.compilation_unresolvedProblem);
- }
- problemString = buffer.toString();
- }
-
- // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
- this.codeStream.generateCodeAttributeForProblemMethod(problemString);
- attributeNumber++; // code attribute
- completeCodeAttributeForClinit(
- codeAttributeOffset,
- problemLine,
- null);
- if (this.contentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- this.contents[attributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[attributeOffset] = (byte) attributeNumber;
- }
-
- /**
- * INTERNAL USE-ONLY
- * Generate the byte for a problem method info that correspond to a boggus constructor.
- *
- * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
- * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
- * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
- */
- public void addProblemConstructor(
- AbstractMethodDeclaration method,
- MethodBinding methodBinding,
- CategorizedProblem[] problems) {
-
- if (methodBinding.declaringClass.isInterface()) {
- method.abort(ProblemSeverities.AbortType, null);
- }
-
- // always clear the strictfp/native/abstract bit for a problem method
- generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
- int methodAttributeOffset = this.contentsOffset;
- int attributesNumber = generateMethodInfoAttributes(methodBinding);
-
- // Code attribute
- attributesNumber++;
- int codeAttributeOffset = this.contentsOffset;
- generateCodeAttributeHeader();
- this.codeStream.reset(method, this);
- String problemString = "" ; //$NON-NLS-1$
- int problemLine = 0;
- if (problems != null) {
- int max = problems.length;
- StringBuilder buffer = new StringBuilder(25);
- int count = 0;
- for (int i = 0; i < max; i++) {
- CategorizedProblem problem = problems[i];
- if ((problem != null) && (problem.isError())) {
- buffer.append("\t" +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
- count++;
- if (problemLine == 0) {
- problemLine = problem.getSourceLineNumber();
- }
- }
- } // insert the top line afterwards, once knowing how many problems we have to consider
- if (count > 1) {
- buffer.insert(0, Messages.compilation_unresolvedProblems);
- } else {
- buffer.insert(0, Messages.compilation_unresolvedProblem);
- }
- problemString = buffer.toString();
- }
-
- // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
- this.codeStream.generateCodeAttributeForProblemMethod(problemString);
- completeCodeAttributeForProblemMethod(
- method,
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions(),
- problemLine);
- completeMethodInfo(methodBinding, methodAttributeOffset, attributesNumber);
- }
- /**
- * INTERNAL USE-ONLY
- * Generate the byte for a problem method info that correspond to a boggus constructor.
- * Reset the position inside the contents byte array to the savedOffset.
- *
- * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
- * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
- * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
- * @param savedOffset int
- */
- public void addProblemConstructor(
- AbstractMethodDeclaration method,
- MethodBinding methodBinding,
- CategorizedProblem[] problems,
- int savedOffset) {
- // we need to move back the contentsOffset to the value at the beginning of the method
- this.contentsOffset = savedOffset;
- this.methodCount--; // we need to remove the method that causes the problem
- addProblemConstructor(method, methodBinding, problems);
- }
- /**
- * INTERNAL USE-ONLY
- * Generate the byte for a problem method info that correspond to a boggus method.
- *
- * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
- * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
- * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
- */
- public void addProblemMethod(
- AbstractMethodDeclaration method,
- MethodBinding methodBinding,
- CategorizedProblem[] problems) {
- if (methodBinding.isAbstract() && methodBinding.declaringClass.isInterface()) {
- method.abort(ProblemSeverities.AbortType, null);
- }
- // always clear the strictfp/native/abstract bit for a problem method
- generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
- int methodAttributeOffset = this.contentsOffset;
- int attributesNumber = generateMethodInfoAttributes(methodBinding);
-
- // Code attribute
- attributesNumber++;
-
- int codeAttributeOffset = this.contentsOffset;
- generateCodeAttributeHeader();
- this.codeStream.reset(method, this);
- String problemString = "" ; //$NON-NLS-1$
- int problemLine = 0;
- if (problems != null) {
- int max = problems.length;
- StringBuilder buffer = new StringBuilder(25);
- int count = 0;
- for (int i = 0; i < max; i++) {
- CategorizedProblem problem = problems[i];
- if ((problem != null)
- && (problem.isError())
- && (problem.getSourceStart() >= method.declarationSourceStart)
- && (problem.getSourceEnd() <= method.declarationSourceEnd)) {
- buffer.append("\t" +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
- count++;
- if (problemLine == 0) {
- problemLine = problem.getSourceLineNumber();
- }
- problems[i] = null;
- }
- } // insert the top line afterwards, once knowing how many problems we have to consider
- if (count > 1) {
- buffer.insert(0, Messages.compilation_unresolvedProblems);
- } else {
- buffer.insert(0, Messages.compilation_unresolvedProblem);
- }
- problemString = buffer.toString();
- }
-
- // return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
- this.codeStream.generateCodeAttributeForProblemMethod(problemString);
- completeCodeAttributeForProblemMethod(
- method,
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions(),
- problemLine);
- completeMethodInfo(methodBinding, methodAttributeOffset, attributesNumber);
- }
-
- /**
- * INTERNAL USE-ONLY
- * Generate the byte for a problem method info that correspond to a boggus method.
- * Reset the position inside the contents byte array to the savedOffset.
- *
- * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
- * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
- * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
- * @param savedOffset int
- */
- public void addProblemMethod(
- AbstractMethodDeclaration method,
- MethodBinding methodBinding,
- CategorizedProblem[] problems,
- int savedOffset) {
- // we need to move back the contentsOffset to the value at the beginning of the method
- this.contentsOffset = savedOffset;
- this.methodCount--; // we need to remove the method that causes the problem
- addProblemMethod(method, methodBinding, problems);
- }
-
- /**
- * INTERNAL USE-ONLY
- * Generate the byte for all the special method infos.
- * They are:
- * - synthetic access methods
- * - default abstract methods
- * - lambda methods.
- */
- public void addSpecialMethods(TypeDeclaration typeDecl) {
-
- // add all methods (default abstract methods and synthetic)
-
- // default abstract methods
- generateMissingAbstractMethods(this.referenceBinding.scope.referenceType().missingAbstractMethods, this.referenceBinding.scope.referenceCompilationUnit().compilationResult);
-
- MethodBinding[] defaultAbstractMethods = this.referenceBinding.getDefaultAbstractMethods();
- for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
- MethodBinding methodBinding = defaultAbstractMethods[i];
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
- }
-
- // add synthetic methods infos
- int emittedSyntheticsCount = 0;
- SyntheticMethodBinding deserializeLambdaMethod = null;
- boolean continueScanningSynthetics = true;
- while (continueScanningSynthetics) {
- continueScanningSynthetics = false;
- SyntheticMethodBinding[] syntheticMethods = this.referenceBinding.syntheticMethods();
- int currentSyntheticsCount = syntheticMethods == null ? 0: syntheticMethods.length;
- if (emittedSyntheticsCount != currentSyntheticsCount) {
- for (int i = emittedSyntheticsCount, max = currentSyntheticsCount; i < max; i++) {
- SyntheticMethodBinding syntheticMethod = syntheticMethods[i];
- switch (syntheticMethod.purpose) {
- case SyntheticMethodBinding.FieldReadAccess :
- case SyntheticMethodBinding.SuperFieldReadAccess :
- // generate a method info to emulate an reading access to
- // a non-accessible field
- addSyntheticFieldReadAccessMethod(syntheticMethod);
- break;
- case SyntheticMethodBinding.FieldWriteAccess :
- case SyntheticMethodBinding.SuperFieldWriteAccess :
- // generate a method info to emulate an writing access to
- // a non-accessible field
- addSyntheticFieldWriteAccessMethod(syntheticMethod);
- break;
- case SyntheticMethodBinding.MethodAccess :
- case SyntheticMethodBinding.SuperMethodAccess :
- case SyntheticMethodBinding.BridgeMethod :
- // generate a method info to emulate an access to a non-accessible method / super-method or bridge method
- addSyntheticMethodAccessMethod(syntheticMethod);
- break;
- case SyntheticMethodBinding.ConstructorAccess :
- // generate a method info to emulate an access to a non-accessible constructor
- addSyntheticConstructorAccessMethod(syntheticMethod);
- break;
- case SyntheticMethodBinding.EnumValues :
- // generate a method info to define #values()
- addSyntheticEnumValuesMethod(syntheticMethod);
- break;
- case SyntheticMethodBinding.EnumValueOf :
- // generate a method info to define #valueOf(String)
- addSyntheticEnumValueOfMethod(syntheticMethod);
- break;
- case SyntheticMethodBinding.SwitchTable :
- // generate a method info to define the switch table synthetic method
- addSyntheticSwitchTable(syntheticMethod);
- break;
- case SyntheticMethodBinding.TooManyEnumsConstants :
- addSyntheticEnumInitializationMethod(syntheticMethod);
- break;
- case SyntheticMethodBinding.LambdaMethod:
- syntheticMethod.lambda.generateCode(this.referenceBinding.scope, this);
- continueScanningSynthetics = true; // lambda code generation could schedule additional nested lambdas for code generation.
- break;
- case SyntheticMethodBinding.ArrayConstructor:
- addSyntheticArrayConstructor(syntheticMethod);
- break;
- case SyntheticMethodBinding.ArrayClone:
- addSyntheticArrayClone(syntheticMethod);
- break;
- case SyntheticMethodBinding.FactoryMethod:
- addSyntheticFactoryMethod(syntheticMethod);
- break;
- case SyntheticMethodBinding.DeserializeLambda:
- deserializeLambdaMethod = syntheticMethod; // delay processing
- break;
- case SyntheticMethodBinding.SerializableMethodReference:
- // Nothing to be done
- break;
- case SyntheticMethodBinding.RecordCanonicalConstructor:
- addSyntheticRecordCanonicalConstructor(typeDecl, syntheticMethod);
- break;
- case SyntheticMethodBinding.RecordOverrideEquals:
- case SyntheticMethodBinding.RecordOverrideHashCode:
- case SyntheticMethodBinding.RecordOverrideToString:
- addSyntheticRecordOverrideMethods(typeDecl, syntheticMethod, syntheticMethod.purpose);
- break;
- }
- }
- emittedSyntheticsCount = currentSyntheticsCount;
- }
- }
- if (deserializeLambdaMethod != null) {
- int problemResetPC = 0;
- this.codeStream.wideMode = false;
- boolean restart = false;
- do {
- try {
- problemResetPC = this.contentsOffset;
- addSyntheticDeserializeLambda(deserializeLambdaMethod,this.referenceBinding.syntheticMethods());
- restart = false;
- } catch (AbortMethod e) {
- // Restart code generation if possible ...
- if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
- // a branch target required a goto_w, restart code generation in wide mode.
- this.contentsOffset = problemResetPC;
- this.methodCount--;
- this.codeStream.resetInWideMode(); // request wide mode
- restart = true;
- } else {
- throw new AbortType(this.referenceBinding.scope.referenceContext.compilationResult, e.problem);
- }
- }
- } while (restart);
- }
- }
-
- private void addSyntheticRecordCanonicalConstructor(TypeDeclaration typeDecl, SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForRecordCanonicalConstructor(methodBinding);
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
-
- private void addSyntheticRecordOverrideMethods(TypeDeclaration typeDecl, SyntheticMethodBinding methodBinding, int purpose) {
- if (this.bootstrapMethods == null)
- this.bootstrapMethods = new ArrayList<>(3);
- if (!this.bootstrapMethods.contains(typeDecl))
- this.bootstrapMethods.add(typeDecl);
- int index = this.bootstrapMethods.indexOf(typeDecl);
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- switch (purpose) {
- case SyntheticMethodBinding.RecordCanonicalConstructor:
- this.codeStream.generateSyntheticBodyForRecordCanonicalConstructor(methodBinding);
- break;
- case SyntheticMethodBinding.RecordOverrideEquals:
- this.codeStream.generateSyntheticBodyForRecordEquals(methodBinding, index);
- break;
- case SyntheticMethodBinding.RecordOverrideHashCode:
- this.codeStream.generateSyntheticBodyForRecordHashCode(methodBinding, index);
- break;
- case SyntheticMethodBinding.RecordOverrideToString:
- this.codeStream.generateSyntheticBodyForRecordToString(methodBinding, index);
- break;
- default:
- break;
- }
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
-
- public void addSyntheticArrayConstructor(SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForArrayConstructor(methodBinding);
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
- public void addSyntheticArrayClone(SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForArrayClone(methodBinding);
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
- public void addSyntheticFactoryMethod(SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForFactoryMethod(methodBinding);
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
- /**
- * INTERNAL USE-ONLY
- * Generate the bytes for a synthetic method that provides an access to a private constructor.
- *
- * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
- */
- public void addSyntheticConstructorAccessMethod(SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForConstructorAccess(methodBinding);
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
-
- /**
- * INTERNAL USE-ONLY
- * Generate the bytes for a synthetic method that implements Enum#valueOf(String) for a given enum type
- *
- * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
- */
- public void addSyntheticEnumValueOfMethod(SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForEnumValueOf(methodBinding);
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- if ((this.produceAttributes & ClassFileConstants.ATTR_METHOD_PARAMETERS) != 0) {
- attributeNumber += generateMethodParameters(methodBinding);
- }
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
-
- /**
- * INTERNAL USE-ONLY
- * Generate the bytes for a synthetic method that implements Enum#values() for a given enum type
- *
- * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
- */
- public void addSyntheticEnumValuesMethod(SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForEnumValues(methodBinding);
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
-
- public void addSyntheticEnumInitializationMethod(SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForEnumInitializationMethod(methodBinding);
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
- /**
- * INTERNAL USE-ONLY
- * Generate the byte for a problem method info that correspond to a synthetic method that
- * generate an read access to a private field.
- *
- * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
- */
- public void addSyntheticFieldReadAccessMethod(SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForFieldReadAccess(methodBinding);
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
-
- /**
- * INTERNAL USE-ONLY
- * Generate the byte for a problem method info that correspond to a synthetic method that
- * generate an write access to a private field.
- *
- * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
- */
- public void addSyntheticFieldWriteAccessMethod(SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForFieldWriteAccess(methodBinding);
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
-
- /**
- * INTERNAL USE-ONLY
- * Generate the bytes for a synthetic method that provides access to a private method.
- *
- * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
- */
- public void addSyntheticMethodAccessMethod(SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForMethodAccess(methodBinding);
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
-
- public void addSyntheticSwitchTable(SyntheticMethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForSwitchTable(methodBinding);
- int code_length = this.codeStream.position;
- if (code_length > 65535) {
- SwitchStatement switchStatement = methodBinding.switchStatement;
- if (switchStatement != null) {
- switchStatement.scope.problemReporter().bytecodeExceeds64KLimit(switchStatement);
- }
- }
- completeCodeAttributeForSyntheticMethod(
- true,
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions(),
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope);
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
-
- /**
- * INTERNAL USE-ONLY
- * That method completes the creation of the code attribute by setting
- * - the attribute_length
- * - max_stack
- * - max_locals
- * - code_length
- * - exception table
- * - and debug attributes if necessary.
- *
- * @param codeAttributeOffset int
- */
- public void completeCodeAttribute(int codeAttributeOffset, MethodScope scope) {
- // reinitialize the localContents with the byte modified by the code stream
- this.contents = this.codeStream.bCodeStream;
- int localContentsOffset = this.codeStream.classFileOffset;
- // codeAttributeOffset is the position inside localContents byte array before we started to write
- // any information about the codeAttribute
- // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
- // to get the right position, 6 for the max_stack etc...
- int code_length = this.codeStream.position;
- if (code_length > 65535) {
- if (this.codeStream.methodDeclaration != null) {
- this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(this.codeStream.methodDeclaration);
- } else {
- this.codeStream.lambdaExpression.scope.problemReporter().bytecodeExceeds64KLimit(this.codeStream.lambdaExpression);
- }
- }
- if (localContentsOffset + 20 >= this.contents.length) {
- resizeContents(20);
- }
- int max_stack = this.codeStream.stackMax;
- this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
- this.contents[codeAttributeOffset + 7] = (byte) max_stack;
- int max_locals = this.codeStream.maxLocals;
- this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
- this.contents[codeAttributeOffset + 9] = (byte) max_locals;
- this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
- this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
- this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
- this.contents[codeAttributeOffset + 13] = (byte) code_length;
-
- boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
- // write the exception table
- ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
- int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
- for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
- exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
- }
- int exSize = exceptionHandlersCount * 8 + 2;
- if (exSize + localContentsOffset >= this.contents.length) {
- resizeContents(exSize);
- }
- // there is no exception table, so we need to offset by 2 the current offset and move
- // on the attribute generation
- this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
- this.contents[localContentsOffset++] = (byte) exceptionHandlersCount;
- for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
- ExceptionLabel exceptionLabel = exceptionLabels[i];
- if (exceptionLabel != null) {
- int iRange = 0, maxRange = exceptionLabel.getCount();
- if ((maxRange & 1) != 0) {
- if (this.codeStream.methodDeclaration != null) {
- this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError(
- Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.methodDeclaration.selector)),
- this.codeStream.methodDeclaration);
- } else {
- this.codeStream.lambdaExpression.scope.problemReporter().abortDueToInternalError(
- Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.lambdaExpression.binding.selector)),
- this.codeStream.lambdaExpression);
- }
- }
- while (iRange < maxRange) {
- int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
- this.contents[localContentsOffset++] = (byte) (start >> 8);
- this.contents[localContentsOffset++] = (byte) start;
- int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
- this.contents[localContentsOffset++] = (byte) (end >> 8);
- this.contents[localContentsOffset++] = (byte) end;
- int handlerPC = exceptionLabel.position;
- if (addStackMaps) {
- StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
- stackMapFrameCodeStream.addFramePosition(handlerPC);
-// stackMapFrameCodeStream.addExceptionMarker(handlerPC, exceptionLabel.exceptionType);
- }
- this.contents[localContentsOffset++] = (byte) (handlerPC >> 8);
- this.contents[localContentsOffset++] = (byte) handlerPC;
- if (exceptionLabel.exceptionType == null) {
- // any exception handler
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- } else {
- int nameIndex;
- if (exceptionLabel.exceptionType == TypeBinding.NULL) {
- /* represents ClassNotFoundException, see class literal access*/
- nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
- } else {
- nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType);
- }
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) nameIndex;
- }
- }
- }
- }
- // debug attributes
- int codeAttributeAttributeOffset = localContentsOffset;
- int attributesNumber = 0;
- // leave two bytes for the attribute_length
- localContentsOffset += 2;
- if (localContentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
-
- this.contentsOffset = localContentsOffset;
-
- // first we handle the linenumber attribute
- if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
- attributesNumber += generateLineNumberAttribute();
- }
- // then we do the local variable attribute
- if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
- final boolean methodDeclarationIsStatic = this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.isStatic() : this.codeStream.lambdaExpression.binding.isStatic();
- attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, false);
- }
-
- if (addStackMaps) {
- attributesNumber += generateStackMapTableAttribute(
- this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.binding : this.codeStream.lambdaExpression.binding,
- code_length,
- codeAttributeOffset,
- max_locals,
- false,
- scope);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
- attributesNumber += generateStackMapAttribute(
- this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.binding : this.codeStream.lambdaExpression.binding,
- code_length,
- codeAttributeOffset,
- max_locals,
- false,
- scope);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
- attributesNumber += generateTypeAnnotationsOnCodeAttribute();
- }
-
- this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
- this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
-
- // update the attribute length
- int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
- this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
- this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
- this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
- this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
- }
-
- public int generateTypeAnnotationsOnCodeAttribute() {
- int attributesNumber = 0;
-
- List allTypeAnnotationContexts = ((TypeAnnotationCodeStream) this.codeStream).allTypeAnnotationContexts;
-
- for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
- LocalVariableBinding localVariable = this.codeStream.locals[i];
- if (localVariable.isCatchParameter()) continue;
- LocalDeclaration declaration = localVariable.declaration;
- if (declaration == null
- || (declaration.isArgument() && ((declaration.bits & ASTNode.IsUnionType) == 0))
- || (localVariable.initializationCount == 0)
- || ((declaration.bits & ASTNode.HasTypeAnnotations) == 0)) {
- continue;
- }
- int targetType = ((localVariable.tagBits & TagBits.IsResource) == 0) ? AnnotationTargetTypeConstants.LOCAL_VARIABLE : AnnotationTargetTypeConstants.RESOURCE_VARIABLE;
- declaration.getAllAnnotationContexts(targetType, localVariable, allTypeAnnotationContexts);
- }
-
- ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
- for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
- ExceptionLabel exceptionLabel = exceptionLabels[i];
- if (exceptionLabel.exceptionTypeReference != null && (exceptionLabel.exceptionTypeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
- exceptionLabel.exceptionTypeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.EXCEPTION_PARAMETER, i, allTypeAnnotationContexts, exceptionLabel.se7Annotations);
- }
- }
- int size = allTypeAnnotationContexts.size();
- attributesNumber = completeRuntimeTypeAnnotations(attributesNumber,
- null,
- node -> size > 0,
- () -> allTypeAnnotationContexts);
- return attributesNumber;
- }
-
- /**
- * INTERNAL USE-ONLY
- * That method completes the creation of the code attribute by setting
- * - the attribute_length
- * - max_stack
- * - max_locals
- * - code_length
- * - exception table
- * - and debug attributes if necessary.
- *
- * @param codeAttributeOffset int
- */
- public void completeCodeAttributeForClinit(int codeAttributeOffset, Scope scope) {
- // reinitialize the contents with the byte modified by the code stream
- this.contents = this.codeStream.bCodeStream;
- int localContentsOffset = this.codeStream.classFileOffset;
- // codeAttributeOffset is the position inside contents byte array before we started to write
- // any information about the codeAttribute
- // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
- // to get the right position, 6 for the max_stack etc...
- int code_length = this.codeStream.position;
- if (code_length > 65535) {
- this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(
- this.codeStream.methodDeclaration.scope.referenceType());
- }
- if (localContentsOffset + 20 >= this.contents.length) {
- resizeContents(20);
- }
- int max_stack = this.codeStream.stackMax;
- this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
- this.contents[codeAttributeOffset + 7] = (byte) max_stack;
- int max_locals = this.codeStream.maxLocals;
- this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
- this.contents[codeAttributeOffset + 9] = (byte) max_locals;
- this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
- this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
- this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
- this.contents[codeAttributeOffset + 13] = (byte) code_length;
-
- boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
- // write the exception table
- ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
- int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
- for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
- exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
- }
- int exSize = exceptionHandlersCount * 8 + 2;
- if (exSize + localContentsOffset >= this.contents.length) {
- resizeContents(exSize);
- }
- // there is no exception table, so we need to offset by 2 the current offset and move
- // on the attribute generation
- this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
- this.contents[localContentsOffset++] = (byte) exceptionHandlersCount;
- for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
- ExceptionLabel exceptionLabel = exceptionLabels[i];
- if (exceptionLabel != null) {
- int iRange = 0, maxRange = exceptionLabel.getCount();
- if ((maxRange & 1) != 0) {
- this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError(
- Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.methodDeclaration.selector)),
- this.codeStream.methodDeclaration);
- }
- while (iRange < maxRange) {
- int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
- this.contents[localContentsOffset++] = (byte) (start >> 8);
- this.contents[localContentsOffset++] = (byte) start;
- int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
- this.contents[localContentsOffset++] = (byte) (end >> 8);
- this.contents[localContentsOffset++] = (byte) end;
- int handlerPC = exceptionLabel.position;
- this.contents[localContentsOffset++] = (byte) (handlerPC >> 8);
- this.contents[localContentsOffset++] = (byte) handlerPC;
- if (addStackMaps) {
- StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
- stackMapFrameCodeStream.addFramePosition(handlerPC);
-// stackMapFrameCodeStream.addExceptionMarker(handlerPC, exceptionLabel.exceptionType);
- }
- if (exceptionLabel.exceptionType == null) {
- // any exception handler
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- } else {
- int nameIndex;
- if (exceptionLabel.exceptionType == TypeBinding.NULL) {
- /* represents denote ClassNotFoundException, see class literal access*/
- nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
- } else {
- nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType);
- }
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) nameIndex;
- }
- }
- }
- }
- // debug attributes
- int codeAttributeAttributeOffset = localContentsOffset;
- int attributesNumber = 0;
- // leave two bytes for the attribute_length
- localContentsOffset += 2;
- if (localContentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
-
- this.contentsOffset = localContentsOffset;
-
- // first we handle the linenumber attribute
- if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
- attributesNumber += generateLineNumberAttribute();
- }
- // then we do the local variable attribute
- if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
- attributesNumber += generateLocalVariableTableAttribute(code_length, true, false);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
- attributesNumber += generateStackMapTableAttribute(
- null,
- code_length,
- codeAttributeOffset,
- max_locals,
- true,
- scope);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
- attributesNumber += generateStackMapAttribute(
- null,
- code_length,
- codeAttributeOffset,
- max_locals,
- true,
- scope);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
- attributesNumber += generateTypeAnnotationsOnCodeAttribute();
- }
-
- // update the number of attributes
- // ensure first that there is enough space available inside the contents array
- if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
- this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
- // update the attribute length
- int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
- this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
- this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
- this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
- this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
- }
-
- /**
- * INTERNAL USE-ONLY
- * That method completes the creation of the code attribute by setting
- * - the attribute_length
- * - max_stack
- * - max_locals
- * - code_length
- * - exception table
- * - and debug attributes if necessary.
- */
- public void completeCodeAttributeForClinit(
- int codeAttributeOffset,
- int problemLine,
- MethodScope scope) {
- // reinitialize the contents with the byte modified by the code stream
- this.contents = this.codeStream.bCodeStream;
- int localContentsOffset = this.codeStream.classFileOffset;
- // codeAttributeOffset is the position inside contents byte array before we started to write
- // any information about the codeAttribute
- // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
- // to get the right position, 6 for the max_stack etc...
- int code_length = this.codeStream.position;
- if (code_length > 65535) {
- this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(
- this.codeStream.methodDeclaration.scope.referenceType());
- }
- if (localContentsOffset + 20 >= this.contents.length) {
- resizeContents(20);
- }
- int max_stack = this.codeStream.stackMax;
- this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
- this.contents[codeAttributeOffset + 7] = (byte) max_stack;
- int max_locals = this.codeStream.maxLocals;
- this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
- this.contents[codeAttributeOffset + 9] = (byte) max_locals;
- this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
- this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
- this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
- this.contents[codeAttributeOffset + 13] = (byte) code_length;
-
- // write the exception table
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
-
- // debug attributes
- int codeAttributeAttributeOffset = localContentsOffset;
- int attributesNumber = 0; // leave two bytes for the attribute_length
- localContentsOffset += 2; // first we handle the linenumber attribute
- if (localContentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
-
- this.contentsOffset = localContentsOffset;
- // first we handle the linenumber attribute
- if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
- attributesNumber += generateLineNumberAttribute(problemLine);
- }
- localContentsOffset = this.contentsOffset;
- // then we do the local variable attribute
- if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
- int localVariableNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
- if (localContentsOffset + 8 >= this.contents.length) {
- resizeContents(8);
- }
- this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) localVariableNameIndex;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 2;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- attributesNumber++;
- }
-
- this.contentsOffset = localContentsOffset;
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
- attributesNumber += generateStackMapTableAttribute(
- null,
- code_length,
- codeAttributeOffset,
- max_locals,
- true,
- scope);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
- attributesNumber += generateStackMapAttribute(
- null,
- code_length,
- codeAttributeOffset,
- max_locals,
- true,
- scope);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
- attributesNumber += generateTypeAnnotationsOnCodeAttribute();
- }
-
- // update the number of attributes
- // ensure first that there is enough space available inside the contents array
- if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
- this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
- // update the attribute length
- int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
- this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
- this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
- this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
- this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
- }
-
-
- public void completeCodeAttributeForMissingAbstractProblemMethod(
- MethodBinding binding,
- int codeAttributeOffset,
- int[] startLineIndexes,
- int problemLine) {
- // reinitialize the localContents with the byte modified by the code stream
- this.contents = this.codeStream.bCodeStream;
- int localContentsOffset = this.codeStream.classFileOffset;
- // codeAttributeOffset is the position inside localContents byte array before we started to write// any information about the codeAttribute// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset// to get the right position, 6 for the max_stack etc...
- int max_stack = this.codeStream.stackMax;
- this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
- this.contents[codeAttributeOffset + 7] = (byte) max_stack;
- int max_locals = this.codeStream.maxLocals;
- this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
- this.contents[codeAttributeOffset + 9] = (byte) max_locals;
- int code_length = this.codeStream.position;
- this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
- this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
- this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
- this.contents[codeAttributeOffset + 13] = (byte) code_length;
- // write the exception table
- if (localContentsOffset + 50 >= this.contents.length) {
- resizeContents(50);
- }
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- // debug attributes
- int codeAttributeAttributeOffset = localContentsOffset;
- int attributesNumber = 0; // leave two bytes for the attribute_length
- localContentsOffset += 2; // first we handle the linenumber attribute
- if (localContentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
-
- this.contentsOffset = localContentsOffset;
- if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
- if (problemLine == 0) {
- problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1);
- }
- attributesNumber += generateLineNumberAttribute(problemLine);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
- attributesNumber += generateStackMapTableAttribute(
- binding,
- code_length,
- codeAttributeOffset,
- max_locals,
- false,
- null);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
- attributesNumber += generateStackMapAttribute(
- binding,
- code_length,
- codeAttributeOffset,
- max_locals,
- false,
- null);
- }
-
- // then we do the local variable attribute
- // update the number of attributes// ensure first that there is enough space available inside the localContents array
- if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
- this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
- // update the attribute length
- int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
- this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
- this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
- this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
- this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
- }
-
- /**
- * INTERNAL USE-ONLY
- * That method completes the creation of the code attribute by setting
- * - the attribute_length
- * - max_stack
- * - max_locals
- * - code_length
- * - exception table
- * - and debug attributes if necessary.
- *
- * @param codeAttributeOffset int
- */
- public void completeCodeAttributeForProblemMethod(
- AbstractMethodDeclaration method,
- MethodBinding binding,
- int codeAttributeOffset,
- int[] startLineIndexes,
- int problemLine) {
- // reinitialize the localContents with the byte modified by the code stream
- this.contents = this.codeStream.bCodeStream;
- int localContentsOffset = this.codeStream.classFileOffset;
- // codeAttributeOffset is the position inside localContents byte array before we started to write// any information about the codeAttribute// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset// to get the right position, 6 for the max_stack etc...
- int max_stack = this.codeStream.stackMax;
- this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
- this.contents[codeAttributeOffset + 7] = (byte) max_stack;
- int max_locals = this.codeStream.maxLocals;
- this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
- this.contents[codeAttributeOffset + 9] = (byte) max_locals;
- int code_length = this.codeStream.position;
- this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
- this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
- this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
- this.contents[codeAttributeOffset + 13] = (byte) code_length;
- // write the exception table
- if (localContentsOffset + 50 >= this.contents.length) {
- resizeContents(50);
- }
-
- // write the exception table
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- // debug attributes
- int codeAttributeAttributeOffset = localContentsOffset;
- int attributesNumber = 0; // leave two bytes for the attribute_length
- localContentsOffset += 2; // first we handle the linenumber attribute
- if (localContentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
-
- this.contentsOffset = localContentsOffset;
- if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
- if (problemLine == 0) {
- problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1);
- }
- attributesNumber += generateLineNumberAttribute(problemLine);
- }
-
- // then we do the local variable attribute
- if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
- final boolean methodDeclarationIsStatic = this.codeStream.methodDeclaration.isStatic();
- attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, false);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
- attributesNumber += generateStackMapTableAttribute(
- binding,
- code_length,
- codeAttributeOffset,
- max_locals,
- false,
- null);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
- attributesNumber += generateStackMapAttribute(
- binding,
- code_length,
- codeAttributeOffset,
- max_locals,
- false,
- null);
- }
-
- // update the number of attributes// ensure first that there is enough space available inside the localContents array
- if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
- this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
- // update the attribute length
- int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
- this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
- this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
- this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
- this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
- }
-
- /**
- * INTERNAL USE-ONLY
- * That method completes the creation of the code attribute by setting
- * - the attribute_length
- * - max_stack
- * - max_locals
- * - code_length
- * - exception table
- * - and debug attributes if necessary.
- *
- * @param binding org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
- * @param codeAttributeOffset int
- */
- public void completeCodeAttributeForSyntheticMethod(
- boolean hasExceptionHandlers,
- SyntheticMethodBinding binding,
- int codeAttributeOffset,
- int[] startLineIndexes,
- Scope scope) {
- // reinitialize the contents with the byte modified by the code stream
- this.contents = this.codeStream.bCodeStream;
- int localContentsOffset = this.codeStream.classFileOffset;
- // codeAttributeOffset is the position inside contents byte array before we started to write
- // any information about the codeAttribute
- // That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
- // to get the right position, 6 for the max_stack etc...
- int max_stack = this.codeStream.stackMax;
- this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
- this.contents[codeAttributeOffset + 7] = (byte) max_stack;
- int max_locals = this.codeStream.maxLocals;
- this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
- this.contents[codeAttributeOffset + 9] = (byte) max_locals;
- int code_length = this.codeStream.position;
- this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
- this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
- this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
- this.contents[codeAttributeOffset + 13] = (byte) code_length;
- if ((localContentsOffset + 40) >= this.contents.length) {
- resizeContents(40);
- }
-
- boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
- if (hasExceptionHandlers) {
- // write the exception table
- ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
- int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
- for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
- exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
- }
- int exSize = exceptionHandlersCount * 8 + 2;
- if (exSize + localContentsOffset >= this.contents.length) {
- resizeContents(exSize);
- }
- // there is no exception table, so we need to offset by 2 the current offset and move
- // on the attribute generation
- this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
- this.contents[localContentsOffset++] = (byte) exceptionHandlersCount;
- for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
- ExceptionLabel exceptionLabel = exceptionLabels[i];
- if (exceptionLabel != null) {
- int iRange = 0, maxRange = exceptionLabel.getCount();
- if ((maxRange & 1) != 0) {
- ProblemReporter problemReporter = this.referenceBinding.scope.problemReporter();
- problemReporter.abortDueToInternalError(
- Messages.bind(Messages.abort_invalidExceptionAttribute, new String(binding.selector),
- problemReporter.referenceContext));
- }
- while (iRange < maxRange) {
- int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
- this.contents[localContentsOffset++] = (byte) (start >> 8);
- this.contents[localContentsOffset++] = (byte) start;
- int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
- this.contents[localContentsOffset++] = (byte) (end >> 8);
- this.contents[localContentsOffset++] = (byte) end;
- int handlerPC = exceptionLabel.position;
- if (addStackMaps) {
- StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
- stackMapFrameCodeStream.addFramePosition(handlerPC);
- }
- this.contents[localContentsOffset++] = (byte) (handlerPC >> 8);
- this.contents[localContentsOffset++] = (byte) handlerPC;
- if (exceptionLabel.exceptionType == null) {
- // any exception handler
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- } else {
- int nameIndex;
- switch(exceptionLabel.exceptionType.id) {
- case T_null :
- /* represents ClassNotFoundException, see class literal access*/
- nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
- break;
- case T_long :
- /* represents NoSuchFieldError, see switch table generation*/
- nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangNoSuchFieldErrorConstantPoolName);
- break;
- default:
- nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType);
- }
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) nameIndex;
- }
- }
- }
- }
- } else {
- // there is no exception table, so we need to offset by 2 the current offset and move
- // on the attribute generation
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- }
- // debug attributes
- int codeAttributeAttributeOffset = localContentsOffset;
- int attributesNumber = 0;
- // leave two bytes for the attribute_length
- localContentsOffset += 2;
- if (localContentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
-
- this.contentsOffset = localContentsOffset;
- // first we handle the linenumber attribute
- if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
- int lineNumber = Util.getLineNumber(binding.sourceStart, startLineIndexes, 0, startLineIndexes.length-1);
- attributesNumber += generateLineNumberAttribute(lineNumber);
- }
- // then we do the local variable attribute
- if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
- final boolean methodDeclarationIsStatic = binding.isStatic();
- attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, true);
- }
- if (addStackMaps) {
- attributesNumber += generateStackMapTableAttribute(binding, code_length, codeAttributeOffset, max_locals, false, scope);
- }
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
- attributesNumber += generateStackMapAttribute(
- binding,
- code_length,
- codeAttributeOffset,
- max_locals,
- false,
- scope);
- }
-
- // update the number of attributes
- // ensure first that there is enough space available inside the contents array
- if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
- this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
-
- // update the attribute length
- int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
- this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
- this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
- this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
- this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
- }
-
- /**
- * INTERNAL USE-ONLY
- * That method completes the creation of the code attribute by setting
- * - the attribute_length
- * - max_stack
- * - max_locals
- * - code_length
- * - exception table
- * - and debug attributes if necessary.
- *
- * @param binding org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
- * @param codeAttributeOffset int
- */
- public void completeCodeAttributeForSyntheticMethod(
- SyntheticMethodBinding binding,
- int codeAttributeOffset,
- int[] startLineIndexes) {
-
- this.completeCodeAttributeForSyntheticMethod(
- false,
- binding,
- codeAttributeOffset,
- startLineIndexes,
- ((SourceTypeBinding) binding.declaringClass).scope);
- }
-
- private void completeArgumentAnnotationInfo(Argument[] arguments, List allAnnotationContexts) {
- for (int i = 0, max = arguments.length; i < max; i++) {
- Argument argument = arguments[i];
- if ((argument.bits & ASTNode.HasTypeAnnotations) != 0) {
- argument.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER, i, allAnnotationContexts);
- }
- }
- }
-
- /**
- * INTERNAL USE-ONLY
- * Complete the creation of a method info by setting up the number of attributes at the right offset.
- *
- * @param methodAttributeOffset int
- * @param attributesNumber int
- */
- public void completeMethodInfo(
- MethodBinding binding,
- int methodAttributeOffset,
- int attributesNumber) {
-
- if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
- List allTypeAnnotationContexts = new ArrayList<>();
- AbstractMethodDeclaration methodDeclaration = binding.sourceMethod();
- if (methodDeclaration != null) {
- if ((methodDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) {
- Argument[] arguments = methodDeclaration.arguments;
- if (arguments != null) {
- completeArgumentAnnotationInfo(arguments, allTypeAnnotationContexts);
- }
- Receiver receiver = methodDeclaration.receiver;
- if (receiver != null && (receiver.type.bits & ASTNode.HasTypeAnnotations) != 0) {
- receiver.type.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RECEIVER, allTypeAnnotationContexts);
- }
- }
- Annotation[] annotations = methodDeclaration.annotations;
- if (annotations != null && !methodDeclaration.isClinit() && (methodDeclaration.isConstructor() || binding.returnType.id != T_void)) {
- // at source level type annotations have not been moved from declaration to type use position, collect them now:
- methodDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
- }
- if (!methodDeclaration.isConstructor() && !methodDeclaration.isClinit() && binding.returnType.id != T_void) {
- MethodDeclaration declaration = (MethodDeclaration) methodDeclaration;
- TypeReference typeReference = declaration.returnType;
- if ((typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
- typeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
- }
- }
- TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
- if (thrownExceptions != null) {
- for (int i = 0, max = thrownExceptions.length; i < max; i++) {
- TypeReference thrownException = thrownExceptions[i];
- thrownException.getAllAnnotationContexts(AnnotationTargetTypeConstants.THROWS, i, allTypeAnnotationContexts);
- }
- }
- TypeParameter[] typeParameters = methodDeclaration.typeParameters();
- if (typeParameters != null) {
- for (int i = 0, max = typeParameters.length; i < max; i++) {
- TypeParameter typeParameter = typeParameters[i];
- if ((typeParameter.bits & ASTNode.HasTypeAnnotations) != 0) {
- typeParameter.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER, i, allTypeAnnotationContexts);
- }
- }
- }
- } else if (binding.sourceLambda() != null) { // SyntheticMethodBinding, purpose : LambdaMethod.
- LambdaExpression lambda = binding.sourceLambda();
- if ((lambda.bits & ASTNode.HasTypeAnnotations) != 0) {
- if (lambda.arguments != null)
- completeArgumentAnnotationInfo(lambda.arguments, allTypeAnnotationContexts);
- }
- }
- int size = allTypeAnnotationContexts.size();
- attributesNumber = completeRuntimeTypeAnnotations(attributesNumber,
- null,
- node -> size > 0,
- () -> allTypeAnnotationContexts);
- }
- if ((this.produceAttributes & ClassFileConstants.ATTR_METHOD_PARAMETERS) != 0 ||
- binding.isConstructor() && binding.declaringClass.isRecord()) {
- attributesNumber += generateMethodParameters(binding);
- }
- // update the number of attributes
- this.contents[methodAttributeOffset++] = (byte) (attributesNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributesNumber;
- }
-
- private void dumpLocations(int[] locations) {
- if (locations == null) {
- // no type path
- if (this.contentsOffset + 1 >= this.contents.length) {
- resizeContents(1);
- }
- this.contents[this.contentsOffset++] = (byte) 0;
- } else {
- int length = locations.length;
- if (this.contentsOffset + length >= this.contents.length) {
- resizeContents(length + 1);
- }
- this.contents[this.contentsOffset++] = (byte) (locations.length / 2);
- for (int i = 0; i < length; i++) {
- this.contents[this.contentsOffset++] = (byte) locations[i];
- }
- }
- }
- private void dumpTargetTypeContents(int targetType, AnnotationContext annotationContext) {
- switch(targetType) {
- case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
- case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
- // parameter index
- this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- break;
-
- case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
- // type_parameter_index
- this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- // bound_index
- this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
- break;
- case AnnotationTargetTypeConstants.FIELD :
- case AnnotationTargetTypeConstants.METHOD_RECEIVER :
- case AnnotationTargetTypeConstants.METHOD_RETURN :
- // target_info is empty_target
- break;
- case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER :
- // target_info is parameter index
- this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- break;
-
- case AnnotationTargetTypeConstants.INSTANCEOF :
- case AnnotationTargetTypeConstants.NEW :
- case AnnotationTargetTypeConstants.EXCEPTION_PARAMETER :
- case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE :
- case AnnotationTargetTypeConstants.METHOD_REFERENCE :
- // bytecode offset for new/instanceof/method_reference
- // exception table entry index for exception_parameter
- this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
- this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- break;
- case AnnotationTargetTypeConstants.CAST :
- // bytecode offset
- this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
- this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
- break;
-
- case AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
- case AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
- case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
- case AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
- // bytecode offset
- this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
- this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- // type_argument_index
- this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
- break;
-
- case AnnotationTargetTypeConstants.CLASS_EXTENDS :
- case AnnotationTargetTypeConstants.THROWS :
- // For CLASS_EXTENDS - info is supertype index (-1 = superclass)
- // For THROWS - info is exception table index
- this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
- this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- break;
-
- case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
- case AnnotationTargetTypeConstants.RESOURCE_VARIABLE :
- int localVariableTableOffset = this.contentsOffset;
- LocalVariableBinding localVariable = annotationContext.variableBinding;
- int actualSize = 0;
- int initializationCount = localVariable.initializationCount;
- actualSize += 2 /* for number of entries */ + (6 * initializationCount);
- // reserve enough space
- if (this.contentsOffset + actualSize >= this.contents.length) {
- resizeContents(actualSize);
- }
- this.contentsOffset += 2;
- int numberOfEntries = 0;
- for (int j = 0; j < initializationCount; j++) {
- int startPC = localVariable.initializationPCs[j << 1];
- int endPC = localVariable.initializationPCs[(j << 1) + 1];
- if (startPC != endPC) { // only entries for non zero length
- // now we can safely add the local entry
- numberOfEntries++;
- this.contents[this.contentsOffset++] = (byte) (startPC >> 8);
- this.contents[this.contentsOffset++] = (byte) startPC;
- int length = endPC - startPC;
- this.contents[this.contentsOffset++] = (byte) (length >> 8);
- this.contents[this.contentsOffset++] = (byte) length;
- int resolvedPosition = localVariable.resolvedPosition;
- this.contents[this.contentsOffset++] = (byte) (resolvedPosition >> 8);
- this.contents[this.contentsOffset++] = (byte) resolvedPosition;
- }
- }
- this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
- this.contents[localVariableTableOffset] = (byte) numberOfEntries;
- break;
- case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
- this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
- break;
- }
- }
-
-
-
- /**
- * INTERNAL USE-ONLY
- * This methods returns a char[] representing the file name of the receiver
- *
- * @return char[]
- */
- public char[] fileName() {
- return this.constantPool.UTF8Cache.returnKeyFor(2);
- }
-
- private void generateAnnotation(Annotation annotation, int currentOffset) {
- int startingContentsOffset = currentOffset;
- if (this.contentsOffset + 4 >= this.contents.length) {
- resizeContents(4);
- }
- TypeBinding annotationTypeBinding = annotation.resolvedType;
- if (annotationTypeBinding == null) {
- this.contentsOffset = startingContentsOffset;
- return;
- }
- if (annotationTypeBinding.isMemberType()) {
- this.recordInnerClasses(annotationTypeBinding);
- }
- final int typeIndex = this.constantPool.literalIndex(annotationTypeBinding.signature());
- this.contents[this.contentsOffset++] = (byte) (typeIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) typeIndex;
- if (annotation instanceof NormalAnnotation) {
- NormalAnnotation normalAnnotation = (NormalAnnotation) annotation;
- MemberValuePair[] memberValuePairs = normalAnnotation.memberValuePairs;
- int memberValuePairOffset = this.contentsOffset;
- if (memberValuePairs != null) {
- int memberValuePairsCount = 0;
- int memberValuePairsLengthPosition = this.contentsOffset;
- this.contentsOffset += 2; // leave space to fill in the pair count later
- int resetPosition = this.contentsOffset;
- final int memberValuePairsLength = memberValuePairs.length;
- loop: for (int i = 0; i < memberValuePairsLength; i++) {
- MemberValuePair memberValuePair = memberValuePairs[i];
- if (this.contentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- final int elementNameIndex = this.constantPool.literalIndex(memberValuePair.name);
- this.contents[this.contentsOffset++] = (byte) (elementNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) elementNameIndex;
- MethodBinding methodBinding = memberValuePair.binding;
- if (methodBinding == null) {
- this.contentsOffset = resetPosition;
- } else {
- try {
- generateElementValue(memberValuePair.value, methodBinding.returnType, memberValuePairOffset);
- if (this.contentsOffset == memberValuePairOffset) {
- // ignore all annotation values
- this.contents[this.contentsOffset++] = 0;
- this.contents[this.contentsOffset++] = 0;
- break loop;
- }
- memberValuePairsCount++;
- resetPosition = this.contentsOffset;
- } catch(ClassCastException | ShouldNotImplement e) {
- this.contentsOffset = resetPosition;
- }
- }
- }
- this.contents[memberValuePairsLengthPosition++] = (byte) (memberValuePairsCount >> 8);
- this.contents[memberValuePairsLengthPosition++] = (byte) memberValuePairsCount;
- } else {
- this.contents[this.contentsOffset++] = 0;
- this.contents[this.contentsOffset++] = 0;
- }
- } else if (annotation instanceof SingleMemberAnnotation) {
- SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) annotation;
- // this is a single member annotation (one member value)
- this.contents[this.contentsOffset++] = 0;
- this.contents[this.contentsOffset++] = 1;
- if (this.contentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- final int elementNameIndex = this.constantPool.literalIndex(VALUE);
- this.contents[this.contentsOffset++] = (byte) (elementNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) elementNameIndex;
- MethodBinding methodBinding = singleMemberAnnotation.memberValuePairs()[0].binding;
- if (methodBinding == null) {
- this.contentsOffset = startingContentsOffset;
- } else {
- int memberValuePairOffset = this.contentsOffset;
- try {
- generateElementValue(singleMemberAnnotation.memberValue, methodBinding.returnType, memberValuePairOffset);
- if (this.contentsOffset == memberValuePairOffset) {
- // completely remove the annotation as its value is invalid
- this.contentsOffset = startingContentsOffset;
- }
- } catch(ClassCastException | ShouldNotImplement e) {
- this.contentsOffset = startingContentsOffset;
- }
- }
- } else {
- // this is a marker annotation (no member value pairs)
- this.contents[this.contentsOffset++] = 0;
- this.contents[this.contentsOffset++] = 0;
- }
- }
-
- private int generateAnnotationDefaultAttribute(AnnotationMethodDeclaration declaration, int attributeOffset) {
- int attributesNumber = 0;
- // add an annotation default attribute
- int annotationDefaultNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.AnnotationDefaultName);
- if (this.contentsOffset + 6 >= this.contents.length) {
- resizeContents(6);
- }
- this.contents[this.contentsOffset++] = (byte) (annotationDefaultNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) annotationDefaultNameIndex;
- int attributeLengthOffset = this.contentsOffset;
- this.contentsOffset += 4;
- generateElementValue(declaration.defaultValue, declaration.binding.returnType, attributeOffset);
- if (this.contentsOffset != attributeOffset) {
- int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
- this.contents[attributeLengthOffset++] = (byte) attributeLength;
- attributesNumber++;
- }
- return attributesNumber;
- }
- /**
- * INTERNAL USE-ONLY
- * That method generates the header of a code attribute.
- * - the index inside the constant pool for the attribute name ("Code")
- * - leave some space for attribute_length(4), max_stack(2), max_locals(2), code_length(4).
- */
- public void generateCodeAttributeHeader() {
- if (this.contentsOffset + 20 >= this.contents.length) {
- resizeContents(20);
- }
- int constantValueNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.CodeName);
- this.contents[this.contentsOffset++] = (byte) (constantValueNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) constantValueNameIndex;
- // leave space for attribute_length(4), max_stack(2), max_locals(2), code_length(4)
- this.contentsOffset += 12;
- }
-
- private int generateConstantValueAttribute(Constant fieldConstant, FieldBinding fieldBinding, int fieldAttributeOffset) {
- int localContentsOffset = this.contentsOffset;
- int attributesNumber = 1;
- if (localContentsOffset + 8 >= this.contents.length) {
- resizeContents(8);
- }
- // Now we generate the constant attribute corresponding to the fieldBinding
- int constantValueNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.ConstantValueName);
- this.contents[localContentsOffset++] = (byte) (constantValueNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) constantValueNameIndex;
- // The attribute length = 2 in case of a constantValue attribute
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 2;
- // Need to add the constant_value_index
- switch (fieldConstant.typeID()) {
- case T_boolean :
- int booleanValueIndex =
- this.constantPool.literalIndex(fieldConstant.booleanValue() ? 1 : 0);
- this.contents[localContentsOffset++] = (byte) (booleanValueIndex >> 8);
- this.contents[localContentsOffset++] = (byte) booleanValueIndex;
- break;
- case T_byte :
- case T_char :
- case T_int :
- case T_short :
- int integerValueIndex =
- this.constantPool.literalIndex(fieldConstant.intValue());
- this.contents[localContentsOffset++] = (byte) (integerValueIndex >> 8);
- this.contents[localContentsOffset++] = (byte) integerValueIndex;
- break;
- case T_float :
- int floatValueIndex =
- this.constantPool.literalIndex(fieldConstant.floatValue());
- this.contents[localContentsOffset++] = (byte) (floatValueIndex >> 8);
- this.contents[localContentsOffset++] = (byte) floatValueIndex;
- break;
- case T_double :
- int doubleValueIndex =
- this.constantPool.literalIndex(fieldConstant.doubleValue());
- this.contents[localContentsOffset++] = (byte) (doubleValueIndex >> 8);
- this.contents[localContentsOffset++] = (byte) doubleValueIndex;
- break;
- case T_long :
- int longValueIndex =
- this.constantPool.literalIndex(fieldConstant.longValue());
- this.contents[localContentsOffset++] = (byte) (longValueIndex >> 8);
- this.contents[localContentsOffset++] = (byte) longValueIndex;
- break;
- case T_JavaLangString :
- int stringValueIndex =
- this.constantPool.literalIndex(
- ((StringConstant) fieldConstant).stringValue());
- if (stringValueIndex == -1) {
- if (!this.creatingProblemType) {
- // report an error and abort: will lead to a problem type classfile creation
- TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
- FieldDeclaration[] fieldDecls = typeDeclaration.fields;
- int max = fieldDecls == null ? 0 : fieldDecls.length;
- for (int i = 0; i < max; i++) {
- if (fieldDecls[i].binding == fieldBinding) {
- // problem should abort
- typeDeclaration.scope.problemReporter().stringConstantIsExceedingUtf8Limit(
- fieldDecls[i]);
- }
- }
- } else {
- // already inside a problem type creation : no constant for this field
- this.contentsOffset = fieldAttributeOffset;
- attributesNumber = 0;
- }
- } else {
- this.contents[localContentsOffset++] = (byte) (stringValueIndex >> 8);
- this.contents[localContentsOffset++] = (byte) stringValueIndex;
- }
- }
- this.contentsOffset = localContentsOffset;
- return attributesNumber;
- }
- private int generateDeprecatedAttribute() {
- int localContentsOffset = this.contentsOffset;
- if (localContentsOffset + 6 >= this.contents.length) {
- resizeContents(6);
- }
- int deprecatedAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.DeprecatedName);
- this.contents[localContentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) deprecatedAttributeNameIndex;
- // the length of a deprecated attribute is equals to 0
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contentsOffset = localContentsOffset;
- return 1;
- }
- private int generateNestHostAttribute() {
- SourceTypeBinding nestHost = this.referenceBinding.getNestHost();
- if (nestHost == null)
- return 0;
- int localContentsOffset = this.contentsOffset;
- if (localContentsOffset + 10 >= this.contents.length) {
- resizeContents(10);
- }
- int nestHostAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.NestHost);
- this.contents[localContentsOffset++] = (byte) (nestHostAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) nestHostAttributeNameIndex;
-
- // The value of the attribute_length item must be two.
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 2;
-
- int nestHostIndex = this.constantPool.literalIndexForType(nestHost.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (nestHostIndex >> 8);
- this.contents[localContentsOffset++] = (byte) nestHostIndex;
- this.contentsOffset = localContentsOffset;
- return 1;
- }
- private int generateNestMembersAttribute() {
-
- int localContentsOffset = this.contentsOffset;
- List nestedMembers = getNestMembers();
- int numberOfNestedMembers = nestedMembers != null ? nestedMembers.size() : 0;
- if (numberOfNestedMembers == 0) // JVMS 11 4.7.29 says "at most one" NestMembers attribute - return if none.
- return 0;
-
- int exSize = 8 + 2 * numberOfNestedMembers;
- if (exSize + localContentsOffset >= this.contents.length) {
- resizeContents(exSize);
- }
- int attributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.NestMembers);
- this.contents[localContentsOffset++] = (byte) (attributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) attributeNameIndex;
- int value = (numberOfNestedMembers << 1) + 2;
- this.contents[localContentsOffset++] = (byte) (value >> 24);
- this.contents[localContentsOffset++] = (byte) (value >> 16);
- this.contents[localContentsOffset++] = (byte) (value >> 8);
- this.contents[localContentsOffset++] = (byte) value;
- this.contents[localContentsOffset++] = (byte) (numberOfNestedMembers >> 8);
- this.contents[localContentsOffset++] = (byte) numberOfNestedMembers;
-
- for (int i = 0; i < numberOfNestedMembers; i++) {
- char[] nestMemberName = nestedMembers.get(i).toCharArray();
- int nestedMemberIndex = this.constantPool.literalIndexForType(nestMemberName);
- this.contents[localContentsOffset++] = (byte) (nestedMemberIndex >> 8);
- this.contents[localContentsOffset++] = (byte) nestedMemberIndex;
- }
- this.contentsOffset = localContentsOffset;
- return 1;
- }
- private int generateNestAttributes() {
- int nAttrs = generateNestMembersAttribute(); //either member or host will exist 4.7.29
- nAttrs += generateNestHostAttribute();
- return nAttrs;
- }
- private int generatePermittedTypeAttributes() {
- SourceTypeBinding type = this.referenceBinding;
- int localContentsOffset = this.contentsOffset;
- ReferenceBinding[] permittedTypes = type.permittedTypes();
- int l = permittedTypes != null ? permittedTypes.length : 0;
- if (l == 0)
- return 0;
-
- int exSize = 8 + 2 * l;
- if (exSize + localContentsOffset >= this.contents.length) {
- resizeContents(exSize);
- }
- int attributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.PermittedSubclasses);
- this.contents[localContentsOffset++] = (byte) (attributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) attributeNameIndex;
- int value = (l << 1) + 2;
- this.contents[localContentsOffset++] = (byte) (value >> 24);
- this.contents[localContentsOffset++] = (byte) (value >> 16);
- this.contents[localContentsOffset++] = (byte) (value >> 8);
- this.contents[localContentsOffset++] = (byte) value;
- this.contents[localContentsOffset++] = (byte) (l >> 8);
- this.contents[localContentsOffset++] = (byte) l;
-
- for (int i = 0; i < l; i++) {
- int permittedTypeIndex = this.constantPool.literalIndexForType(permittedTypes[i]);
- this.contents[localContentsOffset++] = (byte) (permittedTypeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) permittedTypeIndex;
- }
- this.contentsOffset = localContentsOffset;
- return 1;
- }
- private int generateRecordAttributes() {
- SourceTypeBinding record = this.referenceBinding;
- if (record == null || !record.isRecord())
- return 0;
- int localContentsOffset = this.contentsOffset;
- RecordComponentBinding[] recordComponents = this.referenceBinding.components();
- if (recordComponents == null)
- return 0;
- // could be an empty record also, account for zero components as well.
-
- int numberOfRecordComponents = recordComponents.length;
-
- int exSize = 8 + 2 * numberOfRecordComponents;
- if (exSize + localContentsOffset >= this.contents.length) {
- resizeContents(exSize);
- }
- /*
- * Record_attribute {
- * u2 attribute_name_index;
- * u4 attribute_length;
- * u2 components_count;
- * component_info components[components_count];
- * }*/
- int attributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.RecordClass);
- this.contents[localContentsOffset++] = (byte) (attributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) attributeNameIndex;
- int attrLengthOffset = localContentsOffset;
- localContentsOffset += 4;
- int base = localContentsOffset;
- this.contents[localContentsOffset++] = (byte) (numberOfRecordComponents >> 8);
- this.contents[localContentsOffset++] = (byte) numberOfRecordComponents;
- this.contentsOffset = localContentsOffset;
- for (int i = 0; i < numberOfRecordComponents; i++) {
- addComponentInfo(recordComponents[i]);
- }
- int attrLength = this.contentsOffset - base;
- this.contents[attrLengthOffset++] = (byte) (attrLength >> 24);
- this.contents[attrLengthOffset++] = (byte) (attrLength >> 16);
- this.contents[attrLengthOffset++] = (byte) (attrLength >> 8);
- this.contents[attrLengthOffset++] = (byte) attrLength;
- return 1;
- }
-
- private int generateModuleAttribute(ModuleDeclaration module) {
- ModuleBinding binding = module.binding;
- int localContentsOffset = this.contentsOffset;
- if (localContentsOffset + 10 >= this.contents.length) {
- resizeContents(10);
- }
- int moduleAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.ModuleName);
- this.contents[localContentsOffset++] = (byte) (moduleAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) moduleAttributeNameIndex;
- int attrLengthOffset = localContentsOffset;
- localContentsOffset += 4;
- int moduleNameIndex =
- this.constantPool.literalIndexForModule(binding.moduleName);
- this.contents[localContentsOffset++] = (byte) (moduleNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) moduleNameIndex;
- int flags = module.modifiers & ~(ClassFileConstants.AccModule);
- this.contents[localContentsOffset++] = (byte) (flags >> 8);
- this.contents[localContentsOffset++] = (byte) flags;
- String moduleVersion = module.getModuleVersion();
- int module_version_idx = moduleVersion == null ? 0 : this.constantPool.literalIndex(moduleVersion.toCharArray());
- this.contents[localContentsOffset++] = (byte) (module_version_idx >> 8);
- this.contents[localContentsOffset++] = (byte) module_version_idx;
- int attrLength = 6;
-
- // ================= requires section =================
- /** u2 requires_count;
- { u2 requires_index;
- u2 requires_flags;
- } requires[requires_count];
- **/
- int requiresCountOffset = localContentsOffset;
- int requiresCount = module.requiresCount;
- int requiresSize = 2 + requiresCount * 6;
- if (localContentsOffset + requiresSize >= this.contents.length) {
- resizeContents(requiresSize);
- }
-
- localContentsOffset += 2;
- ModuleBinding javaBaseBinding = null;
- for(int i = 0; i < module.requiresCount; i++) {
- RequiresStatement req = module.requires[i];
- ModuleBinding reqBinding = req.resolvedBinding;
- if (CharOperation.equals(reqBinding.moduleName, TypeConstants.JAVA_BASE)) {
- javaBaseBinding = reqBinding;
- }
- int nameIndex = this.constantPool.literalIndexForModule(reqBinding.moduleName);
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) (nameIndex);
- flags = req.modifiers;
- this.contents[localContentsOffset++] = (byte) (flags >> 8);
- this.contents[localContentsOffset++] = (byte) (flags);
- int required_version = 0;
- this.contents[localContentsOffset++] = (byte) (required_version >> 8);
- this.contents[localContentsOffset++] = (byte) (required_version);
- }
- if (!CharOperation.equals(binding.moduleName, TypeConstants.JAVA_BASE) && javaBaseBinding == null) {
- if (localContentsOffset + 6 >= this.contents.length) {
- resizeContents(6);
- }
- javaBaseBinding = binding.environment.javaBaseModule();
- int javabase_index = this.constantPool.literalIndexForModule(javaBaseBinding.moduleName);
- this.contents[localContentsOffset++] = (byte) (javabase_index >> 8);
- this.contents[localContentsOffset++] = (byte) (javabase_index);
- flags = ClassFileConstants.AccMandated;
- this.contents[localContentsOffset++] = (byte) (flags >> 8);
- this.contents[localContentsOffset++] = (byte) flags;
- int required_version = 0;
- this.contents[localContentsOffset++] = (byte) (required_version >> 8);
- this.contents[localContentsOffset++] = (byte) (required_version);
- requiresCount++;
- }
- this.contents[requiresCountOffset++] = (byte) (requiresCount >> 8);
- this.contents[requiresCountOffset++] = (byte) requiresCount;
- attrLength += 2 + 6 * requiresCount;
- // ================= end requires section =================
-
- // ================= exports section =================
- /**
- * u2 exports_count;
- * { u2 exports_index;
- * u2 exports_flags;
- * u2 exports_to_count;
- * u2 exports_to_index[exports_to_count];
- * } exports[exports_count];
- */
- int exportsSize = 2 + module.exportsCount * 6;
- if (localContentsOffset + exportsSize >= this.contents.length) {
- resizeContents(exportsSize);
- }
- this.contents[localContentsOffset++] = (byte) (module.exportsCount >> 8);
- this.contents[localContentsOffset++] = (byte) module.exportsCount;
- for (int i = 0; i < module.exportsCount; i++) {
- ExportsStatement ref = module.exports[i];
- if (localContentsOffset + 6 >= this.contents.length) {
- resizeContents((module.exportsCount - i) * 6);
- }
- int nameIndex = this.constantPool.literalIndexForPackage(CharOperation.replaceOnCopy(ref.pkgName, '.', '/'));
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) (nameIndex);
- // TODO exports_flags - check when they are set
- this.contents[localContentsOffset++] = (byte) 0;
- this.contents[localContentsOffset++] = (byte) 0;
-
- int exportsToCount = ref.isQualified() ? ref.targets.length : 0;
- this.contents[localContentsOffset++] = (byte) (exportsToCount >> 8);
- this.contents[localContentsOffset++] = (byte) (exportsToCount);
- if (exportsToCount > 0) {
- int targetSize = 2 * exportsToCount;
- if (localContentsOffset + targetSize >= this.contents.length) {
- resizeContents(targetSize);
- }
- for(int j = 0; j < exportsToCount; j++) {
- nameIndex = this.constantPool.literalIndexForModule(ref.targets[j].moduleName);
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) (nameIndex);
- }
- attrLength += targetSize;
- }
- }
- attrLength += exportsSize;
- // ================= end exports section =================
-
- // ================= opens section =================
- /**
- * u2 opens_count;
- * { u2 opens_index;
- * u2 opens_flags;
- * u2 opens_to_count;
- * u2 opens_to_index[opens_to_count];
- * } exports[exports_count];
- */
- int opensSize = 2 + module.opensCount * 6;
- if (localContentsOffset + opensSize >= this.contents.length) {
- resizeContents(opensSize);
- }
- this.contents[localContentsOffset++] = (byte) (module.opensCount >> 8);
- this.contents[localContentsOffset++] = (byte) module.opensCount;
- for (int i = 0; i < module.opensCount; i++) {
- OpensStatement ref = module.opens[i];
- if (localContentsOffset + 6 >= this.contents.length) {
- resizeContents((module.opensCount - i) * 6);
- }
- int nameIndex = this.constantPool.literalIndexForPackage(CharOperation.replaceOnCopy(ref.pkgName, '.', '/'));
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) (nameIndex);
- // TODO opens_flags - check when they are set
- this.contents[localContentsOffset++] = (byte) 0;
- this.contents[localContentsOffset++] = (byte) 0;
-
- int opensToCount = ref.isQualified() ? ref.targets.length : 0;
- this.contents[localContentsOffset++] = (byte) (opensToCount >> 8);
- this.contents[localContentsOffset++] = (byte) (opensToCount);
- if (opensToCount > 0) {
- int targetSize = 2 * opensToCount;
- if (localContentsOffset + targetSize >= this.contents.length) {
- resizeContents(targetSize);
- }
- for(int j = 0; j < opensToCount; j++) {
- nameIndex = this.constantPool.literalIndexForModule(ref.targets[j].moduleName);
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) (nameIndex);
- }
- attrLength += targetSize;
- }
- }
- attrLength += opensSize;
- // ================= end opens section =================
-
- // ================= uses section =================
- /**
- * u2 uses_count;
- * u2 uses_index[uses_count];
- */
- int usesSize = 2 + 2 * module.usesCount;
- if (localContentsOffset + usesSize >= this.contents.length) {
- resizeContents(usesSize);
- }
- this.contents[localContentsOffset++] = (byte) (module.usesCount >> 8);
- this.contents[localContentsOffset++] = (byte) module.usesCount;
- for(int i = 0; i < module.usesCount; i++) {
- int nameIndex = this.constantPool.literalIndexForType(module.uses[i].serviceInterface.resolvedType.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) (nameIndex);
- }
- attrLength += usesSize;
- // ================= end uses section =================
-
- // ================= provides section =================
- /**
- * u2 provides_count;
- * {
- * u2 provides_index;
- * u2 provides_with_count;
- * u2 provides_with_index[provides_with_count];
- * } provides[provides_count];
- */
- int servicesSize = 2 + 4 * module.servicesCount;
- if (localContentsOffset + servicesSize >= this.contents.length) {
- resizeContents(servicesSize);
- }
- this.contents[localContentsOffset++] = (byte) (module.servicesCount >> 8);
- this.contents[localContentsOffset++] = (byte) module.servicesCount;
- for(int i = 0; i < module.servicesCount; i++) {
- if (localContentsOffset + 4 >= this.contents.length) {
- resizeContents((module.servicesCount - i) * 4);
- }
- int nameIndex = this.constantPool.literalIndexForType(module.services[i].serviceInterface.resolvedType.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) (nameIndex);
- TypeReference[] impls = module.services[i].implementations;
- int implLength = impls.length;
- this.contents[localContentsOffset++] = (byte) (implLength >> 8);
- this.contents[localContentsOffset++] = (byte) implLength;
- int targetSize = implLength * 2;
- if (localContentsOffset + targetSize >= this.contents.length) {
- resizeContents(targetSize);
- }
- for (int j = 0; j < implLength; j++) {
- nameIndex = this.constantPool.literalIndexForType(impls[j].resolvedType.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) (nameIndex);
- }
- attrLength += targetSize;
- }
- attrLength += servicesSize;
- // ================= end provides section =================
-
- this.contents[attrLengthOffset++] = (byte)(attrLength >> 24);
- this.contents[attrLengthOffset++] = (byte)(attrLength >> 16);
- this.contents[attrLengthOffset++] = (byte)(attrLength >> 8);
- this.contents[attrLengthOffset++] = (byte)attrLength;
- this.contentsOffset = localContentsOffset;
- return 1;
- }
-
- private int generateModuleMainClassAttribute(char[] moduleMainClass) {
- int localContentsOffset = this.contentsOffset;
- if (localContentsOffset + 8 >= this.contents.length) {
- resizeContents(8);
- }
- int moduleAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.ModuleMainClass);
- this.contents[localContentsOffset++] = (byte) (moduleAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) moduleAttributeNameIndex;
- int attrLength = 2;
- this.contents[localContentsOffset++] = (byte)(attrLength >> 24);
- this.contents[localContentsOffset++] = (byte)(attrLength >> 16);
- this.contents[localContentsOffset++] = (byte)(attrLength >> 8);
- this.contents[localContentsOffset++] = (byte)attrLength;
- int moduleNameIndex = this.constantPool.literalIndexForType(moduleMainClass);
- this.contents[localContentsOffset++] = (byte) (moduleNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) moduleNameIndex;
- this.contentsOffset = localContentsOffset;
- return 1;
- }
-
- private int generateModulePackagesAttribute(char[][] packageNames) {
- int localContentsOffset = this.contentsOffset;
- int maxSize = 6 + 2*packageNames.length;
- if (localContentsOffset + maxSize >= this.contents.length) {
- resizeContents(maxSize);
- }
- int moduleAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.ModulePackages);
- this.contents[localContentsOffset++] = (byte) (moduleAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) moduleAttributeNameIndex;
-
- int attrLengthOffset = localContentsOffset;
- localContentsOffset+= 4;
- int packageCountOffset = localContentsOffset;
- localContentsOffset+= 2;
-
- int packagesCount = 0;
- for (char[] packageName : packageNames) {
- if (packageName == null || packageName.length == 0) continue;
- int packageNameIndex = this.constantPool.literalIndexForPackage(packageName);
- this.contents[localContentsOffset++] = (byte) (packageNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) packageNameIndex;
- packagesCount++;
- }
-
- this.contents[packageCountOffset++] = (byte)(packagesCount >> 8);
- this.contents[packageCountOffset++] = (byte)packagesCount;
- int attrLength = 2 + 2 * packagesCount;
- this.contents[attrLengthOffset++] = (byte)(attrLength >> 24);
- this.contents[attrLengthOffset++] = (byte)(attrLength >> 16);
- this.contents[attrLengthOffset++] = (byte)(attrLength >> 8);
- this.contents[attrLengthOffset++] = (byte)attrLength;
- this.contentsOffset = localContentsOffset;
- return 1;
- }
-
- private void generateElementValue(
- Expression defaultValue,
- TypeBinding memberValuePairReturnType,
- int attributeOffset) {
- Constant constant = defaultValue.constant;
- TypeBinding defaultValueBinding = defaultValue.resolvedType;
- if (defaultValueBinding == null) {
- this.contentsOffset = attributeOffset;
- } else {
- if (defaultValueBinding.isMemberType()) {
- this.recordInnerClasses(defaultValueBinding);
- }
- if (memberValuePairReturnType.isMemberType()) {
- this.recordInnerClasses(memberValuePairReturnType);
- }
- if (memberValuePairReturnType.isArrayType() && !defaultValueBinding.isArrayType()) {
- // automatic wrapping
- if (this.contentsOffset + 3 >= this.contents.length) {
- resizeContents(3);
- }
- this.contents[this.contentsOffset++] = (byte) '[';
- this.contents[this.contentsOffset++] = (byte) 0;
- this.contents[this.contentsOffset++] = (byte) 1;
- }
- if (constant != null && constant != Constant.NotAConstant) {
- generateElementValue(attributeOffset, defaultValue, constant, memberValuePairReturnType.leafComponentType());
- } else {
- generateElementValueForNonConstantExpression(defaultValue, attributeOffset, defaultValueBinding);
- }
- }
- }
- private void generateElementValue(int attributeOffset, Expression defaultValue, Constant constant, TypeBinding binding) {
- if (this.contentsOffset + 3 >= this.contents.length) {
- resizeContents(3);
- }
- switch (binding.id) {
- case T_boolean :
- this.contents[this.contentsOffset++] = (byte) 'Z';
- int booleanValueIndex =
- this.constantPool.literalIndex(constant.booleanValue() ? 1 : 0);
- this.contents[this.contentsOffset++] = (byte) (booleanValueIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) booleanValueIndex;
- break;
- case T_byte :
- this.contents[this.contentsOffset++] = (byte) 'B';
- int integerValueIndex =
- this.constantPool.literalIndex(constant.intValue());
- this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) integerValueIndex;
- break;
- case T_char :
- this.contents[this.contentsOffset++] = (byte) 'C';
- integerValueIndex =
- this.constantPool.literalIndex(constant.intValue());
- this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) integerValueIndex;
- break;
- case T_int :
- this.contents[this.contentsOffset++] = (byte) 'I';
- integerValueIndex =
- this.constantPool.literalIndex(constant.intValue());
- this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) integerValueIndex;
- break;
- case T_short :
- this.contents[this.contentsOffset++] = (byte) 'S';
- integerValueIndex =
- this.constantPool.literalIndex(constant.intValue());
- this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) integerValueIndex;
- break;
- case T_float :
- this.contents[this.contentsOffset++] = (byte) 'F';
- int floatValueIndex =
- this.constantPool.literalIndex(constant.floatValue());
- this.contents[this.contentsOffset++] = (byte) (floatValueIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) floatValueIndex;
- break;
- case T_double :
- this.contents[this.contentsOffset++] = (byte) 'D';
- int doubleValueIndex =
- this.constantPool.literalIndex(constant.doubleValue());
- this.contents[this.contentsOffset++] = (byte) (doubleValueIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) doubleValueIndex;
- break;
- case T_long :
- this.contents[this.contentsOffset++] = (byte) 'J';
- int longValueIndex =
- this.constantPool.literalIndex(constant.longValue());
- this.contents[this.contentsOffset++] = (byte) (longValueIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) longValueIndex;
- break;
- case T_JavaLangString :
- this.contents[this.contentsOffset++] = (byte) 's';
- int stringValueIndex =
- this.constantPool.literalIndex(((StringConstant) constant).stringValue().toCharArray());
- if (stringValueIndex == -1) {
- if (!this.creatingProblemType) {
- // report an error and abort: will lead to a problem type classfile creation
- TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
- typeDeclaration.scope.problemReporter().stringConstantIsExceedingUtf8Limit(defaultValue);
- } else {
- // already inside a problem type creation : no attribute
- this.contentsOffset = attributeOffset;
- }
- } else {
- this.contents[this.contentsOffset++] = (byte) (stringValueIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) stringValueIndex;
- }
- }
- }
-
- private void generateElementValueForNonConstantExpression(Expression defaultValue, int attributeOffset, TypeBinding defaultValueBinding) {
- if (defaultValueBinding != null) {
- if (defaultValueBinding.isEnum()) {
- if (this.contentsOffset + 5 >= this.contents.length) {
- resizeContents(5);
- }
- this.contents[this.contentsOffset++] = (byte) 'e';
- FieldBinding fieldBinding = null;
- if (defaultValue instanceof QualifiedNameReference) {
- QualifiedNameReference nameReference = (QualifiedNameReference) defaultValue;
- fieldBinding = (FieldBinding) nameReference.binding;
- } else if (defaultValue instanceof SingleNameReference) {
- SingleNameReference nameReference = (SingleNameReference) defaultValue;
- fieldBinding = (FieldBinding) nameReference.binding;
- } else {
- this.contentsOffset = attributeOffset;
- }
- if (fieldBinding != null) {
- final int enumConstantTypeNameIndex = this.constantPool.literalIndex(fieldBinding.type.signature());
- final int enumConstantNameIndex = this.constantPool.literalIndex(fieldBinding.name);
- this.contents[this.contentsOffset++] = (byte) (enumConstantTypeNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) enumConstantTypeNameIndex;
- this.contents[this.contentsOffset++] = (byte) (enumConstantNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) enumConstantNameIndex;
- }
- } else if (defaultValueBinding.isAnnotationType()) {
- if (this.contentsOffset + 1 >= this.contents.length) {
- resizeContents(1);
- }
- this.contents[this.contentsOffset++] = (byte) '@';
- generateAnnotation((Annotation) defaultValue, attributeOffset);
- } else if (defaultValueBinding.isArrayType()) {
- // array type
- if (this.contentsOffset + 3 >= this.contents.length) {
- resizeContents(3);
- }
- this.contents[this.contentsOffset++] = (byte) '[';
- if (defaultValue instanceof ArrayInitializer) {
- ArrayInitializer arrayInitializer = (ArrayInitializer) defaultValue;
- int arrayLength = arrayInitializer.expressions != null ? arrayInitializer.expressions.length : 0;
- this.contents[this.contentsOffset++] = (byte) (arrayLength >> 8);
- this.contents[this.contentsOffset++] = (byte) arrayLength;
- for (int i = 0; i < arrayLength; i++) {
- generateElementValue(arrayInitializer.expressions[i], defaultValueBinding.leafComponentType(), attributeOffset);
- }
- } else {
- this.contentsOffset = attributeOffset;
- }
- } else {
- // class type
- if (this.contentsOffset + 3 >= this.contents.length) {
- resizeContents(3);
- }
- this.contents[this.contentsOffset++] = (byte) 'c';
- if (defaultValue instanceof ClassLiteralAccess) {
- ClassLiteralAccess classLiteralAccess = (ClassLiteralAccess) defaultValue;
- final int classInfoIndex = this.constantPool.literalIndex(classLiteralAccess.targetType.signature());
- this.contents[this.contentsOffset++] = (byte) (classInfoIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) classInfoIndex;
- } else {
- this.contentsOffset = attributeOffset;
- }
- }
- } else {
- this.contentsOffset = attributeOffset;
- }
- }
-
- private int generateEnclosingMethodAttribute() {
- int localContentsOffset = this.contentsOffset;
- // add enclosing method attribute (1.5 mode only)
- if (localContentsOffset + 10 >= this.contents.length) {
- resizeContents(10);
- }
- int enclosingMethodAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.EnclosingMethodName);
- this.contents[localContentsOffset++] = (byte) (enclosingMethodAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) enclosingMethodAttributeNameIndex;
- // the length of a signature attribute is equals to 2
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 4;
-
- int enclosingTypeIndex = this.constantPool.literalIndexForType(this.referenceBinding.enclosingType().constantPoolName());
- this.contents[localContentsOffset++] = (byte) (enclosingTypeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) enclosingTypeIndex;
- byte methodIndexByte1 = 0;
- byte methodIndexByte2 = 0;
- if (this.referenceBinding instanceof LocalTypeBinding) {
- MethodBinding methodBinding = ((LocalTypeBinding) this.referenceBinding).enclosingMethod;
- if (methodBinding != null) {
- int enclosingMethodIndex = this.constantPool.literalIndexForNameAndType(methodBinding.selector, methodBinding.signature(this));
- methodIndexByte1 = (byte) (enclosingMethodIndex >> 8);
- methodIndexByte2 = (byte) enclosingMethodIndex;
- }
- }
- this.contents[localContentsOffset++] = methodIndexByte1;
- this.contents[localContentsOffset++] = methodIndexByte2;
- this.contentsOffset = localContentsOffset;
- return 1;
- }
- private int generateExceptionsAttribute(ReferenceBinding[] thrownsExceptions) {
- int localContentsOffset = this.contentsOffset;
- int length = thrownsExceptions.length;
- int exSize = 8 + length * 2;
- if (exSize + this.contentsOffset >= this.contents.length) {
- resizeContents(exSize);
- }
- int exceptionNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.ExceptionsName);
- this.contents[localContentsOffset++] = (byte) (exceptionNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) exceptionNameIndex;
- // The attribute length = length * 2 + 2 in case of a exception attribute
- int attributeLength = length * 2 + 2;
- this.contents[localContentsOffset++] = (byte) (attributeLength >> 24);
- this.contents[localContentsOffset++] = (byte) (attributeLength >> 16);
- this.contents[localContentsOffset++] = (byte) (attributeLength >> 8);
- this.contents[localContentsOffset++] = (byte) attributeLength;
- this.contents[localContentsOffset++] = (byte) (length >> 8);
- this.contents[localContentsOffset++] = (byte) length;
- for (int i = 0; i < length; i++) {
- int exceptionIndex = this.constantPool.literalIndexForType(thrownsExceptions[i]);
- this.contents[localContentsOffset++] = (byte) (exceptionIndex >> 8);
- this.contents[localContentsOffset++] = (byte) exceptionIndex;
- }
- this.contentsOffset = localContentsOffset;
- return 1;
- }
- private int generateHierarchyInconsistentAttribute() {
- int localContentsOffset = this.contentsOffset;
- // add an attribute for inconsistent hierarchy
- if (localContentsOffset + 6 >= this.contents.length) {
- resizeContents(6);
- }
- int inconsistentHierarchyNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.InconsistentHierarchy);
- this.contents[localContentsOffset++] = (byte) (inconsistentHierarchyNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) inconsistentHierarchyNameIndex;
- // the length of an inconsistent hierarchy attribute is equals to 0
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contentsOffset = localContentsOffset;
- return 1;
- }
- private int generateInnerClassAttribute(int numberOfInnerClasses, ReferenceBinding[] innerClasses) {
- int localContentsOffset = this.contentsOffset;
- // Generate the inner class attribute
- int exSize = 8 * numberOfInnerClasses + 8;
- if (exSize + localContentsOffset >= this.contents.length) {
- resizeContents(exSize);
- }
- // Now we now the size of the attribute and the number of entries
- // attribute name
- int attributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.InnerClassName);
- this.contents[localContentsOffset++] = (byte) (attributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) attributeNameIndex;
- int value = (numberOfInnerClasses << 3) + 2;
- this.contents[localContentsOffset++] = (byte) (value >> 24);
- this.contents[localContentsOffset++] = (byte) (value >> 16);
- this.contents[localContentsOffset++] = (byte) (value >> 8);
- this.contents[localContentsOffset++] = (byte) value;
- this.contents[localContentsOffset++] = (byte) (numberOfInnerClasses >> 8);
- this.contents[localContentsOffset++] = (byte) numberOfInnerClasses;
- for (int i = 0; i < numberOfInnerClasses; i++) {
- ReferenceBinding innerClass = innerClasses[i];
- int accessFlags = innerClass.getAccessFlags();
- int innerClassIndex = this.constantPool.literalIndexForType(innerClass.constantPoolName());
- // inner class index
- this.contents[localContentsOffset++] = (byte) (innerClassIndex >> 8);
- this.contents[localContentsOffset++] = (byte) innerClassIndex;
- // outer class index: anonymous and local have no outer class index
- if (innerClass.isMemberType()) {
- // member or member of local
- int outerClassIndex = this.constantPool.literalIndexForType(innerClass.enclosingType().constantPoolName());
- this.contents[localContentsOffset++] = (byte) (outerClassIndex >> 8);
- this.contents[localContentsOffset++] = (byte) outerClassIndex;
- } else {
- // equals to 0 if the innerClass is not a member type
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- }
- // name index
- if (!innerClass.isAnonymousType()) {
- int nameIndex = this.constantPool.literalIndex(innerClass.sourceName());
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) nameIndex;
- } else {
- // equals to 0 if the innerClass is an anonymous type
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- }
- // access flag
- if (innerClass.isAnonymousType()) {
- ReferenceBinding superClass = innerClass.superclass();
- if (superClass == null || !(superClass.isEnum() && superClass.isSealed()))
- accessFlags &= ~ClassFileConstants.AccFinal;
- } else if (innerClass.isMemberType() && innerClass.isInterface()) {
- accessFlags |= ClassFileConstants.AccStatic; // implicitely static
- }
- this.contents[localContentsOffset++] = (byte) (accessFlags >> 8);
- this.contents[localContentsOffset++] = (byte) accessFlags;
- }
- this.contentsOffset = localContentsOffset;
- return 1;
- }
-
- private Map createInitBootStrapMethodsMap() {
- Map fPtr = new HashMap<>(ClassFile.BOOTSTRAP_METHODS.length);
- for (String key : ClassFile.BOOTSTRAP_METHODS) {
- fPtr.put(key, 0);
- }
- return fPtr;
- }
- private int generateBootstrapMethods(List bootStrapMethodsList) {
- /* See JVM spec 4.7.21
- The BootstrapMethods attribute has the following format:
- BootstrapMethods_attribute {
- u2 attribute_name_index;
- u4 attribute_length;
- u2 num_bootstrap_methods;
- { u2 bootstrap_method_ref;
- u2 num_bootstrap_arguments;
- u2 bootstrap_arguments[num_bootstrap_arguments];
- } bootstrap_methods[num_bootstrap_methods];
- }
- */
- // Record inner classes for MethodHandles$Lookup
- ReferenceBinding methodHandlesLookup = this.referenceBinding.scope.getJavaLangInvokeMethodHandlesLookup();
- if (methodHandlesLookup == null) return 0; // skip bootstrap section, class path problem already reported, just avoid NPE.
- recordInnerClasses(methodHandlesLookup); // Should be done, it's what javac does also
-
- int numberOfBootstraps = bootStrapMethodsList != null ? bootStrapMethodsList.size() : 0;
- int localContentsOffset = this.contentsOffset;
- // Generate the boot strap attribute - since we are only making lambdas and
- // functional expressions, we know the size ahead of time - this less general
- // than the full invokedynamic scope, but fine for Java 8
-
- final int contentsEntries = 10;
- int exSize = contentsEntries * numberOfBootstraps + 8;
- if (exSize + localContentsOffset >= this.contents.length) {
- resizeContents(exSize);
- }
-
- int attributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.BootstrapMethodsName);
- this.contents[localContentsOffset++] = (byte) (attributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) attributeNameIndex;
- // leave space for attribute_length and remember where to insert it
- int attributeLengthPosition = localContentsOffset;
- localContentsOffset += 4;
-
- this.contents[localContentsOffset++] = (byte) (numberOfBootstraps >> 8);
- this.contents[localContentsOffset++] = (byte) numberOfBootstraps;
-
- Map fPtr = createInitBootStrapMethodsMap();
- for (int i = 0; i < numberOfBootstraps; i++) {
- Object o = this.bootstrapMethods.get(i);
- if (o instanceof FunctionalExpression) {
- localContentsOffset = addBootStrapLambdaEntry(localContentsOffset, (FunctionalExpression) o, fPtr);
- } else if (o instanceof TypeDeclaration) {
- localContentsOffset = addBootStrapRecordEntry(localContentsOffset, (TypeDeclaration) o, fPtr);
- } else if (o instanceof SwitchStatement) {
- SwitchStatement stmt = (SwitchStatement) o;
- if (stmt.expression.resolvedType.isEnum()) {
- localContentsOffset = addBootStrapEnumSwitchEntry(localContentsOffset, stmt, fPtr);
- } else {
- localContentsOffset = addBootStrapTypeSwitchEntry(localContentsOffset, stmt, fPtr);
- }
- } else if (o instanceof String) {
- localContentsOffset = addBootStrapStringConcatEntry(localContentsOffset, (String) o, fPtr);
- } else if (o instanceof ResolvedCase) {
- localContentsOffset = addBootStrapTypeCaseConstantEntry(localContentsOffset, (ResolvedCase) o, fPtr);
- } else if (o instanceof TypeBinding) {
- localContentsOffset = addClassDescBootstrap(localContentsOffset, (TypeBinding) o, fPtr);
- } else if (o instanceof StringTemplate template) {
- localContentsOffset = addBootStrapTemplateRuntimeEntry(localContentsOffset, template, fPtr);
- }
- }
-
- int attributeLength = localContentsOffset - attributeLengthPosition - 4;
- this.contents[attributeLengthPosition++] = (byte) (attributeLength >> 24);
- this.contents[attributeLengthPosition++] = (byte) (attributeLength >> 16);
- this.contents[attributeLengthPosition++] = (byte) (attributeLength >> 8);
- this.contents[attributeLengthPosition++] = (byte) attributeLength;
- this.contentsOffset = localContentsOffset;
- return 1;
- }
-
- private int addBootStrapLambdaEntry(int localContentsOffset, FunctionalExpression functional, Map fPtr) {
- MethodBinding [] bridges = functional.getRequiredBridges();
- TypeBinding[] markerInterfaces = null;
- final int contentsEntries = 10;
- int indexForAltMetaFactory = fPtr.get(ClassFile.ALTMETAFACTORY_STRING);
- int indexForMetaFactory = fPtr.get(ClassFile.METAFACTORY_STRING);
- if ((functional instanceof LambdaExpression
- && (((markerInterfaces = ((LambdaExpression) functional).getMarkerInterfaces()) != null))
- || bridges != null) || functional.isSerializable) {
- // may need even more space
- int extraSpace = 2; // at least 2 more than when the normal metafactory is used, for the bitflags entry
- if (markerInterfaces != null) {
- // 2 for the marker interface list size then 2 per marker interface index
- extraSpace += (2 + 2 * markerInterfaces.length);
- }
- if (bridges != null) {
- // 2 for bridge count then 2 per bridge method type.
- extraSpace += (2 + 2 * bridges.length);
- }
- if (extraSpace + contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(extraSpace + contentsEntries);
- }
-
- if (indexForAltMetaFactory == 0) {
- ReferenceBinding javaLangInvokeLambdaMetafactory = this.referenceBinding.scope.getJavaLangInvokeLambdaMetafactory();
- indexForAltMetaFactory =
- this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory,
- ConstantPool.ALTMETAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_ALTMETAFACTORY_SIGNATURE, false);
- fPtr.put(ClassFile.ALTMETAFACTORY_STRING, indexForAltMetaFactory);
- }
- this.contents[localContentsOffset++] = (byte) (indexForAltMetaFactory >> 8);
- this.contents[localContentsOffset++] = (byte) indexForAltMetaFactory;
-
- // u2 num_bootstrap_arguments
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) (4 + (markerInterfaces==null?0:1+markerInterfaces.length) +
- (bridges == null ? 0 : 1 + bridges.length));
-
- int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
- this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
- this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
-
- int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
- this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodHandleIndex;
-
- char [] instantiatedSignature = functional.descriptor.signature();
- int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
- this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodTypeIndex;
-
- int bitflags = 0;
- if (functional.isSerializable) {
- bitflags |= ClassFileConstants.FLAG_SERIALIZABLE;
- }
- if (markerInterfaces!=null) {
- bitflags |= ClassFileConstants.FLAG_MARKERS;
- }
- if (bridges != null) {
- bitflags |= ClassFileConstants.FLAG_BRIDGES;
- }
- int indexForBitflags = this.constantPool.literalIndex(bitflags);
-
- this.contents[localContentsOffset++] = (byte)(indexForBitflags>>8);
- this.contents[localContentsOffset++] = (byte)(indexForBitflags);
-
- if (markerInterfaces != null) {
- int markerInterfaceCountIndex = this.constantPool.literalIndex(markerInterfaces.length);
- this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex>>8);
- this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex);
- for (int m = 0, maxm = markerInterfaces.length; m < maxm; m++) {
- int classTypeIndex = this.constantPool.literalIndexForType(markerInterfaces[m]);
- this.contents[localContentsOffset++] = (byte)(classTypeIndex>>8);
- this.contents[localContentsOffset++] = (byte)(classTypeIndex);
- }
- }
- if (bridges != null) {
- int bridgeCountIndex = this.constantPool.literalIndex(bridges.length);
- this.contents[localContentsOffset++] = (byte) (bridgeCountIndex >> 8);
- this.contents[localContentsOffset++] = (byte) (bridgeCountIndex);
- for (int m = 0, maxm = bridges.length; m < maxm; m++) {
- char [] bridgeSignature = bridges[m].signature();
- int bridgeMethodTypeIndex = this.constantPool.literalIndexForMethodType(bridgeSignature);
- this.contents[localContentsOffset++] = (byte) (bridgeMethodTypeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) bridgeMethodTypeIndex;
- }
- }
- } else {
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- if (indexForMetaFactory == 0) {
- ReferenceBinding javaLangInvokeLambdaMetafactory = this.referenceBinding.scope.getJavaLangInvokeLambdaMetafactory();
- indexForMetaFactory = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory,
- ConstantPool.METAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_METAFACTORY_SIGNATURE, false);
- fPtr.put(ClassFile.METAFACTORY_STRING, indexForMetaFactory);
- }
- this.contents[localContentsOffset++] = (byte) (indexForMetaFactory >> 8);
- this.contents[localContentsOffset++] = (byte) indexForMetaFactory;
-
- // u2 num_bootstrap_arguments
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) 3;
-
- int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
- this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
- this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
-
- int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding instanceof PolymorphicMethodBinding ? functional.binding : functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
- this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodHandleIndex;
-
- char [] instantiatedSignature = functional.descriptor.signature();
- int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
- this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodTypeIndex;
- }
- return localContentsOffset;
- }
-
- private int addBootStrapRecordEntry(int localContentsOffset, TypeDeclaration typeDecl, Map fPtr) {
- TypeBinding type = typeDecl.binding;
- assert type.isRecord(); // sanity check
- final int contentsEntries = 10;
- int indexForObjectMethodBootStrap = fPtr.get(ClassFile.BOOTSTRAP_STRING);
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- if (indexForObjectMethodBootStrap == 0) {
- ReferenceBinding javaLangRuntimeObjectMethods = this.referenceBinding.scope.getJavaLangRuntimeObjectMethods();
- indexForObjectMethodBootStrap = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangRuntimeObjectMethods,
- ConstantPool.BOOTSTRAP, ConstantPool.JAVA_LANG_RUNTIME_OBJECTMETHOD_BOOTSTRAP_SIGNATURE, false);
- fPtr.put(ClassFile.BOOTSTRAP_STRING, indexForObjectMethodBootStrap);
- }
- this.contents[localContentsOffset++] = (byte) (indexForObjectMethodBootStrap >> 8);
- this.contents[localContentsOffset++] = (byte) indexForObjectMethodBootStrap;
-
- // u2 num_bootstrap_arguments
- int numArgsLocation = localContentsOffset;
- localContentsOffset += 2;
-
- char[] recordName = type.constantPoolName();
- int recordIndex = this.constantPool.literalIndexForType(recordName);
- this.contents[localContentsOffset++] = (byte) (recordIndex >> 8);
- this.contents[localContentsOffset++] = (byte) recordIndex;
-
- assert type instanceof SourceTypeBinding;
- SourceTypeBinding sourceType = (SourceTypeBinding) type;
- FieldBinding[] recordComponents = sourceType.getImplicitComponentFields();
-
- int numArgs = 2 + recordComponents.length;
- this.contents[numArgsLocation++] = (byte) (numArgs >> 8);
- this.contents[numArgsLocation] = (byte) numArgs;
-
- String names =
- Arrays.stream(recordComponents)
- .map(f -> new String(f.name))
- .reduce((s1, s2) -> (s1 + ";" + s2)) //$NON-NLS-1$
- .orElse(Util.EMPTY_STRING);
- int namesIndex = this.constantPool.literalIndex(names);
- this.contents[localContentsOffset++] = (byte) (namesIndex >> 8);
- this.contents[localContentsOffset++] = (byte) namesIndex;
-
- if (recordComponents.length * 2 + localContentsOffset >= this.contents.length) {
- resizeContents(recordComponents.length * 2);
- }
- for (FieldBinding field : recordComponents) {
- int methodHandleIndex = this.constantPool.literalIndexForMethodHandleFieldRef(
- ClassFileConstants.MethodHandleRefKindGetField,
- recordName, field.name, field.type.signature());
-
- this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodHandleIndex;
- }
- return localContentsOffset;
- }
- private int addBootStrapTypeCaseConstantEntry(int localContentsOffset, ResolvedCase caseConstant, Map fPtr) {
- final int contentsEntries = 10;
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- int idx = fPtr.get(ClassFile.INVOKE_STRING);
- if (idx == 0) {
- ReferenceBinding constantBootstrap = this.referenceBinding.scope.getJavaLangInvokeConstantBootstraps();
- idx = this.constantPool.literalIndexForMethodHandle(
- ClassFileConstants.MethodHandleRefKindInvokeStatic,
- constantBootstrap,
- ConstantPool.INVOKE_METHOD_METHOD_NAME,
- ConstantPool.JAVA_LANG_INVOKE_CONSTANTBOOTSTRAP_SIGNATURE,
- false);
- fPtr.put(ClassFile.INVOKE_STRING, idx);
- }
- this.contents[localContentsOffset++] = (byte) (idx >> 8);
- this.contents[localContentsOffset++] = (byte) idx;
-
- // u2 num_bootstrap_arguments
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) 3;
-
- idx = fPtr.get(ClassFile.ENUMDESC_OF);
- if (idx == 0) {
- ReferenceBinding enumDesc = this.referenceBinding.scope.getJavaLangEnumDesc();
- idx = this.constantPool.literalIndexForMethodHandle(
- ClassFileConstants.MethodHandleRefKindInvokeStatic,
- enumDesc,
- "of".toCharArray(), //$NON-NLS-1$
- ConstantPool.JAVA_LANG_ENUMDESC_OF_SIGNATURE,
- false);
- fPtr.put(ClassFile.ENUMDESC_OF, idx);
- }
-
- this.contents[localContentsOffset++] = (byte) (idx >> 8);
- this.contents[localContentsOffset++] = (byte) idx;
-
- idx = this.constantPool.literalIndexForDynamic(
- caseConstant.classDescIdx,
- ConstantPool.INVOKE_METHOD_METHOD_NAME,
- ConstantPool.JAVA_LANG_CONST_CLASSDESC);
- this.contents[localContentsOffset++] = (byte) (idx >> 8);
- this.contents[localContentsOffset++] = (byte) idx;
-
- idx = this.constantPool.literalIndex(caseConstant.c.stringValue());
- this.contents[localContentsOffset++] = (byte) (idx >> 8);
- this.contents[localContentsOffset++] = (byte) idx;
-
- return localContentsOffset;
- }
- private int addClassDescBootstrap(int localContentsOffset, TypeBinding type, Map fPtr) {
- final int contentsEntries = 10;
- int idx = fPtr.get(ClassFile.INVOKE_STRING);
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- if (idx == 0) {
- ReferenceBinding constantBootstrap = this.referenceBinding.scope.getJavaLangInvokeConstantBootstraps();
- idx = this.constantPool.literalIndexForMethodHandle(
- ClassFileConstants.MethodHandleRefKindInvokeStatic,
- constantBootstrap,
- ConstantPool.INVOKE_METHOD_METHOD_NAME,
- ConstantPool.JAVA_LANG_INVOKE_CONSTANTBOOTSTRAP_SIGNATURE,
- false);
- fPtr.put(ClassFile.INVOKE_STRING, idx);
- }
- this.contents[localContentsOffset++] = (byte) (idx >> 8);
- this.contents[localContentsOffset++] = (byte) idx;
-
- // u2 num_bootstrap_arguments
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) 2;
-
- idx = fPtr.get(ClassFile.CLASSDESC);
- if (idx == 0) {
- ReferenceBinding classDesc = this.referenceBinding.scope.getJavaLangClassDesc();
- idx = this.constantPool.literalIndexForMethodHandle(
- ClassFileConstants.MethodHandleRefKindInvokeStatic,
- classDesc,
- "of".toCharArray(), //$NON-NLS-1$
- ConstantPool.JAVA_LANG_CLASSDESC_OF_SIGNATURE,
- true);
- fPtr.put(ClassFile.CLASSDESC_OF, idx);
- }
-
- this.contents[localContentsOffset++] = (byte) (idx >> 8);
- this.contents[localContentsOffset++] = (byte) idx;
-
- ReferenceBinding refBinding = (ReferenceBinding) type;
- idx = this.constantPool.literalIndex(CharOperation.toString(refBinding.compoundName));
- this.contents[localContentsOffset++] = (byte) (idx >> 8);
- this.contents[localContentsOffset++] = (byte) idx;
-
- return localContentsOffset;
- }
- private int addBootStrapTypeSwitchEntry(int localContentsOffset, SwitchStatement switchStatement, Map fPtr) {
- CaseStatement.ResolvedCase[] constants = switchStatement.otherConstants;
- int numArgs = constants.length;
- final int contentsEntries = 10 + (numArgs * 2);
- int indexFortypeSwitch = fPtr.get(ClassFile.TYPESWITCH_STRING);
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- if (indexFortypeSwitch == 0) {
- ReferenceBinding javaLangRuntimeSwitchBootstraps = this.referenceBinding.scope.getJavaLangRuntimeSwitchBootstraps();
- indexFortypeSwitch = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangRuntimeSwitchBootstraps,
- ConstantPool.TYPESWITCH, ConstantPool.JAVA_LANG_RUNTIME_SWITCHBOOTSTRAPS_SWITCH_SIGNATURE, false);
- fPtr.put(ClassFile.TYPESWITCH_STRING, indexFortypeSwitch);
- }
- this.contents[localContentsOffset++] = (byte) (indexFortypeSwitch >> 8);
- this.contents[localContentsOffset++] = (byte) indexFortypeSwitch;
-
- // u2 num_bootstrap_arguments
- int numArgsLocation = localContentsOffset;
- if (switchStatement.containsNull) --numArgs;
- this.contents[numArgsLocation++] = (byte) (numArgs >> 8);
- this.contents[numArgsLocation] = (byte) numArgs;
- localContentsOffset += 2;
- for (CaseStatement.ResolvedCase c : constants) {
- if (c.isPattern()) {
- char[] typeName = c.t.constantPoolName();
- int typeIndex = this.constantPool.literalIndexForType(typeName);
- this.contents[localContentsOffset++] = (byte) (typeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) typeIndex;
- } else if (c.isQualifiedEnum()){
- int typeIndex = this.constantPool.literalIndexForDynamic(c.enumDescIdx,
- ConstantPool.INVOKE_METHOD_METHOD_NAME,
- ConstantPool.JAVA_LANG_ENUM_ENUMDESC);
- this.contents[localContentsOffset++] = (byte) (typeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) typeIndex;
- } else if ((c.e instanceof StringLiteral)||(c.c instanceof StringConstant)) {
- int intValIdx =
- this.constantPool.literalIndex(c.c.stringValue());
- this.contents[localContentsOffset++] = (byte) (intValIdx >> 8);
- this.contents[localContentsOffset++] = (byte) intValIdx;
- } else {
- if (c.e instanceof NullLiteral) continue;
- int intValIdx =
- this.constantPool.literalIndex(c.intValue());
- this.contents[localContentsOffset++] = (byte) (intValIdx >> 8);
- this.contents[localContentsOffset++] = (byte) intValIdx;
- }
- }
-
- return localContentsOffset;
- }
- private int addBootStrapEnumSwitchEntry(int localContentsOffset, SwitchStatement switchStatement, Map fPtr) {
- final int contentsEntries = 10;
- int indexForenumSwitch = fPtr.get(ClassFile.ENUMSWITCH_STRING);
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- if (indexForenumSwitch == 0) {
- ReferenceBinding javaLangRuntimeSwitchBootstraps = this.referenceBinding.scope.getJavaLangRuntimeSwitchBootstraps();
- indexForenumSwitch = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangRuntimeSwitchBootstraps,
- ConstantPool.ENUMSWITCH, ConstantPool.JAVA_LANG_RUNTIME_SWITCHBOOTSTRAPS_SWITCH_SIGNATURE, false);
- fPtr.put(ClassFile.ENUMSWITCH_STRING, indexForenumSwitch);
- }
- this.contents[localContentsOffset++] = (byte) (indexForenumSwitch >> 8);
- this.contents[localContentsOffset++] = (byte) indexForenumSwitch;
-
- // u2 num_bootstrap_arguments
- int numArgsLocation = localContentsOffset;
- CaseStatement.ResolvedCase[] constants = switchStatement.otherConstants;
- int numArgs = constants.length;
- if (switchStatement.containsNull) --numArgs;
- this.contents[numArgsLocation++] = (byte) (numArgs >> 8);
- this.contents[numArgsLocation] = (byte) numArgs;
- localContentsOffset += 2;
-
- for (CaseStatement.ResolvedCase c : constants) {
- if (c.isPattern()) {
- char[] typeName = switchStatement.expression.resolvedType.constantPoolName();
- int typeIndex = this.constantPool.literalIndexForType(typeName);
- this.contents[localContentsOffset++] = (byte) (typeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) typeIndex;
- } else {
- if (c.e instanceof NullLiteral) continue;
- String s = c.e instanceof QualifiedNameReference qnr ? // handle superfluously qualified enumerator.
- new String(qnr.tokens[qnr.tokens.length-1]) : c.e.toString();
- int intValIdx =
- this.constantPool.literalIndex(s);
- this.contents[localContentsOffset++] = (byte) (intValIdx >> 8);
- this.contents[localContentsOffset++] = (byte) intValIdx;
- }
- }
-
- return localContentsOffset;
- }
- private int addBootStrapStringConcatEntry(int localContentsOffset, String recipe, Map fPtr) {
- final int contentsEntries = 10;
- int indexForStringConcat = fPtr.get(ClassFile.CONCAT_CONSTANTS);
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- if (indexForStringConcat == 0) {
- ReferenceBinding stringConcatBootstrap = this.referenceBinding.scope.getJavaLangInvokeStringConcatFactory();
- indexForStringConcat = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, stringConcatBootstrap,
- ConstantPool.ConcatWithConstants, ConstantPool.JAVA_LANG_INVOKE_STRING_CONCAT_FACTORY_SIGNATURE, false);
- fPtr.put(ClassFile.CONCAT_CONSTANTS, indexForStringConcat);
- }
- this.contents[localContentsOffset++] = (byte) (indexForStringConcat >> 8);
- this.contents[localContentsOffset++] = (byte) indexForStringConcat;
-
- // u2 num_bootstrap_arguments
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) 1;
-
- int intValIdx =
- this.constantPool.literalIndex(recipe);
- this.contents[localContentsOffset++] = (byte) (intValIdx >> 8);
- this.contents[localContentsOffset++] = (byte) intValIdx;
-
- return localContentsOffset;
- }
- private int addBootStrapTemplateRuntimeEntry(int localContentsOffset, StringTemplate template, Map fPtr) {
- final int contentsEntries = 10;
- int indexForProcess = fPtr.get(NEW_STRING_TEMPLATE);
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- if (indexForProcess == 0) {
- ReferenceBinding javaLangRuntimeTemplateBootstraps = this.referenceBinding.scope.getJavaLangRuntimeTemplateRuntimeBootstraps();
- indexForProcess = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangRuntimeTemplateBootstraps,
- NEW_STRING_TEMPLATE.toCharArray(), ConstantPool.JAVA_LANG_RUNTIME_STRING_TEMPLATE_SIGNATURE, false);
- fPtr.put(NEW_STRING_TEMPLATE, indexForProcess);
- }
- this.contents[localContentsOffset++] = (byte) (indexForProcess >> 8);
- this.contents[localContentsOffset++] = (byte) indexForProcess;
-
- // u2 num_bootstrap_arguments
- int numArgsLocation = localContentsOffset;
- StringLiteral[] fragments = template.fragments();
- int numArgs = fragments.length;
- this.contents[numArgsLocation++] = (byte) (numArgs >> 8);
- this.contents[numArgsLocation] = (byte) numArgs;
- localContentsOffset += 2;
-
- if ((numArgs * 2) + localContentsOffset >= this.contents.length) {
- resizeContents(numArgs * 2);
- }
- for (StringLiteral frag : fragments) {
- int intValIdx =
- this.constantPool.literalIndex(frag.constant.stringValue());
- this.contents[localContentsOffset++] = (byte) (intValIdx >> 8);
- this.contents[localContentsOffset++] = (byte) intValIdx;
- }
- return localContentsOffset;
- }
- private int generateLineNumberAttribute() {
- int localContentsOffset = this.contentsOffset;
- int attributesNumber = 0;
- /* Create and add the line number attribute (used for debugging)
- * Build the pairs of:
- * (bytecodePC lineNumber)
- * according to the table of start line indexes and the pcToSourceMap table
- * contained into the codestream
- */
- int[] pcToSourceMapTable;
- if (((pcToSourceMapTable = this.codeStream.pcToSourceMap) != null)
- && (this.codeStream.pcToSourceMapSize != 0)) {
- int lineNumberNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
- if (localContentsOffset + 8 >= this.contents.length) {
- resizeContents(8);
- }
- this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
- int lineNumberTableOffset = localContentsOffset;
- localContentsOffset += 6;
- // leave space for attribute_length and line_number_table_length
- int numberOfEntries = 0;
- int length = this.codeStream.pcToSourceMapSize;
- for (int i = 0; i < length;) {
- // write the entry
- if (localContentsOffset + 4 >= this.contents.length) {
- resizeContents(4);
- }
- int pc = pcToSourceMapTable[i++];
- this.contents[localContentsOffset++] = (byte) (pc >> 8);
- this.contents[localContentsOffset++] = (byte) pc;
- int lineNumber = pcToSourceMapTable[i++];
- this.contents[localContentsOffset++] = (byte) (lineNumber >> 8);
- this.contents[localContentsOffset++] = (byte) lineNumber;
- numberOfEntries++;
- }
- // now we change the size of the line number attribute
- int lineNumberAttr_length = numberOfEntries * 4 + 2;
- this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24);
- this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16);
- this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8);
- this.contents[lineNumberTableOffset++] = (byte) lineNumberAttr_length;
- this.contents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8);
- this.contents[lineNumberTableOffset++] = (byte) numberOfEntries;
- attributesNumber = 1;
- }
- this.contentsOffset = localContentsOffset;
- return attributesNumber;
- }
- // this is used for problem and synthetic methods
- private int generateLineNumberAttribute(int problemLine) {
- int localContentsOffset = this.contentsOffset;
- if (localContentsOffset + 12 >= this.contents.length) {
- resizeContents(12);
- }
- /* Create and add the line number attribute (used for debugging)
- * Build the pairs of:
- * (bytecodePC lineNumber)
- * according to the table of start line indexes and the pcToSourceMap table
- * contained into the codestream
- */
- int lineNumberNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
- this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 6;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 1;
- // first entry at pc = 0
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) (problemLine >> 8);
- this.contents[localContentsOffset++] = (byte) problemLine;
- // now we change the size of the line number attribute
- this.contentsOffset = localContentsOffset;
- return 1;
- }
-
- private int generateLocalVariableTableAttribute(int code_length, boolean methodDeclarationIsStatic, boolean isSynthetic) {
- int attributesNumber = 0;
- int localContentsOffset = this.contentsOffset;
- int numberOfEntries = 0;
- int localVariableNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
- int maxOfEntries = 8 + 10 * (methodDeclarationIsStatic ? 0 : 1);
- for (int i = 0; i < this.codeStream.allLocalsCounter; i++) {
- LocalVariableBinding localVariableBinding = this.codeStream.locals[i];
- maxOfEntries += 10 * localVariableBinding.initializationCount;
- }
- // reserve enough space
- if (localContentsOffset + maxOfEntries >= this.contents.length) {
- resizeContents(maxOfEntries);
- }
- this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) localVariableNameIndex;
- int localVariableTableOffset = localContentsOffset;
- // leave space for attribute_length and local_variable_table_length
- localContentsOffset += 6;
- int nameIndex;
- int descriptorIndex;
- SourceTypeBinding declaringClassBinding = null;
- if (!methodDeclarationIsStatic && !isSynthetic) {
- numberOfEntries++;
- this.contents[localContentsOffset++] = 0; // the startPC for this is always 0
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) (code_length >> 8);
- this.contents[localContentsOffset++] = (byte) code_length;
- nameIndex = this.constantPool.literalIndex(ConstantPool.This);
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) nameIndex;
- declaringClassBinding = (SourceTypeBinding)
- (this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.binding.declaringClass : this.codeStream.lambdaExpression.binding.declaringClass);
- descriptorIndex =
- this.constantPool.literalIndex(
- declaringClassBinding.signature());
- this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
- this.contents[localContentsOffset++] = (byte) descriptorIndex;
- this.contents[localContentsOffset++] = 0;// the resolved position for this is always 0
- this.contents[localContentsOffset++] = 0;
- }
- // used to remember the local variable with a generic type
- int genericLocalVariablesCounter = 0;
- LocalVariableBinding[] genericLocalVariables = null;
- int numberOfGenericEntries = 0;
-
- for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
- LocalVariableBinding localVariable = this.codeStream.locals[i];
- int initializationCount = localVariable.initializationCount;
- if (initializationCount == 0) continue;
- if (localVariable.declaration == null) continue;
- final TypeBinding localVariableTypeBinding = localVariable.type;
- boolean isParameterizedType = localVariableTypeBinding.isParameterizedType() || localVariableTypeBinding.isTypeVariable();
- if (isParameterizedType) {
- if (genericLocalVariables == null) {
- // we cannot have more than max locals
- genericLocalVariables = new LocalVariableBinding[max];
- }
- genericLocalVariables[genericLocalVariablesCounter++] = localVariable;
- }
- for (int j = 0; j < initializationCount; j++) {
- int startPC = localVariable.initializationPCs[j << 1];
- int endPC = localVariable.initializationPCs[(j << 1) + 1];
- if (startPC != endPC) { // only entries for non zero length
- if (endPC == -1) {
- localVariable.declaringScope.problemReporter().abortDueToInternalError(
- Messages.bind(Messages.abort_invalidAttribute, new String(localVariable.name)),
- (ASTNode) localVariable.declaringScope.methodScope().referenceContext);
- }
- if (isParameterizedType) {
- numberOfGenericEntries++;
- }
- // now we can safely add the local entry
- numberOfEntries++;
- this.contents[localContentsOffset++] = (byte) (startPC >> 8);
- this.contents[localContentsOffset++] = (byte) startPC;
- int length = endPC - startPC;
- this.contents[localContentsOffset++] = (byte) (length >> 8);
- this.contents[localContentsOffset++] = (byte) length;
- nameIndex = this.constantPool.literalIndex(localVariable.name);
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) nameIndex;
- descriptorIndex = this.constantPool.literalIndex(localVariableTypeBinding.signature());
- this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
- this.contents[localContentsOffset++] = (byte) descriptorIndex;
- int resolvedPosition = localVariable.resolvedPosition;
- this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
- this.contents[localContentsOffset++] = (byte) resolvedPosition;
- }
- }
- }
- int value = numberOfEntries * 10 + 2;
- this.contents[localVariableTableOffset++] = (byte) (value >> 24);
- this.contents[localVariableTableOffset++] = (byte) (value >> 16);
- this.contents[localVariableTableOffset++] = (byte) (value >> 8);
- this.contents[localVariableTableOffset++] = (byte) value;
- this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
- this.contents[localVariableTableOffset] = (byte) numberOfEntries;
- attributesNumber++;
-
- final boolean currentInstanceIsGeneric =
- !methodDeclarationIsStatic
- && declaringClassBinding != null
- && declaringClassBinding.typeVariables != Binding.NO_TYPE_VARIABLES;
- if (genericLocalVariablesCounter != 0 || currentInstanceIsGeneric) {
- // add the local variable type table attribute
- numberOfGenericEntries += (currentInstanceIsGeneric ? 1 : 0);
- maxOfEntries = 8 + numberOfGenericEntries * 10;
- // reserve enough space
- if (localContentsOffset + maxOfEntries >= this.contents.length) {
- resizeContents(maxOfEntries);
- }
- int localVariableTypeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTypeTableName);
- this.contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) localVariableTypeNameIndex;
- value = numberOfGenericEntries * 10 + 2;
- this.contents[localContentsOffset++] = (byte) (value >> 24);
- this.contents[localContentsOffset++] = (byte) (value >> 16);
- this.contents[localContentsOffset++] = (byte) (value >> 8);
- this.contents[localContentsOffset++] = (byte) value;
- this.contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8);
- this.contents[localContentsOffset++] = (byte) numberOfGenericEntries;
- if (currentInstanceIsGeneric) {
- this.contents[localContentsOffset++] = 0; // the startPC for this is always 0
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) (code_length >> 8);
- this.contents[localContentsOffset++] = (byte) code_length;
- nameIndex = this.constantPool.literalIndex(ConstantPool.This);
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) nameIndex;
- descriptorIndex = this.constantPool.literalIndex(declaringClassBinding.genericTypeSignature());
- this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
- this.contents[localContentsOffset++] = (byte) descriptorIndex;
- this.contents[localContentsOffset++] = 0;// the resolved position for this is always 0
- this.contents[localContentsOffset++] = 0;
- }
-
- for (int i = 0; i < genericLocalVariablesCounter; i++) {
- LocalVariableBinding localVariable = genericLocalVariables[i];
- for (int j = 0; j < localVariable.initializationCount; j++) {
- int startPC = localVariable.initializationPCs[j << 1];
- int endPC = localVariable.initializationPCs[(j << 1) + 1];
- if (startPC != endPC) {
- // only entries for non zero length
- // now we can safely add the local entry
- this.contents[localContentsOffset++] = (byte) (startPC >> 8);
- this.contents[localContentsOffset++] = (byte) startPC;
- int length = endPC - startPC;
- this.contents[localContentsOffset++] = (byte) (length >> 8);
- this.contents[localContentsOffset++] = (byte) length;
- nameIndex = this.constantPool.literalIndex(localVariable.name);
- this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) nameIndex;
- descriptorIndex = this.constantPool.literalIndex(localVariable.type.genericTypeSignature());
- this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
- this.contents[localContentsOffset++] = (byte) descriptorIndex;
- int resolvedPosition = localVariable.resolvedPosition;
- this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
- this.contents[localContentsOffset++] = (byte) resolvedPosition;
- }
- }
- }
- attributesNumber++;
- }
- this.contentsOffset = localContentsOffset;
- return attributesNumber;
- }
- /**
- * INTERNAL USE-ONLY
- * That method generates the attributes of a code attribute.
- * They could be:
- * - an exception attribute for each try/catch found inside the method
- * - a deprecated attribute
- * - a synthetic attribute for synthetic access methods
- *
- * It returns the number of attributes created for the code attribute.
- *
- * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
- * @return int
- */
- public int generateMethodInfoAttributes(MethodBinding methodBinding) {
- // leave two bytes for the attribute_number
- this.contentsOffset += 2;
- if (this.contentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- // now we can handle all the attribute for that method info:
- // it could be:
- // - a CodeAttribute
- // - a ExceptionAttribute
- // - a DeprecatedAttribute
- // - a SyntheticAttribute
-
- // Exception attribute
- ReferenceBinding[] thrownsExceptions;
- int attributesNumber = 0;
- if ((thrownsExceptions = methodBinding.thrownExceptions) != Binding.NO_EXCEPTIONS) {
- // The method has a throw clause. So we need to add an exception attribute
- // check that there is enough space to write all the bytes for the exception attribute
- attributesNumber += generateExceptionsAttribute(thrownsExceptions);
- }
- if (methodBinding.isDeprecated()) {
- // Deprecated attribute
- attributesNumber += generateDeprecatedAttribute();
- }
- if (this.targetJDK < ClassFileConstants.JDK1_5) {
- if (methodBinding.isSynthetic()) {
- attributesNumber += generateSyntheticAttribute();
- }
- if (methodBinding.isVarargs()) {
- attributesNumber += generateVarargsAttribute();
- }
- }
- // add signature attribute
- char[] genericSignature = methodBinding.genericSignature();
- if (genericSignature != null) {
- attributesNumber += generateSignatureAttribute(genericSignature);
- }
- if (this.targetJDK >= ClassFileConstants.JDK1_4) {
- AbstractMethodDeclaration methodDeclaration = methodBinding.sourceMethod();
- if (methodBinding instanceof SyntheticMethodBinding) {
- SyntheticMethodBinding syntheticMethod = (SyntheticMethodBinding) methodBinding;
- if (syntheticMethod.purpose == SyntheticMethodBinding.SuperMethodAccess && CharOperation.equals(syntheticMethod.selector, syntheticMethod.targetMethod.selector))
- methodDeclaration = ((SyntheticMethodBinding)methodBinding).targetMethod.sourceMethod();
- if (syntheticMethod.recordComponentBinding != null) {
- assert methodDeclaration == null;
- long rcMask = TagBits.AnnotationForMethod | TagBits.AnnotationForTypeUse;
- // record component (field) accessor method
- ReferenceBinding declaringClass = methodBinding.declaringClass;
- RecordComponent comp = getRecordComponent(declaringClass, methodBinding.selector);
- if (comp != null) {
- Annotation[] annotations = ASTNode.getRelevantAnnotations(comp.annotations, rcMask, null);
- if (annotations != null) {
- assert !methodBinding.isConstructor();
- attributesNumber += generateRuntimeAnnotations(annotations, TagBits.AnnotationForMethod);
- }
- if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
- List allTypeAnnotationContexts = new ArrayList<>();
- if (annotations != null && (comp.bits & ASTNode.HasTypeAnnotations) != 0) {
- comp.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
- }
- TypeReference compType = comp.type;
- if (compType != null && ((compType.bits & ASTNode.HasTypeAnnotations) != 0)) {
- compType.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
- }
- int size = allTypeAnnotationContexts.size();
- attributesNumber = completeRuntimeTypeAnnotations(attributesNumber,
- null,
- node -> size > 0,
- () -> allTypeAnnotationContexts);
- }
- }
- }
- }
- if (methodDeclaration != null) {
- Annotation[] annotations = methodDeclaration.annotations;
- if (annotations != null) {
- attributesNumber += generateRuntimeAnnotations(annotations, methodBinding.isConstructor() ? TagBits.AnnotationForConstructor : TagBits.AnnotationForMethod);
- }
- if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
- Argument[] arguments = methodDeclaration.arguments;
- if (arguments != null) {
- propagateRecordComponentArguments(methodDeclaration);
- attributesNumber += generateRuntimeAnnotationsForParameters(arguments);
- }
- }
- } else {
- LambdaExpression lambda = methodBinding.sourceLambda();
- if (lambda != null) {
- if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
- Argument[] arguments = lambda.arguments();
- if (arguments != null) {
- int parameterCount = methodBinding.parameters.length;
- int argumentCount = arguments.length;
- if (parameterCount > argumentCount) { // synthetics prefixed
- int redShift = parameterCount - argumentCount;
- System.arraycopy(arguments, 0, arguments = new Argument[parameterCount], redShift, argumentCount);
- for (int i = 0; i < redShift; i++)
- arguments[i] = new Argument(CharOperation.NO_CHAR, 0, null, 0);
- }
- attributesNumber += generateRuntimeAnnotationsForParameters(arguments);
- }
- }
- }
- }
- }
- if ((methodBinding.tagBits & TagBits.HasMissingType) != 0) {
- this.missingTypes = methodBinding.collectMissingTypes(this.missingTypes);
- }
- return attributesNumber;
- }
- private int completeRuntimeTypeAnnotations(int attributesNumber,
- ASTNode node,
- Predicate condition,
- Supplier> supplier) {
- int invisibleTypeAnnotationsCounter = 0;
- int visibleTypeAnnotationsCounter = 0;
- if (condition.test(node)) {
- List allTypeAnnotationContexts = supplier.get();
- if (allTypeAnnotationContexts.size() > 0) {
- AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[allTypeAnnotationContexts.size()];
- allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
- for (int j = 0, max2 = allTypeAnnotationContextsArray.length; j < max2; j++) {
- AnnotationContext annotationContext = allTypeAnnotationContextsArray[j];
- if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
- invisibleTypeAnnotationsCounter++;
- } else {
- visibleTypeAnnotationsCounter++;
- }
- }
- attributesNumber += generateRuntimeTypeAnnotations(
- allTypeAnnotationContextsArray,
- visibleTypeAnnotationsCounter,
- invisibleTypeAnnotationsCounter);
- }
- }
- return attributesNumber;
- }
- private void propagateRecordComponentArguments(AbstractMethodDeclaration methodDeclaration) {
- if ((methodDeclaration.bits & (ASTNode.IsCanonicalConstructor | ASTNode.IsImplicit)) == 0)
- return;
- ReferenceBinding declaringClass = methodDeclaration.binding.declaringClass;
- if (declaringClass instanceof SourceTypeBinding) {
- assert declaringClass.isRecord();
- RecordComponentBinding[] rcbs = ((SourceTypeBinding) declaringClass).components();
- Argument[] arguments = methodDeclaration.arguments;
- for (int i = 0, length = rcbs.length; i < length; i++) {
- RecordComponentBinding rcb = rcbs[i];
- RecordComponent recordComponent = rcb.sourceRecordComponent();
- if ((recordComponent.bits & ASTNode.HasTypeAnnotations) != 0) {
- methodDeclaration.bits |= ASTNode.HasTypeAnnotations;
- arguments[i].bits |= ASTNode.HasTypeAnnotations;
- }
- long rcMask = TagBits.AnnotationForParameter | TagBits.AnnotationForTypeUse;
- arguments[i].annotations = ASTNode.getRelevantAnnotations(recordComponent.annotations, rcMask, null);
- }
- }
- }
-
- public int generateMethodInfoAttributes(MethodBinding methodBinding, AnnotationMethodDeclaration declaration) {
- int attributesNumber = generateMethodInfoAttributes(methodBinding);
- int attributeOffset = this.contentsOffset;
- if ((declaration.modifiers & ClassFileConstants.AccAnnotationDefault) != 0) {
- // add an annotation default attribute
- attributesNumber += generateAnnotationDefaultAttribute(declaration, attributeOffset);
- }
- return attributesNumber;
- }
- /**
- * INTERNAL USE-ONLY
- * That method generates the header of a method info:
- * The header consists in:
- * - the access flags
- * - the name index of the method name inside the constant pool
- * - the descriptor index of the signature of the method inside the constant pool.
- *
- * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
- */
- public void generateMethodInfoHeader(MethodBinding methodBinding) {
- generateMethodInfoHeader(methodBinding, methodBinding.modifiers);
- }
-
- /**
- * INTERNAL USE-ONLY
- * That method generates the header of a method info:
- * The header consists in:
- * - the access flags
- * - the name index of the method name inside the constant pool
- * - the descriptor index of the signature of the method inside the constant pool.
- *
- * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
- * @param accessFlags the access flags
- */
- public void generateMethodInfoHeader(MethodBinding methodBinding, int accessFlags) {
- // check that there is enough space to write all the bytes for the method info corresponding
- // to the @methodBinding
- this.methodCount++; // add one more method
- if (this.contentsOffset + 10 >= this.contents.length) {
- resizeContents(10);
- }
- if (this.targetJDK < ClassFileConstants.JDK1_5) {
- // pre 1.5, synthetic is an attribute, not a modifier
- // pre 1.5, varargs is an attribute, not a modifier (-target jsr14 mode)
- accessFlags &= ~(ClassFileConstants.AccSynthetic | ClassFileConstants.AccVarargs);
- }
- if ((methodBinding.tagBits & TagBits.ClearPrivateModifier) != 0) {
- accessFlags &= ~ClassFileConstants.AccPrivate;
- }
- if (this.targetJDK >= ClassFileConstants.JDK17) {
- accessFlags &= ~(ClassFileConstants.AccStrictfp);
- }
- this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
- this.contents[this.contentsOffset++] = (byte) accessFlags;
- int nameIndex = this.constantPool.literalIndex(methodBinding.selector);
- this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) nameIndex;
- int descriptorIndex = this.constantPool.literalIndex(methodBinding.signature(this));
- this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) descriptorIndex;
- }
-
- public void addSyntheticDeserializeLambda(SyntheticMethodBinding methodBinding, SyntheticMethodBinding[] syntheticMethodBindings ) {
- generateMethodInfoHeader(methodBinding);
- int methodAttributeOffset = this.contentsOffset;
- // this will add exception attribute, synthetic attribute, deprecated attribute,...
- int attributeNumber = generateMethodInfoAttributes(methodBinding);
- // Code attribute
- int codeAttributeOffset = this.contentsOffset;
- attributeNumber++; // add code attribute
- generateCodeAttributeHeader();
- this.codeStream.init(this);
- this.codeStream.generateSyntheticBodyForDeserializeLambda(methodBinding, syntheticMethodBindings);
- int code_length = this.codeStream.position;
- if (code_length > 65535) {
- this.referenceBinding.scope.problemReporter().bytecodeExceeds64KLimit(
- methodBinding, this.referenceBinding.sourceStart(), this.referenceBinding.sourceEnd());
- }
- completeCodeAttributeForSyntheticMethod(
- methodBinding,
- codeAttributeOffset,
- ((SourceTypeBinding) methodBinding.declaringClass)
- .scope
- .referenceCompilationUnit()
- .compilationResult
- .getLineSeparatorPositions());
- this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
- this.contents[methodAttributeOffset] = (byte) attributeNumber;
- }
-
- /**
- * INTERNAL USE-ONLY
- * That method generates the method info header of a clinit:
- * The header consists in:
- * - the access flags (always default access + static)
- * - the name index of the method name (always {@code }) inside the constant pool
- * - the descriptor index of the signature (always ()V) of the method inside the constant pool.
- */
- public void generateMethodInfoHeaderForClinit() {
- // check that there is enough space to write all the bytes for the method info corresponding
- // to the @methodBinding
- this.methodCount++; // add one more method
- if (this.contentsOffset + 10 >= this.contents.length) {
- resizeContents(10);
- }
- this.contents[this.contentsOffset++] = (byte) ((ClassFileConstants.AccDefault | ClassFileConstants.AccStatic) >> 8);
- this.contents[this.contentsOffset++] = (byte) (ClassFileConstants.AccDefault | ClassFileConstants.AccStatic);
- int nameIndex = this.constantPool.literalIndex(ConstantPool.Clinit);
- this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) nameIndex;
- int descriptorIndex =
- this.constantPool.literalIndex(ConstantPool.ClinitSignature);
- this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) descriptorIndex;
- // We know that we won't get more than 1 attribute: the code attribute
- this.contents[this.contentsOffset++] = 0;
- this.contents[this.contentsOffset++] = 1;
- }
-
- /**
- * INTERNAL USE-ONLY
- * Generate the byte for problem method infos that correspond to missing abstract methods.
- * http://dev.eclipse.org/bugs/show_bug.cgi?id=3179
- *
- * @param methodDeclarations Array of all missing abstract methods
- */
- public void generateMissingAbstractMethods(MethodDeclaration[] methodDeclarations, CompilationResult compilationResult) {
- if (methodDeclarations != null) {
- TypeDeclaration currentDeclaration = this.referenceBinding.scope.referenceContext;
- int typeDeclarationSourceStart = currentDeclaration.sourceStart();
- int typeDeclarationSourceEnd = currentDeclaration.sourceEnd();
- for (int i = 0, max = methodDeclarations.length; i < max; i++) {
- MethodDeclaration methodDeclaration = methodDeclarations[i];
- MethodBinding methodBinding = methodDeclaration.binding;
- String readableName = new String(methodBinding.readableName());
- CategorizedProblem[] problems = compilationResult.problems;
- int problemsCount = compilationResult.problemCount;
- for (int j = 0; j < problemsCount; j++) {
- CategorizedProblem problem = problems[j];
- if (problem != null
- && problem.getID() == IProblem.AbstractMethodMustBeImplemented
- && problem.getMessage().indexOf(readableName) != -1
- && problem.getSourceStart() >= typeDeclarationSourceStart
- && problem.getSourceEnd() <= typeDeclarationSourceEnd) {
- // we found a match
- addMissingAbstractProblemMethod(methodDeclaration, methodBinding, problem, compilationResult);
- }
- }
- }
- }
- }
-
- private void generateMissingTypesAttribute() {
- int initialSize = this.missingTypes.size();
- int[] missingTypesIndexes = new int[initialSize];
- int numberOfMissingTypes = 0;
- if (initialSize > 1) {
- Collections.sort(this.missingTypes, new Comparator() {
- @Override
- public int compare(TypeBinding o1, TypeBinding o2) {
- return CharOperation.compareTo(o1.constantPoolName(), o2.constantPoolName());
- }
- });
- }
- int previousIndex = 0;
- next: for (int i = 0; i < initialSize; i++) {
- int missingTypeIndex = this.constantPool.literalIndexForType(this.missingTypes.get(i));
- if (previousIndex == missingTypeIndex) {
- continue next;
- }
- previousIndex = missingTypeIndex;
- missingTypesIndexes[numberOfMissingTypes++] = missingTypeIndex;
- }
- // we don't need to resize as we interate from 0 to numberOfMissingTypes when recording the indexes in the .class file
- int attributeLength = numberOfMissingTypes * 2 + 2;
- if (this.contentsOffset + attributeLength + 6 >= this.contents.length) {
- resizeContents(attributeLength + 6);
- }
- int missingTypesNameIndex = this.constantPool.literalIndex(AttributeNamesConstants.MissingTypesName);
- this.contents[this.contentsOffset++] = (byte) (missingTypesNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) missingTypesNameIndex;
-
- // generate attribute length
- this.contents[this.contentsOffset++] = (byte) (attributeLength >> 24);
- this.contents[this.contentsOffset++] = (byte) (attributeLength >> 16);
- this.contents[this.contentsOffset++] = (byte) (attributeLength >> 8);
- this.contents[this.contentsOffset++] = (byte) attributeLength;
-
- // generate number of missing types
- this.contents[this.contentsOffset++] = (byte) (numberOfMissingTypes >> 8);
- this.contents[this.contentsOffset++] = (byte) numberOfMissingTypes;
- // generate entry for each missing type
- for (int i = 0; i < numberOfMissingTypes; i++) {
- int missingTypeIndex = missingTypesIndexes[i];
- this.contents[this.contentsOffset++] = (byte) (missingTypeIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) missingTypeIndex;
- }
- }
-
- private boolean jdk16packageInfoAnnotation(final long annotationMask, final long targetMask) {
- if (this.targetJDK <= ClassFileConstants.JDK1_6 &&
- targetMask == TagBits.AnnotationForPackage && annotationMask != 0 &&
- (annotationMask & TagBits.AnnotationForPackage) == 0) {
- return true;
- }
- return false;
- }
- /**
- * @param targetMask allowed targets
- * @return the number of attributes created while dumping the annotations in the .class file
- */
- private int generateRuntimeAnnotations(final Annotation[] annotations, final long targetMask) {
- int attributesNumber = 0;
- final int length = annotations.length;
- int visibleAnnotationsCounter = 0;
- int invisibleAnnotationsCounter = 0;
- for (int i = 0; i < length; i++) {
- Annotation annotation;
- if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
- long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
- if (annotationMask != 0 && (annotationMask & targetMask) == 0) {
- if (!jdk16packageInfoAnnotation(annotationMask, targetMask)) continue;
- }
- if (annotation.isRuntimeInvisible()) {
- invisibleAnnotationsCounter++;
- } else if (annotation.isRuntimeVisible()) {
- visibleAnnotationsCounter++;
- }
- }
-
- int annotationAttributeOffset = this.contentsOffset;
- if (invisibleAnnotationsCounter != 0) {
- if (this.contentsOffset + 10 >= this.contents.length) {
- resizeContents(10);
- }
- int runtimeInvisibleAnnotationsAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleAnnotationsName);
- this.contents[this.contentsOffset++] = (byte) (runtimeInvisibleAnnotationsAttributeNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) runtimeInvisibleAnnotationsAttributeNameIndex;
- int attributeLengthOffset = this.contentsOffset;
- this.contentsOffset += 4; // leave space for the attribute length
-
- int annotationsLengthOffset = this.contentsOffset;
- this.contentsOffset += 2; // leave space for the annotations length
-
- int counter = 0;
- loop: for (int i = 0; i < length; i++) {
- if (invisibleAnnotationsCounter == 0) break loop;
- Annotation annotation;
- if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
- long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
- if (annotationMask != 0 && (annotationMask & targetMask) == 0) {
- if (!jdk16packageInfoAnnotation(annotationMask, targetMask)) continue;
- }
- if (annotation.isRuntimeInvisible()) {
- int currentAnnotationOffset = this.contentsOffset;
- generateAnnotation(annotation, currentAnnotationOffset);
- invisibleAnnotationsCounter--;
- if (this.contentsOffset != currentAnnotationOffset) {
- counter++;
- }
- }
- }
- if (counter != 0) {
- this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
- this.contents[annotationsLengthOffset++] = (byte) counter;
-
- int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
- this.contents[attributeLengthOffset++] = (byte) attributeLength;
- attributesNumber++;
- } else {
- this.contentsOffset = annotationAttributeOffset;
- }
- }
-
- annotationAttributeOffset = this.contentsOffset;
- if (visibleAnnotationsCounter != 0) {
- if (this.contentsOffset + 10 >= this.contents.length) {
- resizeContents(10);
- }
- int runtimeVisibleAnnotationsAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleAnnotationsName);
- this.contents[this.contentsOffset++] = (byte) (runtimeVisibleAnnotationsAttributeNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) runtimeVisibleAnnotationsAttributeNameIndex;
- int attributeLengthOffset = this.contentsOffset;
- this.contentsOffset += 4; // leave space for the attribute length
-
- int annotationsLengthOffset = this.contentsOffset;
- this.contentsOffset += 2; // leave space for the annotations length
-
- int counter = 0;
- loop: for (int i = 0; i < length; i++) {
- if (visibleAnnotationsCounter == 0) break loop;
- Annotation annotation;
- if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
- long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
- if (annotationMask != 0 && (annotationMask & targetMask) == 0) {
- if (!jdk16packageInfoAnnotation(annotationMask, targetMask)) continue;
- }
- if (annotation.isRuntimeVisible()) {
- visibleAnnotationsCounter--;
- int currentAnnotationOffset = this.contentsOffset;
- generateAnnotation(annotation, currentAnnotationOffset);
- if (this.contentsOffset != currentAnnotationOffset) {
- counter++;
- }
- }
- }
- if (counter != 0) {
- this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
- this.contents[annotationsLengthOffset++] = (byte) counter;
-
- int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
- this.contents[attributeLengthOffset++] = (byte) attributeLength;
- attributesNumber++;
- } else {
- this.contentsOffset = annotationAttributeOffset;
- }
- }
- return attributesNumber;
- }
-
- private int generateRuntimeAnnotationsForParameters(Argument[] arguments) {
- final int argumentsLength = arguments.length;
- final int VISIBLE_INDEX = 0;
- final int INVISIBLE_INDEX = 1;
- int invisibleParametersAnnotationsCounter = 0;
- int visibleParametersAnnotationsCounter = 0;
- int[][] annotationsCounters = new int[argumentsLength][2];
- for (int i = 0; i < argumentsLength; i++) {
- Argument argument = arguments[i];
- Annotation[] annotations = argument.annotations;
- if (annotations != null) {
- for (int j = 0, max2 = annotations.length; j < max2; j++) {
- Annotation annotation;
- if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container.
- long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
- if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue;
- if (annotation.isRuntimeInvisible()) {
- annotationsCounters[i][INVISIBLE_INDEX]++;
- invisibleParametersAnnotationsCounter++;
- } else if (annotation.isRuntimeVisible()) {
- annotationsCounters[i][VISIBLE_INDEX]++;
- visibleParametersAnnotationsCounter++;
- }
- }
- }
- }
- int attributesNumber = 0;
- int annotationAttributeOffset = this.contentsOffset;
- if (invisibleParametersAnnotationsCounter != 0) {
- int globalCounter = 0;
- if (this.contentsOffset + 7 >= this.contents.length) {
- resizeContents(7);
- }
- int attributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleParameterAnnotationsName);
- this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) attributeNameIndex;
- int attributeLengthOffset = this.contentsOffset;
- this.contentsOffset += 4; // leave space for the attribute length
-
- this.contents[this.contentsOffset++] = (byte) argumentsLength;
- for (int i = 0; i < argumentsLength; i++) {
- if (this.contentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- if (invisibleParametersAnnotationsCounter == 0) {
- this.contents[this.contentsOffset++] = (byte) 0;
- this.contents[this.contentsOffset++] = (byte) 0;
- } else {
- final int numberOfInvisibleAnnotations = annotationsCounters[i][INVISIBLE_INDEX];
- int invisibleAnnotationsOffset = this.contentsOffset;
- // leave space for number of annotations
- this.contentsOffset += 2;
- int counter = 0;
- if (numberOfInvisibleAnnotations != 0) {
- Argument argument = arguments[i];
- Annotation[] annotations = argument.annotations;
- for (int j = 0, max = annotations.length; j < max; j++) {
- Annotation annotation;
- if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container.
- long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
- if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue;
- if (annotation.isRuntimeInvisible()) {
- int currentAnnotationOffset = this.contentsOffset;
- generateAnnotation(annotation, currentAnnotationOffset);
- if (this.contentsOffset != currentAnnotationOffset) {
- counter++;
- globalCounter++;
- }
- invisibleParametersAnnotationsCounter--;
- }
- }
- }
- this.contents[invisibleAnnotationsOffset++] = (byte) (counter >> 8);
- this.contents[invisibleAnnotationsOffset] = (byte) counter;
- }
- }
- if (globalCounter != 0) {
- int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
- this.contents[attributeLengthOffset++] = (byte) attributeLength;
- attributesNumber++;
- } else {
- // if globalCounter is 0, this means that the code generation for all visible annotations failed
- this.contentsOffset = annotationAttributeOffset;
- }
- }
- if (visibleParametersAnnotationsCounter != 0) {
- int globalCounter = 0;
- if (this.contentsOffset + 7 >= this.contents.length) {
- resizeContents(7);
- }
- int attributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleParameterAnnotationsName);
- this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) attributeNameIndex;
- int attributeLengthOffset = this.contentsOffset;
- this.contentsOffset += 4; // leave space for the attribute length
-
- this.contents[this.contentsOffset++] = (byte) argumentsLength;
- for (int i = 0; i < argumentsLength; i++) {
- if (this.contentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- if (visibleParametersAnnotationsCounter == 0) {
- this.contents[this.contentsOffset++] = (byte) 0;
- this.contents[this.contentsOffset++] = (byte) 0;
- } else {
- final int numberOfVisibleAnnotations = annotationsCounters[i][VISIBLE_INDEX];
- int visibleAnnotationsOffset = this.contentsOffset;
- // leave space for number of annotations
- this.contentsOffset += 2;
- int counter = 0;
- if (numberOfVisibleAnnotations != 0) {
- Argument argument = arguments[i];
- Annotation[] annotations = argument.annotations;
- for (int j = 0, max = annotations.length; j < max; j++) {
- Annotation annotation;
- if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container.
- long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
- if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue;
- if (annotation.isRuntimeVisible()) {
- int currentAnnotationOffset = this.contentsOffset;
- generateAnnotation(annotation, currentAnnotationOffset);
- if (this.contentsOffset != currentAnnotationOffset) {
- counter++;
- globalCounter++;
- }
- visibleParametersAnnotationsCounter--;
- }
- }
- }
- this.contents[visibleAnnotationsOffset++] = (byte) (counter >> 8);
- this.contents[visibleAnnotationsOffset] = (byte) counter;
- }
- }
- if (globalCounter != 0) {
- int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
- this.contents[attributeLengthOffset++] = (byte) attributeLength;
- attributesNumber++;
- } else {
- // if globalCounter is 0, this means that the code generation for all visible annotations failed
- this.contentsOffset = annotationAttributeOffset;
- }
- }
- return attributesNumber;
- }
-
- /**
- * @param annotationContexts the given annotation contexts
- * @param visibleTypeAnnotationsNumber the given number of visible type annotations
- * @param invisibleTypeAnnotationsNumber the given number of invisible type annotations
- * @return the number of attributes created while dumping the annotations in the .class file
- */
- private int generateRuntimeTypeAnnotations(
- final AnnotationContext[] annotationContexts,
- int visibleTypeAnnotationsNumber,
- int invisibleTypeAnnotationsNumber) {
- int attributesNumber = 0;
- final int length = annotationContexts.length;
-
- int visibleTypeAnnotationsCounter = visibleTypeAnnotationsNumber;
- int invisibleTypeAnnotationsCounter = invisibleTypeAnnotationsNumber;
- int annotationAttributeOffset = this.contentsOffset;
- if (invisibleTypeAnnotationsCounter != 0) {
- if (this.contentsOffset + 10 >= this.contents.length) {
- resizeContents(10);
- }
- int runtimeInvisibleAnnotationsAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleTypeAnnotationsName);
- this.contents[this.contentsOffset++] = (byte) (runtimeInvisibleAnnotationsAttributeNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) runtimeInvisibleAnnotationsAttributeNameIndex;
- int attributeLengthOffset = this.contentsOffset;
- this.contentsOffset += 4; // leave space for the attribute length
-
- int annotationsLengthOffset = this.contentsOffset;
- this.contentsOffset += 2; // leave space for the annotations length
-
- int counter = 0;
- loop: for (int i = 0; i < length; i++) {
- if (invisibleTypeAnnotationsCounter == 0) break loop;
- AnnotationContext annotationContext = annotationContexts[i];
- if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
- int currentAnnotationOffset = this.contentsOffset;
- generateTypeAnnotation(annotationContext, currentAnnotationOffset);
- invisibleTypeAnnotationsCounter--;
- if (this.contentsOffset != currentAnnotationOffset) {
- counter++;
- }
- }
- }
- if (counter != 0) {
- this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
- this.contents[annotationsLengthOffset++] = (byte) counter;
-
- int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
- this.contents[attributeLengthOffset++] = (byte) attributeLength;
- attributesNumber++;
- } else {
- this.contentsOffset = annotationAttributeOffset;
- }
- }
-
- annotationAttributeOffset = this.contentsOffset;
- if (visibleTypeAnnotationsCounter != 0) {
- if (this.contentsOffset + 10 >= this.contents.length) {
- resizeContents(10);
- }
- int runtimeVisibleAnnotationsAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleTypeAnnotationsName);
- this.contents[this.contentsOffset++] = (byte) (runtimeVisibleAnnotationsAttributeNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) runtimeVisibleAnnotationsAttributeNameIndex;
- int attributeLengthOffset = this.contentsOffset;
- this.contentsOffset += 4; // leave space for the attribute length
-
- int annotationsLengthOffset = this.contentsOffset;
- this.contentsOffset += 2; // leave space for the annotations length
-
- int counter = 0;
- loop: for (int i = 0; i < length; i++) {
- if (visibleTypeAnnotationsCounter == 0) break loop;
- AnnotationContext annotationContext = annotationContexts[i];
- if ((annotationContext.visibility & AnnotationContext.VISIBLE) != 0) {
- visibleTypeAnnotationsCounter--;
- int currentAnnotationOffset = this.contentsOffset;
- generateTypeAnnotation(annotationContext, currentAnnotationOffset);
- if (this.contentsOffset != currentAnnotationOffset) {
- counter++;
- }
- }
- }
- if (counter != 0) {
- this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
- this.contents[annotationsLengthOffset++] = (byte) counter;
-
- int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
- this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
- this.contents[attributeLengthOffset++] = (byte) attributeLength;
- attributesNumber++;
- } else {
- this.contentsOffset = annotationAttributeOffset;
- }
- }
- return attributesNumber;
- }
-
- /**
- * @param binding the given method binding
- * @return the number of attributes created while dumping he method's parameters in the .class file (0 or 1)
- */
- private int generateMethodParameters(final MethodBinding binding) {
-
- if (binding.sourceLambda() != null)
- return 0;
- int initialContentsOffset = this.contentsOffset;
- int length = 0; // count of actual parameters
-
- AbstractMethodDeclaration methodDeclaration = binding.sourceMethod();
-
- boolean isConstructor = binding.isConstructor();
- TypeBinding[] targetParameters = binding.parameters;
- ReferenceBinding declaringClass = binding.declaringClass;
-
- if (declaringClass.isEnum()) {
- if (isConstructor) { // insert String name,int ordinal
- length = writeArgumentName(ConstantPool.EnumName, ClassFileConstants.AccSynthetic, length);
- length = writeArgumentName(ConstantPool.EnumOrdinal, ClassFileConstants.AccSynthetic, length);
- } else if (binding instanceof SyntheticMethodBinding
- && CharOperation.equals(ConstantPool.ValueOf, binding.selector)) { // insert String name
- length = writeArgumentName(ConstantPool.Name, ClassFileConstants.AccMandated, length);
- targetParameters = Binding.NO_PARAMETERS; // Override "unknown" synthetics below
- }
- }
-
- boolean needSynthetics = isConstructor && declaringClass.isNestedType();
- if (needSynthetics) {
- // Take into account the synthetic argument names
- // This tracks JLS8, paragraph 8.8.9
- boolean anonymousWithLocalSuper = declaringClass.isAnonymousType() && declaringClass.superclass().isLocalType();
- boolean anonymousWithNestedSuper = declaringClass.isAnonymousType() && declaringClass.superclass().isNestedType();
- boolean isImplicitlyDeclared = ((! declaringClass.isPrivate()) || declaringClass.isAnonymousType()) && !anonymousWithLocalSuper;
- ReferenceBinding[] syntheticArgumentTypes = declaringClass.syntheticEnclosingInstanceTypes();
- if (syntheticArgumentTypes != null) {
- for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) {
- // This behaviour tracks JLS 15.9.5.1
- // This covers that the parameter ending up in a nested class must be mandated "on the way in", even if it
- // isn't the first. The practical relevance of this is questionable, since the constructor call will be
- // generated by the same constructor.
- boolean couldForwardToMandated = anonymousWithNestedSuper ? declaringClass.superclass().enclosingType().equals(syntheticArgumentTypes[i]) : true;
- int modifier = couldForwardToMandated && isImplicitlyDeclared ? ClassFileConstants.AccMandated : ClassFileConstants.AccSynthetic;
- char[] name = CharOperation.concat(
- TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX,
- String.valueOf(i).toCharArray()); // cannot use depth, can be identical
- length = writeArgumentName(name, modifier | ClassFileConstants.AccFinal, length);
- }
- }
- if (binding instanceof SyntheticMethodBinding) {
- targetParameters = ((SyntheticMethodBinding)binding).targetMethod.parameters;
- methodDeclaration = ((SyntheticMethodBinding)binding).targetMethod.sourceMethod();
- }
- }
- if (targetParameters != Binding.NO_PARAMETERS) {
- Argument[] arguments = null;
- if (methodDeclaration != null && methodDeclaration.arguments != null) {
- arguments = methodDeclaration.arguments;
- }
- for (int i = 0, max = targetParameters.length, argumentsLength = arguments != null ? arguments.length : 0; i < max; i++) {
- if (argumentsLength > i && arguments[i] != null) {
- Argument argument = arguments[i];
- int modifiers = argument.binding.modifiers;
- if (binding.isCompactConstructor())
- modifiers |= ClassFileConstants.AccMandated;
- length = writeArgumentName(argument.name, modifiers, length);
- } else {
- length = writeArgumentName(null, ClassFileConstants.AccSynthetic, length);
- }
- }
- }
- if (needSynthetics) {
- SyntheticArgumentBinding[] syntheticOuterArguments = declaringClass.syntheticOuterLocalVariables();
- int count = syntheticOuterArguments == null ? 0 : syntheticOuterArguments.length;
- for (int i = 0; i < count; i++) {
- length = writeArgumentName(syntheticOuterArguments[i].name, syntheticOuterArguments[i].modifiers | ClassFileConstants.AccSynthetic, length);
- }
- // move the extra padding arguments of the synthetic constructor invocation to the end
- for (int i = targetParameters.length, extraLength = binding.parameters.length; i < extraLength; i++) {
- TypeBinding parameter = binding.parameters[i];
- length = writeArgumentName(parameter.constantPoolName(), ClassFileConstants.AccSynthetic, length);
- }
- }
-
- if (length > 0) {
- // so we actually output the parameter
- int attributeLength = 1 + 4 * length; // u1 for count, u2+u2 per parameter
- if (this.contentsOffset + 6 + attributeLength >= this.contents.length) {
- resizeContents(6 + attributeLength);
- }
- int methodParametersNameIndex = this.constantPool.literalIndex(AttributeNamesConstants.MethodParametersName);
- this.contents[initialContentsOffset++] = (byte) (methodParametersNameIndex >> 8);
- this.contents[initialContentsOffset++] = (byte) methodParametersNameIndex;
- this.contents[initialContentsOffset++] = (byte) (attributeLength >> 24);
- this.contents[initialContentsOffset++] = (byte) (attributeLength >> 16);
- this.contents[initialContentsOffset++] = (byte) (attributeLength >> 8);
- this.contents[initialContentsOffset++] = (byte) attributeLength;
- this.contents[initialContentsOffset++] = (byte) length;
- return 1;
- }
- else {
- return 0;
- }
- }
- private int writeArgumentName(char[] name, int modifiers, int oldLength) {
- int ensureRoomForBytes = 4;
- if (oldLength == 0) {
- // Make room for
- ensureRoomForBytes += 7;
- this.contentsOffset += 7; // Make room for attribute header + count byte
- }
- if (this.contentsOffset + ensureRoomForBytes > this.contents.length) {
- resizeContents(ensureRoomForBytes);
- }
- int parameterNameIndex = name == null ? 0 : this.constantPool.literalIndex(name);
- this.contents[this.contentsOffset++] = (byte) (parameterNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) parameterNameIndex;
- int flags = modifiers & (ClassFileConstants.AccFinal | ClassFileConstants.AccSynthetic | ClassFileConstants.AccMandated);
- this.contents[this.contentsOffset++] = (byte) (flags >> 8);
- this.contents[this.contentsOffset++] = (byte) flags;
- return oldLength + 1;
- }
-
- private int generateSignatureAttribute(char[] genericSignature) {
- int localContentsOffset = this.contentsOffset;
- if (localContentsOffset + 8 >= this.contents.length) {
- resizeContents(8);
- }
- int signatureAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.SignatureName);
- this.contents[localContentsOffset++] = (byte) (signatureAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) signatureAttributeNameIndex;
- // the length of a signature attribute is equals to 2
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 2;
- int signatureIndex =
- this.constantPool.literalIndex(genericSignature);
- this.contents[localContentsOffset++] = (byte) (signatureIndex >> 8);
- this.contents[localContentsOffset++] = (byte) signatureIndex;
- this.contentsOffset = localContentsOffset;
- return 1;
- }
-
- private int generateSourceAttribute(String fullFileName) {
- int localContentsOffset = this.contentsOffset;
- // check that there is enough space to write all the bytes for the field info corresponding
- // to the @fieldBinding
- if (localContentsOffset + 8 >= this.contents.length) {
- resizeContents(8);
- }
- int sourceAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.SourceName);
- this.contents[localContentsOffset++] = (byte) (sourceAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) sourceAttributeNameIndex;
- // The length of a source file attribute is 2. This is a fixed-length
- // attribute
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 2;
- // write the source file name
- int fileNameIndex = this.constantPool.literalIndex(fullFileName.toCharArray());
- this.contents[localContentsOffset++] = (byte) (fileNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) fileNameIndex;
- this.contentsOffset = localContentsOffset;
- return 1;
- }
- private int generateStackMapAttribute(
- MethodBinding methodBinding,
- int code_length,
- int codeAttributeOffset,
- int max_locals,
- boolean isClinit,
- Scope scope) {
- int attributesNumber = 0;
- int localContentsOffset = this.contentsOffset;
- StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
- stackMapFrameCodeStream.removeFramePosition(code_length);
- if (stackMapFrameCodeStream.hasFramePositions()) {
- Map frames = new HashMap<>();
- List realFrames = traverse(isClinit ? null : methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit, scope);
- int numberOfFrames = realFrames.size();
- if (numberOfFrames > 1) {
- int stackMapTableAttributeOffset = localContentsOffset;
- // add the stack map table attribute
- if (localContentsOffset + 8 >= this.contents.length) {
- resizeContents(8);
- }
- int stackMapAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.StackMapName);
- this.contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
-
- int stackMapAttributeLengthOffset = localContentsOffset;
- // generate the attribute
- localContentsOffset += 4;
- if (localContentsOffset + 4 >= this.contents.length) {
- resizeContents(4);
- }
- int numberOfFramesOffset = localContentsOffset;
- localContentsOffset += 2;
- if (localContentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- StackMapFrame currentFrame = realFrames.get(0);
- for (int j = 1; j < numberOfFrames; j++) {
- // select next frame
- currentFrame = realFrames.get(j);
- // generate current frame
- // need to find differences between the current frame and the previous frame
- int frameOffset = currentFrame.pc;
- // FULL_FRAME
- if (localContentsOffset + 5 >= this.contents.length) {
- resizeContents(5);
- }
- this.contents[localContentsOffset++] = (byte) (frameOffset >> 8);
- this.contents[localContentsOffset++] = (byte) frameOffset;
- int numberOfLocalOffset = localContentsOffset;
- localContentsOffset += 2; // leave two spots for number of locals
- int numberOfLocalEntries = 0;
- int numberOfLocals = currentFrame.getNumberOfLocals();
- int numberOfEntries = 0;
- int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
- for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
- if (localContentsOffset + 3 >= this.contents.length) {
- resizeContents(3);
- }
- VerificationTypeInfo info = currentFrame.locals[i];
- if (info == null) {
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
- } else {
- switch(info.id()) {
- case T_boolean :
- case T_byte :
- case T_char :
- case T_int :
- case T_short :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
- break;
- case T_float :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
- break;
- case T_long :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
- i++;
- break;
- case T_double :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
- i++;
- break;
- case T_null :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
- break;
- default:
- this.contents[localContentsOffset++] = (byte) info.tag;
- switch (info.tag) {
- case VerificationTypeInfo.ITEM_UNINITIALIZED :
- int offset = info.offset;
- this.contents[localContentsOffset++] = (byte) (offset >> 8);
- this.contents[localContentsOffset++] = (byte) offset;
- break;
- case VerificationTypeInfo.ITEM_OBJECT :
- int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
- this.contents[localContentsOffset++] = (byte) indexForType;
- }
- }
- numberOfLocalEntries++;
- }
- numberOfEntries++;
- }
- if (localContentsOffset + 4 >= this.contents.length) {
- resizeContents(4);
- }
- this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
- this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
- int numberOfStackItems = currentFrame.numberOfStackItems;
- this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
- this.contents[localContentsOffset++] = (byte) numberOfStackItems;
- for (int i = 0; i < numberOfStackItems; i++) {
- if (localContentsOffset + 3 >= this.contents.length) {
- resizeContents(3);
- }
- VerificationTypeInfo info = currentFrame.stackItems[i];
- if (info == null) {
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
- } else {
- switch(info.id()) {
- case T_boolean :
- case T_byte :
- case T_char :
- case T_int :
- case T_short :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
- break;
- case T_float :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
- break;
- case T_long :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
- break;
- case T_double :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
- break;
- case T_null :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
- break;
- default:
- this.contents[localContentsOffset++] = (byte) info.tag;
- switch (info.tag) {
- case VerificationTypeInfo.ITEM_UNINITIALIZED :
- int offset = info.offset;
- this.contents[localContentsOffset++] = (byte) (offset >> 8);
- this.contents[localContentsOffset++] = (byte) offset;
- break;
- case VerificationTypeInfo.ITEM_OBJECT :
- int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
- this.contents[localContentsOffset++] = (byte) indexForType;
- }
- }
- }
- }
- }
-
- numberOfFrames--;
- if (numberOfFrames != 0) {
- this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
- this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
- int attributeLength = localContentsOffset - stackMapAttributeLengthOffset - 4;
- this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
- this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
- this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
- this.contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
- attributesNumber++;
- } else {
- localContentsOffset = stackMapTableAttributeOffset;
- }
- }
- }
- this.contentsOffset = localContentsOffset;
- return attributesNumber;
- }
-
- private int generateStackMapTableAttribute(
- MethodBinding methodBinding,
- int code_length,
- int codeAttributeOffset,
- int max_locals,
- boolean isClinit,
- Scope scope) {
- int attributesNumber = 0;
- int localContentsOffset = this.contentsOffset;
- StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
- stackMapFrameCodeStream.removeFramePosition(code_length);
- if (stackMapFrameCodeStream.hasFramePositions()) {
- Map frames = new HashMap<>();
- List realFrames = traverse(isClinit ? null: methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit, scope);
- int numberOfFrames = realFrames.size();
- if (numberOfFrames > 1) {
- int stackMapTableAttributeOffset = localContentsOffset;
- // add the stack map table attribute
- if (localContentsOffset + 8 >= this.contents.length) {
- resizeContents(8);
- }
- int stackMapTableAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.StackMapTableName);
- this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
-
- int stackMapTableAttributeLengthOffset = localContentsOffset;
- // generate the attribute
- localContentsOffset += 4;
- if (localContentsOffset + 4 >= this.contents.length) {
- resizeContents(4);
- }
- int numberOfFramesOffset = localContentsOffset;
- localContentsOffset += 2;
- if (localContentsOffset + 2 >= this.contents.length) {
- resizeContents(2);
- }
- StackMapFrame currentFrame = realFrames.get(0);
- StackMapFrame prevFrame = null;
- for (int j = 1; j < numberOfFrames; j++) {
- // select next frame
- prevFrame = currentFrame;
- currentFrame = realFrames.get(j);
- // generate current frame
- // need to find differences between the current frame and the previous frame
- int offsetDelta = currentFrame.getOffsetDelta(prevFrame);
- switch (currentFrame.getFrameType(prevFrame)) {
- case StackMapFrame.APPEND_FRAME :
- if (localContentsOffset + 3 >= this.contents.length) {
- resizeContents(3);
- }
- int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame);
- this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
- this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
- this.contents[localContentsOffset++] = (byte) offsetDelta;
- int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals);
- int numberOfLocals = currentFrame.getNumberOfLocals();
- for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) {
- if (localContentsOffset + 6 >= this.contents.length) {
- resizeContents(6);
- }
- VerificationTypeInfo info = currentFrame.locals[i];
- if (info == null) {
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
- } else {
- switch(info.id()) {
- case T_boolean :
- case T_byte :
- case T_char :
- case T_int :
- case T_short :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
- break;
- case T_float :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
- break;
- case T_long :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
- i++;
- break;
- case T_double :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
- i++;
- break;
- case T_null :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
- break;
- default:
- this.contents[localContentsOffset++] = (byte) info.tag;
- switch (info.tag) {
- case VerificationTypeInfo.ITEM_UNINITIALIZED :
- int offset = info.offset;
- this.contents[localContentsOffset++] = (byte) (offset >> 8);
- this.contents[localContentsOffset++] = (byte) offset;
- break;
- case VerificationTypeInfo.ITEM_OBJECT :
- int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
- this.contents[localContentsOffset++] = (byte) indexForType;
- }
- }
- numberOfDifferentLocals--;
- }
- }
- break;
- case StackMapFrame.SAME_FRAME :
- if (localContentsOffset + 1 >= this.contents.length) {
- resizeContents(1);
- }
- this.contents[localContentsOffset++] = (byte) offsetDelta;
- break;
- case StackMapFrame.SAME_FRAME_EXTENDED :
- if (localContentsOffset + 3 >= this.contents.length) {
- resizeContents(3);
- }
- this.contents[localContentsOffset++] = (byte) 251;
- this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
- this.contents[localContentsOffset++] = (byte) offsetDelta;
- break;
- case StackMapFrame.CHOP_FRAME :
- if (localContentsOffset + 3 >= this.contents.length) {
- resizeContents(3);
- }
- numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame);
- this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
- this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
- this.contents[localContentsOffset++] = (byte) offsetDelta;
- break;
- case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS :
- if (localContentsOffset + 4 >= this.contents.length) {
- resizeContents(4);
- }
- this.contents[localContentsOffset++] = (byte) (offsetDelta + 64);
- if (currentFrame.stackItems[0] == null) {
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
- } else {
- switch(currentFrame.stackItems[0].id()) {
- case T_boolean :
- case T_byte :
- case T_char :
- case T_int :
- case T_short :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
- break;
- case T_float :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
- break;
- case T_long :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
- break;
- case T_double :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
- break;
- case T_null :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
- break;
- default:
- VerificationTypeInfo info = currentFrame.stackItems[0];
- byte tag = (byte) info.tag;
- this.contents[localContentsOffset++] = tag;
- switch (tag) {
- case VerificationTypeInfo.ITEM_UNINITIALIZED :
- int offset = info.offset;
- this.contents[localContentsOffset++] = (byte) (offset >> 8);
- this.contents[localContentsOffset++] = (byte) offset;
- break;
- case VerificationTypeInfo.ITEM_OBJECT :
- int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
- this.contents[localContentsOffset++] = (byte) indexForType;
- }
- }
- }
- break;
- case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED :
- if (localContentsOffset + 6 >= this.contents.length) {
- resizeContents(6);
- }
- this.contents[localContentsOffset++] = (byte) 247;
- this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
- this.contents[localContentsOffset++] = (byte) offsetDelta;
- if (currentFrame.stackItems[0] == null) {
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
- } else {
- switch(currentFrame.stackItems[0].id()) {
- case T_boolean :
- case T_byte :
- case T_char :
- case T_int :
- case T_short :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
- break;
- case T_float :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
- break;
- case T_long :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
- break;
- case T_double :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
- break;
- case T_null :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
- break;
- default:
- VerificationTypeInfo info = currentFrame.stackItems[0];
- byte tag = (byte) info.tag;
- this.contents[localContentsOffset++] = tag;
- switch (tag) {
- case VerificationTypeInfo.ITEM_UNINITIALIZED :
- int offset = info.offset;
- this.contents[localContentsOffset++] = (byte) (offset >> 8);
- this.contents[localContentsOffset++] = (byte) offset;
- break;
- case VerificationTypeInfo.ITEM_OBJECT :
- int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
- this.contents[localContentsOffset++] = (byte) indexForType;
- }
- }
- }
- break;
- default :
- // FULL_FRAME
- if (localContentsOffset + 5 >= this.contents.length) {
- resizeContents(5);
- }
- this.contents[localContentsOffset++] = (byte) 255;
- this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
- this.contents[localContentsOffset++] = (byte) offsetDelta;
- int numberOfLocalOffset = localContentsOffset;
- localContentsOffset += 2; // leave two spots for number of locals
- int numberOfLocalEntries = 0;
- numberOfLocals = currentFrame.getNumberOfLocals();
- int numberOfEntries = 0;
- int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
- for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
- if (localContentsOffset + 3 >= this.contents.length) {
- resizeContents(3);
- }
- VerificationTypeInfo info = currentFrame.locals[i];
- if (info == null) {
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
- } else {
- switch(info.id()) {
- case T_boolean :
- case T_byte :
- case T_char :
- case T_int :
- case T_short :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
- break;
- case T_float :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
- break;
- case T_long :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
- i++;
- break;
- case T_double :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
- i++;
- break;
- case T_null :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
- break;
- default:
- this.contents[localContentsOffset++] = (byte) info.tag;
- switch (info.tag) {
- case VerificationTypeInfo.ITEM_UNINITIALIZED :
- int offset = info.offset;
- this.contents[localContentsOffset++] = (byte) (offset >> 8);
- this.contents[localContentsOffset++] = (byte) offset;
- break;
- case VerificationTypeInfo.ITEM_OBJECT :
- int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
- this.contents[localContentsOffset++] = (byte) indexForType;
- }
- }
- numberOfLocalEntries++;
- }
- numberOfEntries++;
- }
- if (localContentsOffset + 4 >= this.contents.length) {
- resizeContents(4);
- }
- this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
- this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
- int numberOfStackItems = currentFrame.numberOfStackItems;
- this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
- this.contents[localContentsOffset++] = (byte) numberOfStackItems;
- for (int i = 0; i < numberOfStackItems; i++) {
- if (localContentsOffset + 3 >= this.contents.length) {
- resizeContents(3);
- }
- VerificationTypeInfo info = currentFrame.stackItems[i];
- if (info == null) {
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
- } else {
- switch(info.id()) {
- case T_boolean :
- case T_byte :
- case T_char :
- case T_int :
- case T_short :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
- break;
- case T_float :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
- break;
- case T_long :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
- break;
- case T_double :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
- break;
- case T_null :
- this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
- break;
- default:
- this.contents[localContentsOffset++] = (byte) info.tag;
- switch (info.tag) {
- case VerificationTypeInfo.ITEM_UNINITIALIZED :
- int offset = info.offset;
- this.contents[localContentsOffset++] = (byte) (offset >> 8);
- this.contents[localContentsOffset++] = (byte) offset;
- break;
- case VerificationTypeInfo.ITEM_OBJECT :
- int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
- this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
- this.contents[localContentsOffset++] = (byte) indexForType;
- }
- }
- }
- }
- }
- }
-
- numberOfFrames--;
- if (numberOfFrames != 0) {
- this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
- this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
- int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4;
- this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
- this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
- this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
- this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
- attributesNumber++;
- } else {
- localContentsOffset = stackMapTableAttributeOffset;
- }
- }
- }
- this.contentsOffset = localContentsOffset;
- return attributesNumber;
- }
-
- private int generateSyntheticAttribute() {
- int localContentsOffset = this.contentsOffset;
- if (localContentsOffset + 6 >= this.contents.length) {
- resizeContents(6);
- }
- int syntheticAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
- this.contents[localContentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) syntheticAttributeNameIndex;
- // the length of a synthetic attribute is equals to 0
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contentsOffset = localContentsOffset;
- return 1;
- }
-
- private void generateTypeAnnotation(AnnotationContext annotationContext, int currentOffset) {
- Annotation annotation = annotationContext.annotation.getPersistibleAnnotation();
- if (annotation == null || annotation.resolvedType == null)
- return;
-
- int targetType = annotationContext.targetType;
-
- int[] locations = Annotation.getLocations(
- annotationContext.typeReference,
- annotationContext.annotation);
-
- if (this.contentsOffset + 5 >= this.contents.length) {
- resizeContents(5);
- }
- this.contents[this.contentsOffset++] = (byte) targetType;
- dumpTargetTypeContents(targetType, annotationContext);
- dumpLocations(locations);
- generateAnnotation(annotation, currentOffset);
- }
-
- private int generateTypeAnnotationAttributeForTypeDeclaration() {
- TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
- if ((typeDeclaration.bits & ASTNode.HasTypeAnnotations) == 0) {
- return 0;
- }
- int attributesNumber = 0;
- TypeReference superclass = typeDeclaration.superclass;
- List allTypeAnnotationContexts = new ArrayList<>();
- if (superclass != null && (superclass.bits & ASTNode.HasTypeAnnotations) != 0) {
- superclass.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, -1, allTypeAnnotationContexts);
- }
- TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
- if (superInterfaces != null) {
- for (int i = 0; i < superInterfaces.length; i++) {
- TypeReference superInterface = superInterfaces[i];
- if ((superInterface.bits & ASTNode.HasTypeAnnotations) == 0) {
- continue;
- }
- superInterface.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, i, allTypeAnnotationContexts);
- }
- }
- // TODO: permittedTypes codegen
- TypeParameter[] typeParameters = typeDeclaration.typeParameters;
- if (typeParameters != null) {
- for (int i = 0, max = typeParameters.length; i < max; i++) {
- TypeParameter typeParameter = typeParameters[i];
- if ((typeParameter.bits & ASTNode.HasTypeAnnotations) != 0) {
- typeParameter.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER, i, allTypeAnnotationContexts);
- }
- }
- }
- int size = allTypeAnnotationContexts.size();
- attributesNumber = completeRuntimeTypeAnnotations(attributesNumber,
- null,
- node -> size > 0,
- () -> allTypeAnnotationContexts);
- return attributesNumber;
- }
-
-
-
-
- private int generateVarargsAttribute() {
- int localContentsOffset = this.contentsOffset;
- /*
- * handle of the target jsr14 for varargs in the source
- * Varargs attribute
- * Check that there is enough space to write the attribute
- */
- if (localContentsOffset + 6 >= this.contents.length) {
- resizeContents(6);
- }
- int varargsAttributeNameIndex =
- this.constantPool.literalIndex(AttributeNamesConstants.VarargsName);
- this.contents[localContentsOffset++] = (byte) (varargsAttributeNameIndex >> 8);
- this.contents[localContentsOffset++] = (byte) varargsAttributeNameIndex;
- // the length of a varargs attribute is equals to 0
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = 0;
-
- this.contentsOffset = localContentsOffset;
- return 1;
- }
-
- /**
- * EXTERNAL API
- * Answer the actual bytes of the class file
- *
- * This method encodes the receiver structure into a byte array which is the content of the classfile.
- * Returns the byte array that represents the encoded structure of the receiver.
- *
- * @return byte[]
- */
- public byte[] getBytes() {
- if (this.bytes == null) {
- this.bytes = new byte[this.headerOffset + this.contentsOffset];
- System.arraycopy(this.header, 0, this.bytes, 0, this.headerOffset);
- System.arraycopy(this.contents, 0, this.bytes, this.headerOffset, this.contentsOffset);
- }
- return this.bytes;
- }
-
- /**
- * Sets the actual bytes of the class file.
- *
- * This method is made public only to be accessible from org.eclipse.jdt.internal.core.builder.AbstractImageBuilder
- * during compilation post processing to store the modified byte representation of the class. Using this method for
- * any other purpose is discouraged and may lead to unpredictable results.
- *
- * @param newBytes
- * array containing new bytes, will be stored "as is", all subsequent modification on given
- * array will be reflected and vice versa.
- */
- public void internalSetBytes(byte[] newBytes) {
- this.bytes = newBytes;
- }
-
- /**
- * EXTERNAL API
- * Answer the compound name of the class file.
- * @return char[][]
- * e.g. {{java}, {util}, {Hashtable}}.
- */
- public char[][] getCompoundName() {
- return CharOperation.splitOn('/', fileName());
- }
-
- private int getParametersCount(char[] methodSignature) {
- int i = CharOperation.indexOf('(', methodSignature);
- i++;
- char currentCharacter = methodSignature[i];
- if (currentCharacter == ')') {
- return 0;
- }
- int result = 0;
- while (true) {
- currentCharacter = methodSignature[i];
- if (currentCharacter == ')') {
- return result;
- }
- switch (currentCharacter) {
- case '[':
- // array type
- int scanType = scanType(methodSignature, i + 1);
- result++;
- i = scanType + 1;
- break;
- case 'L':
- scanType = CharOperation.indexOf(';', methodSignature,
- i + 1);
- result++;
- i = scanType + 1;
- break;
- case 'Z':
- case 'B':
- case 'C':
- case 'D':
- case 'F':
- case 'I':
- case 'J':
- case 'S':
- result++;
- i++;
- break;
- default:
- throw new IllegalArgumentException("Invalid starting type character : " + currentCharacter); //$NON-NLS-1$
- }
- }
- }
-
- private char[] getReturnType(char[] methodSignature) {
- // skip type parameters
- int paren = CharOperation.lastIndexOf(')', methodSignature);
- // there could be thrown exceptions behind, thus scan one type exactly
- return CharOperation.subarray(methodSignature, paren + 1, methodSignature.length);
- }
-
- private final int i4At(byte[] reference, int relativeOffset,
- int structOffset) {
- int position = relativeOffset + structOffset;
- return ((reference[position++] & 0xFF) << 24)
- + ((reference[position++] & 0xFF) << 16)
- + ((reference[position++] & 0xFF) << 8)
- + (reference[position] & 0xFF);
- }
-
- protected void initByteArrays(int members) {
- this.header = new byte[INITIAL_HEADER_SIZE];
- this.contents = new byte[members < 15 ? INITIAL_CONTENTS_SIZE : INITIAL_HEADER_SIZE];
- }
-
- private void initializeHeader(ClassFile parentClassFile, int accessFlags) {
- // generate the magic numbers inside the header
- this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 24);
- this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 16);
- this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 8);
- this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 0);
-
- long targetVersion = this.targetJDK;
- this.header[this.headerOffset++] = (byte) (targetVersion >> 8); // minor high
- this.header[this.headerOffset++] = (byte) (targetVersion>> 0); // minor low
- this.header[this.headerOffset++] = (byte) (targetVersion >> 24); // major high
- this.header[this.headerOffset++] = (byte) (targetVersion >> 16); // major low
-
- this.constantPoolOffset = this.headerOffset;
- this.headerOffset += 2;
- this.constantPool.initialize(this);
- this.enclosingClassFile = parentClassFile;
-
- // now we continue to generate the bytes inside the contents array
- this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
- this.contents[this.contentsOffset++] = (byte) accessFlags;
- }
-
- public void initialize(SourceTypeBinding aType, ClassFile parentClassFile, boolean createProblemType) {
-
- // Modifier manipulations for classfile
- int accessFlags = aType.getAccessFlags();
- if (aType.isPrivate()) { // rewrite private to non-public
- accessFlags &= ~ClassFileConstants.AccPublic;
- }
- if (aType.isProtected()) { // rewrite protected into public
- accessFlags |= ClassFileConstants.AccPublic;
- }
- // clear all bits that are illegal for a class or an interface
- accessFlags
- &= ~(
- ClassFileConstants.AccStrictfp
- | ClassFileConstants.AccProtected
- | ClassFileConstants.AccPrivate
- | ClassFileConstants.AccStatic
- | ClassFileConstants.AccSynchronized
- | ClassFileConstants.AccNative);
-
- // set the AccSuper flag (has to be done after clearing AccSynchronized - since same value)
- if (!aType.isInterface()) { // class or enum
- accessFlags |= ClassFileConstants.AccSuper;
- }
- if (aType.isAnonymousType()) {
- ReferenceBinding superClass = aType.superclass;
- if (superClass == null || !(superClass.isEnum() && superClass.isSealed()))
- accessFlags &= ~ClassFileConstants.AccFinal;
- }
- int finalAbstract = ClassFileConstants.AccFinal | ClassFileConstants.AccAbstract;
- if ((accessFlags & finalAbstract) == finalAbstract) {
- accessFlags &= ~finalAbstract;
- }
- initializeHeader(parentClassFile, accessFlags);
- // innerclasses get their names computed at code gen time
-
- int classNameIndex = this.constantPool.literalIndexForType(aType);
- this.contents[this.contentsOffset++] = (byte) (classNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) classNameIndex;
- int superclassNameIndex;
- if (aType.isInterface()) {
- superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName);
- } else {
- if (aType.superclass != null) {
- if ((aType.superclass.tagBits & TagBits.HasMissingType) != 0) {
- superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName);
- } else {
- superclassNameIndex = this.constantPool.literalIndexForType(aType.superclass);
- }
- } else {
- superclassNameIndex = 0;
- }
- }
- this.contents[this.contentsOffset++] = (byte) (superclassNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) superclassNameIndex;
- ReferenceBinding[] superInterfacesBinding = aType.superInterfaces();
- int interfacesCount = superInterfacesBinding.length;
- int interfacesCountPosition = this.contentsOffset;
- this.contentsOffset += 2;
- int interfaceCounter = 0;
- for (int i = 0; i < interfacesCount; i++) {
- ReferenceBinding binding = superInterfacesBinding[i];
- if ((binding.tagBits & TagBits.HasMissingType) != 0) {
- continue;
- }
- if (this.contentsOffset + 4 >= this.contents.length) {
- resizeContents(4); // 2 bytes this iteration plus 2 bytes after the loop
- }
- interfaceCounter++;
- int interfaceIndex = this.constantPool.literalIndexForType(binding);
- this.contents[this.contentsOffset++] = (byte) (interfaceIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) interfaceIndex;
- }
- this.contents[interfacesCountPosition++] = (byte) (interfaceCounter >> 8);
- this.contents[interfacesCountPosition] = (byte) interfaceCounter;
- this.creatingProblemType = createProblemType;
-
- // retrieve the enclosing one guaranteed to be the one matching the propagated flow info
- // 1FF9ZBU: LFCOM:ALL - Local variable attributes busted (Sanity check)
- this.codeStream.maxFieldCount = aType.scope.outerMostClassScope().referenceType().maxFieldCount;
- }
-
- public void initializeForModule(ModuleBinding module) {
- initializeHeader(null, ClassFileConstants.AccModule);
- int classNameIndex = this.constantPool.literalIndexForType(TypeConstants.MODULE_INFO_NAME);
- this.contents[this.contentsOffset++] = (byte) (classNameIndex >> 8);
- this.contents[this.contentsOffset++] = (byte) classNameIndex;
- this.codeStream.maxFieldCount = 0;
- // superclass:
- this.contents[this.contentsOffset++] = 0;
- this.contents[this.contentsOffset++] = 0;
- // superInterfacesCount
- this.contents[this.contentsOffset++] = 0;
- this.contents[this.contentsOffset++] = 0;
- // fieldsCount
- this.contents[this.contentsOffset++] = 0;
- this.contents[this.contentsOffset++] = 0;
- // methodsCount
- this.contents[this.contentsOffset++] = 0;
- this.contents[this.contentsOffset++] = 0;
- }
-
- private void initializeDefaultLocals(StackMapFrame frame,
- MethodBinding methodBinding,
- int maxLocals,
- int codeLength) {
- if (maxLocals != 0) {
- int resolvedPosition = 0;
- // take into account enum constructor synthetic name+ordinal
- final boolean isConstructor = methodBinding.isConstructor();
- if (isConstructor || !methodBinding.isStatic()) {
- LocalVariableBinding localVariableBinding = new LocalVariableBinding(ConstantPool.This, methodBinding.declaringClass, 0, false);
- localVariableBinding.resolvedPosition = 0;
- this.codeStream.record(localVariableBinding);
- localVariableBinding.recordInitializationStartPC(0);
- localVariableBinding.recordInitializationEndPC(codeLength);
- frame.putLocal(resolvedPosition, new VerificationTypeInfo(
- isConstructor ? VerificationTypeInfo.ITEM_UNINITIALIZED_THIS : VerificationTypeInfo.ITEM_OBJECT,
- methodBinding.declaringClass));
- resolvedPosition++;
- }
-
- if (isConstructor) {
- if (methodBinding.declaringClass.isEnum()) {
- LocalVariableBinding localVariableBinding = new LocalVariableBinding(" name".toCharArray(), this.referenceBinding.scope.getJavaLangString(), 0, false); //$NON-NLS-1$
- localVariableBinding.resolvedPosition = resolvedPosition;
- this.codeStream.record(localVariableBinding);
- localVariableBinding.recordInitializationStartPC(0);
- localVariableBinding.recordInitializationEndPC(codeLength);
-
- frame.putLocal(resolvedPosition, new VerificationTypeInfo(this.referenceBinding.scope.getJavaLangString()));
- resolvedPosition++;
-
- localVariableBinding = new LocalVariableBinding(" ordinal".toCharArray(), TypeBinding.INT, 0, false); //$NON-NLS-1$
- localVariableBinding.resolvedPosition = resolvedPosition;
- this.codeStream.record(localVariableBinding);
- localVariableBinding.recordInitializationStartPC(0);
- localVariableBinding.recordInitializationEndPC(codeLength);
- frame.putLocal(resolvedPosition, new VerificationTypeInfo(TypeBinding.INT));
- resolvedPosition++;
- }
-
- // take into account the synthetic parameters
- if (methodBinding.declaringClass.isNestedType()) {
- ReferenceBinding enclosingInstanceTypes[];
- if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
- for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
- // an enclosingInstanceType can only be a reference
- // binding. It cannot be
- // LongBinding or DoubleBinding
- LocalVariableBinding localVariableBinding = new LocalVariableBinding((" enclosingType" + i).toCharArray(), enclosingInstanceTypes[i], 0, false); //$NON-NLS-1$
- localVariableBinding.resolvedPosition = resolvedPosition;
- this.codeStream.record(localVariableBinding);
- localVariableBinding.recordInitializationStartPC(0);
- localVariableBinding.recordInitializationEndPC(codeLength);
-
- frame.putLocal(resolvedPosition,
- new VerificationTypeInfo(enclosingInstanceTypes[i]));
- resolvedPosition++;
- }
- }
-
- TypeBinding[] arguments;
- if ((arguments = methodBinding.parameters) != null) {
- for (int i = 0, max = arguments.length; i < max; i++) {
- final TypeBinding typeBinding = arguments[i];
- frame.putLocal(resolvedPosition,
- new VerificationTypeInfo(typeBinding));
- switch (typeBinding.id) {
- case TypeIds.T_double:
- case TypeIds.T_long:
- resolvedPosition += 2;
- break;
- default:
- resolvedPosition++;
- }
- }
- }
-
- SyntheticArgumentBinding syntheticArguments[];
- if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
- for (int i = 0, max = syntheticArguments.length; i < max; i++) {
- final TypeBinding typeBinding = syntheticArguments[i].type;
- LocalVariableBinding localVariableBinding = new LocalVariableBinding((" synthetic" + i).toCharArray(), typeBinding, 0, false); //$NON-NLS-1$
- localVariableBinding.resolvedPosition = resolvedPosition;
- this.codeStream.record(localVariableBinding);
- localVariableBinding.recordInitializationStartPC(0);
- localVariableBinding.recordInitializationEndPC(codeLength);
-
- frame.putLocal(resolvedPosition,
- new VerificationTypeInfo(typeBinding));
- switch (typeBinding.id) {
- case TypeIds.T_double:
- case TypeIds.T_long:
- resolvedPosition += 2;
- break;
- default:
- resolvedPosition++;
- }
- }
- }
- } else {
- TypeBinding[] arguments;
- if ((arguments = methodBinding.parameters) != null) {
- for (int i = 0, max = arguments.length; i < max; i++) {
- final TypeBinding typeBinding = arguments[i];
- frame.putLocal(resolvedPosition,
- new VerificationTypeInfo(typeBinding));
- switch (typeBinding.id) {
- case TypeIds.T_double:
- case TypeIds.T_long:
- resolvedPosition += 2;
- break;
- default:
- resolvedPosition++;
- }
- }
- }
- }
- } else {
- TypeBinding[] arguments;
- if ((arguments = methodBinding.parameters) != null) {
- for (int i = 0, max = arguments.length; i < max; i++) {
- final TypeBinding typeBinding = arguments[i];
- // For the branching complexities in the generated $deserializeLambda$ we need the local variable
- LocalVariableBinding localVariableBinding = new LocalVariableBinding((" synthetic"+i).toCharArray(), typeBinding, 0, true); //$NON-NLS-1$
- localVariableBinding.resolvedPosition = i;
- this.codeStream.record(localVariableBinding);
- localVariableBinding.recordInitializationStartPC(0);
- localVariableBinding.recordInitializationEndPC(codeLength);
- frame.putLocal(resolvedPosition,
- new VerificationTypeInfo(typeBinding));
- switch (typeBinding.id) {
- case TypeIds.T_double:
- case TypeIds.T_long:
- resolvedPosition += 2;
- break;
- default:
- resolvedPosition++;
- }
- }
- }
- }
- }
- }
-
- private void initializeLocals(boolean isStatic, int currentPC, StackMapFrame currentFrame) {
- VerificationTypeInfo[] locals = currentFrame.locals;
- int localsLength = locals.length;
- int i = 0;
- if (!isStatic) {
- // we don't want to reset the first local if the method is not static
- i = 1;
- }
- for (; i < localsLength; i++) {
- locals[i] = null;
- }
- i = 0;
- locals: for (int max = this.codeStream.allLocalsCounter; i < max; i++) {
- LocalVariableBinding localVariable = this.codeStream.locals[i];
- if (localVariable == null) continue;
- int resolvedPosition = localVariable.resolvedPosition;
- final TypeBinding localVariableTypeBinding = localVariable.type;
- inits: for (int j = 0; j < localVariable.initializationCount; j++) {
- int startPC = localVariable.initializationPCs[j << 1];
- int endPC = localVariable.initializationPCs[(j << 1) + 1];
- if (currentPC < startPC) {
- continue inits;
- } else if (currentPC < endPC) {
- // the current local is an active local
- if (currentFrame.locals[resolvedPosition] == null) {
- currentFrame.locals[resolvedPosition] =
- new VerificationTypeInfo(
- localVariableTypeBinding);
- }
- continue locals;
- }
- }
- }
- }
- /**
- * INTERNAL USE-ONLY
- * Returns the most enclosing classfile of the receiver. This is used know to store the constant pool name
- * for all inner types of the receiver.
- * @return org.eclipse.jdt.internal.compiler.codegen.ClassFile
- */
- public ClassFile outerMostEnclosingClassFile() {
- ClassFile current = this;
- while (current.enclosingClassFile != null)
- current = current.enclosingClassFile;
- return current;
- }
-
- public void recordInnerClasses(TypeBinding binding) {
- recordInnerClasses(binding, false);
- }
- public void recordInnerClasses(TypeBinding binding, boolean onBottomForBug445231) {
- if (this.innerClassesBindings == null) {
- this.innerClassesBindings = new HashMap<>(INNER_CLASSES_SIZE);
- }
- ReferenceBinding innerClass = (ReferenceBinding) binding;
- this.innerClassesBindings.put(innerClass.erasure().unannotated(), onBottomForBug445231); // should not emit yet another inner class for Outer.@Inner Inner.
- ReferenceBinding enclosingType = innerClass.enclosingType();
- while (enclosingType != null
- && enclosingType.isNestedType()) {
- this.innerClassesBindings.put(enclosingType.erasure().unannotated(), onBottomForBug445231);
- enclosingType = enclosingType.enclosingType();
- }
- }
- public void recordNestMember(SourceTypeBinding binding) {
- SourceTypeBinding nestHost = binding != null ? binding.getNestHost() : null;
- if (nestHost != null && !binding.equals(nestHost)) {// member
- if (this.nestMembers == null) {
- this.nestMembers = new HashSet<>(NESTED_MEMBER_SIZE);
- }
- this.nestMembers.add(binding);
- }
- }
- public List getNestMembers() {
- if (this.nestMembers == null)
- return null;
- List list = this.nestMembers
- .stream()
- .map(s -> new String(s.constantPoolName()))
- .sorted()
- .collect(Collectors.toList());
- return list;
- }
-
- public int recordBootstrapMethod(FunctionalExpression expression) {
- if (this.bootstrapMethods == null) {
- this.bootstrapMethods = new ArrayList<>();
- }
- if (expression instanceof ReferenceExpression) {
- for (int i = 0; i < this.bootstrapMethods.size(); i++) {
- Object node = this.bootstrapMethods.get(i);
- if (node instanceof FunctionalExpression) {
- FunctionalExpression fexp = (FunctionalExpression) node;
- if (fexp.binding == expression.binding
- && TypeBinding.equalsEquals(fexp.expectedType(), expression.expectedType()))
- return expression.bootstrapMethodNumber = i;
- }
- }
- }
- this.bootstrapMethods.add(expression);
- // Record which bootstrap method was assigned to the expression
- return expression.bootstrapMethodNumber = this.bootstrapMethods.size() - 1;
- }
-
- public int recordBootstrapMethod(SwitchStatement switchStatement) {
- if (this.bootstrapMethods == null) {
- this.bootstrapMethods = new ArrayList<>();
- }
- this.bootstrapMethods.add(switchStatement);
- return this.bootstrapMethods.size() - 1;
- }
- public int recordBootstrapMethod(ResolvedCase resolvedCase) {
- if (this.bootstrapMethods == null) {
- this.bootstrapMethods = new ArrayList<>();
- }
- this.bootstrapMethods.add(resolvedCase);
- return this.bootstrapMethods.size() - 1;
- }
- public int recordBootstrapMethod(TypeBinding type) {
- if (this.bootstrapMethods == null) {
- this.bootstrapMethods = new ArrayList<>();
- } else {
- int idx = this.bootstrapMethods.indexOf(type);
- if (idx != -1) {
- return idx;
- }
- }
- this.bootstrapMethods.add(type);
- return this.bootstrapMethods.size() - 1;
- }
- public int recordBootstrapMethod(String expression) {
- if (this.bootstrapMethods == null) {
- this.bootstrapMethods = new ArrayList<>();
- }
- this.bootstrapMethods.add(expression);
- return this.bootstrapMethods.size() - 1;
- }
- public int recordBootstrapMethod(StringTemplate template) {
- if (this.bootstrapMethods == null) {
- this.bootstrapMethods = new ArrayList<>();
- }
- this.bootstrapMethods.add(template);
- return this.bootstrapMethods.size() - 1;
- }
- public void reset(/*@Nullable*/SourceTypeBinding typeBinding, CompilerOptions options) {
- // the code stream is reinitialized for each method
- if (typeBinding != null) {
- this.referenceBinding = typeBinding;
- this.isNestedType = typeBinding.isNestedType();
- } else {
- this.referenceBinding = null;
- this.isNestedType = false;
- }
- this.targetJDK = options.targetJDK;
- this.produceAttributes = options.produceDebugAttributes;
- if (this.targetJDK >= ClassFileConstants.JDK1_6) {
- this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
- if (this.targetJDK >= ClassFileConstants.JDK1_8) {
- this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
- if (!(this.codeStream instanceof TypeAnnotationCodeStream) && this.referenceBinding != null)
- this.codeStream = new TypeAnnotationCodeStream(this);
- if (options.produceMethodParameters) {
- this.produceAttributes |= ClassFileConstants.ATTR_METHOD_PARAMETERS;
- }
- }
- } else if (this.targetJDK == ClassFileConstants.CLDC_1_1) {
- this.targetJDK = ClassFileConstants.JDK1_1; // put back 45.3
- this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP;
- }
- this.bytes = null;
- this.constantPool.reset();
- this.codeStream.reset(this);
- this.constantPoolOffset = 0;
- this.contentsOffset = 0;
- this.creatingProblemType = false;
- this.enclosingClassFile = null;
- this.headerOffset = 0;
- this.methodCount = 0;
- this.methodCountOffset = 0;
- if (this.innerClassesBindings != null) {
- this.innerClassesBindings.clear();
- }
- if (this.nestMembers != null) {
- this.nestMembers.clear();
- }
- if (this.bootstrapMethods != null) {
- this.bootstrapMethods.clear();
- }
- this.missingTypes = null;
- this.visitedTypes = null;
- }
-
- /**
- * Resize the pool contents
- */
- private final void resizeContents(int minimalSize) {
- int length = this.contents.length;
- int toAdd = length;
- if (toAdd < minimalSize)
- toAdd = minimalSize;
- System.arraycopy(this.contents, 0, this.contents = new byte[length + toAdd], 0, length);
- }
-
- private VerificationTypeInfo retrieveLocal(int currentPC, int resolvedPosition) {
- for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
- LocalVariableBinding localVariable = this.codeStream.locals[i];
- if (localVariable == null) continue;
- if (resolvedPosition == localVariable.resolvedPosition) {
- inits: for (int j = 0; j < localVariable.initializationCount; j++) {
- int startPC = localVariable.initializationPCs[j << 1];
- int endPC = localVariable.initializationPCs[(j << 1) + 1];
- if (currentPC < startPC) {
- continue inits;
- } else if (currentPC < endPC) {
- // the current local is an active local
- return new VerificationTypeInfo(localVariable.type);
- }
- }
- }
- }
- return null;
- }
-
- private int scanType(char[] methodSignature, int index) {
- switch (methodSignature[index]) {
- case '[':
- // array type
- return scanType(methodSignature, index + 1);
- case 'L':
- return CharOperation.indexOf(';', methodSignature, index + 1);
- case 'Z':
- case 'B':
- case 'C':
- case 'D':
- case 'F':
- case 'I':
- case 'J':
- case 'S':
- return index;
- default:
- throw newIllegalArgumentException(methodSignature, index);
- }
- }
-
- private static IllegalArgumentException newIllegalArgumentException(char[] string, int index) {
- return new IllegalArgumentException("\"" + String.valueOf(string) + "\" at " + index); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- /**
- * INTERNAL USE-ONLY
- * This methods leaves the space for method counts recording.
- */
- public void setForMethodInfos() {
- // leave some space for the methodCount
- this.methodCountOffset = this.contentsOffset;
- this.contentsOffset += 2;
- }
-
- private List filterFakeFrames(Set realJumpTargets, Map frames, int codeLength) {
- // no more frame to generate
- // filter out "fake" frames
- realJumpTargets.remove(Integer.valueOf(codeLength));
- List result = new ArrayList<>();
- for (Iterator iterator = realJumpTargets.iterator(); iterator.hasNext(); ) {
- Integer jumpTarget = iterator.next();
- StackMapFrame frame = frames.get(jumpTarget);
- if (frame != null) {
- result.add(frame);
- }
- }
- Collections.sort(result, new Comparator() {
- @Override
- public int compare(StackMapFrame frame, StackMapFrame frame2) {
- return frame.pc - frame2.pc;
- }
- });
- return result;
- }
-
- private TypeBinding getTypeBinding(char[] typeConstantPoolName, Scope scope, boolean checkcast) {
- if (typeConstantPoolName.length == 1 && !checkcast) {
- // base type
- switch(typeConstantPoolName[0]) {
- case 'Z':
- return TypeBinding.BOOLEAN;
- case 'B':
- return TypeBinding.BYTE;
- case 'C':
- return TypeBinding.CHAR;
- case 'D':
- return TypeBinding.DOUBLE;
- case 'F':
- return TypeBinding.FLOAT;
- case 'I':
- return TypeBinding.INT;
- case 'J':
- return TypeBinding.LONG;
- case 'S':
- return TypeBinding.SHORT;
- default:
- return null;
- }
- } else if (typeConstantPoolName[0] == '[') {
- int dimensions = getDimensions(typeConstantPoolName);
- if (typeConstantPoolName.length - dimensions == 1) {
- // array of base types
- TypeBinding baseType = null;
- switch(typeConstantPoolName[typeConstantPoolName.length - 1]) {
- case 'Z':
- baseType = TypeBinding.BOOLEAN;
- break;
- case 'B':
- baseType = TypeBinding.BYTE;
- break;
- case 'C':
- baseType = TypeBinding.CHAR;
- break;
- case 'D':
- baseType = TypeBinding.DOUBLE;
- break;
- case 'F':
- baseType = TypeBinding.FLOAT;
- break;
- case 'I':
- baseType = TypeBinding.INT;
- break;
- case 'J':
- baseType = TypeBinding.LONG;
- break;
- case 'S':
- baseType = TypeBinding.SHORT;
- break;
- case 'V':
- baseType = TypeBinding.VOID;
- }
- return scope.createArrayType(baseType, dimensions);
- } else {
- // array of object types
- char[] typeName = CharOperation.subarray(typeConstantPoolName, dimensions + 1, typeConstantPoolName.length - 1);
- TypeBinding type = (TypeBinding) scope.getTypeOrPackage(CharOperation.splitOn('/', typeName));
- if (!type.isValidBinding()) {
- ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) type;
- if ((problemReferenceBinding.problemId() & ProblemReasons.InternalNameProvided) != 0
- || (problemReferenceBinding.problemId() & ProblemReasons.NotVisible) != 0) {
- type = problemReferenceBinding.closestMatch();
- } else if ((problemReferenceBinding.problemId() & ProblemReasons.NotFound) != 0 && this.innerClassesBindings != null) {
- // check local inner types to see if this is a anonymous type
- Set innerTypeBindings = this.innerClassesBindings.keySet();
- for (TypeBinding binding : innerTypeBindings) {
- if (CharOperation.equals(binding.constantPoolName(), typeName)) {
- type = binding;
- break;
- }
- }
- }
- }
- return scope.createArrayType(type, dimensions);
- }
- } else {
- char[] typeName = checkcast ? typeConstantPoolName : CharOperation.subarray(typeConstantPoolName, 1, typeConstantPoolName.length - 1);
- TypeBinding type = (TypeBinding) scope.getTypeOrPackage(CharOperation.splitOn('/', typeName));
- if (!type.isValidBinding()) {
- ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) type;
- if ((problemReferenceBinding.problemId() & ProblemReasons.InternalNameProvided) != 0
- || (problemReferenceBinding.problemId() & ProblemReasons.NotVisible) != 0) {
- type = problemReferenceBinding.closestMatch();
- } else if ((problemReferenceBinding.problemId() & ProblemReasons.NotFound) != 0 && this.innerClassesBindings != null) {
- // check local inner types to see if this is a anonymous type
- Set innerTypeBindings = this.innerClassesBindings.keySet();
- for (TypeBinding binding : innerTypeBindings) {
- if (CharOperation.equals(binding.constantPoolName(), typeName)) {
- type = binding;
- break;
- }
- }
- }
- }
- return type;
- }
- }
-
- private TypeBinding getNewTypeBinding(char[] typeConstantPoolName, Scope scope) {
- char[] typeName = typeConstantPoolName;
- if (this.innerClassesBindings != null && isLikelyLocalTypeName(typeName)) {
- // find local type in innerClassesBindings:
- Set innerTypeBindings = this.innerClassesBindings.keySet();
- for (TypeBinding binding : innerTypeBindings) {
- if (CharOperation.equals(binding.constantPoolName(), typeName))
- return binding;
- }
- }
- TypeBinding type = (TypeBinding) scope.getTypeOrPackage(CharOperation.splitOn('/', typeName));
- if (!type.isValidBinding()) {
- ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) type;
- if ((problemReferenceBinding.problemId() & ProblemReasons.InternalNameProvided) != 0
- || (problemReferenceBinding.problemId() & ProblemReasons.NotVisible) != 0) {
- type = problemReferenceBinding.closestMatch();
- }
- }
- return type;
- }
-
- private boolean isLikelyLocalTypeName(char[] typeName) {
- int dollarPos = CharOperation.lastIndexOf('$', typeName);
- while (dollarPos != -1 && dollarPos+1 < typeName.length) {
- if (Character.isDigit(typeName[dollarPos+1]))
- return true; // name segment starts with a digit => likely a local type (but still "$0" etc. could be part of the source name)
- dollarPos = CharOperation.lastIndexOf('$', typeName, 0, dollarPos-1);
- }
- return false;
- }
-
- private TypeBinding getANewArrayTypeBinding(char[] typeConstantPoolName, Scope scope) {
- if (typeConstantPoolName[0] == '[') {
- int dimensions = getDimensions(typeConstantPoolName);
- if (typeConstantPoolName.length - dimensions == 1) {
- // array of base types
- TypeBinding baseType = null;
- switch(typeConstantPoolName[typeConstantPoolName.length - 1]) {
- case 'Z':
- baseType = TypeBinding.BOOLEAN;
- break;
- case 'B':
- baseType = TypeBinding.BYTE;
- break;
- case 'C':
- baseType = TypeBinding.CHAR;
- break;
- case 'D':
- baseType = TypeBinding.DOUBLE;
- break;
- case 'F':
- baseType = TypeBinding.FLOAT;
- break;
- case 'I':
- baseType = TypeBinding.INT;
- break;
- case 'J':
- baseType = TypeBinding.LONG;
- break;
- case 'S':
- baseType = TypeBinding.SHORT;
- break;
- case 'V':
- baseType = TypeBinding.VOID;
- }
- return scope.createArrayType(baseType, dimensions);
- } else {
- // array of object types
- char[] elementTypeClassName = CharOperation.subarray(typeConstantPoolName, dimensions + 1, typeConstantPoolName.length - 1);
- TypeBinding type = (TypeBinding) scope.getTypeOrPackage(
- CharOperation.splitOn('/', elementTypeClassName));
- if (!type.isValidBinding()) {
- ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) type;
- if ((problemReferenceBinding.problemId() & ProblemReasons.InternalNameProvided) != 0
- || (problemReferenceBinding.problemId() & ProblemReasons.NotVisible) != 0) {
- type = problemReferenceBinding.closestMatch();
- } else if ((problemReferenceBinding.problemId() & ProblemReasons.NotFound) != 0 && this.innerClassesBindings != null) {
- // check local inner types to see if this is a anonymous type
- Set innerTypeBindings = this.innerClassesBindings.keySet();
- for (TypeBinding binding : innerTypeBindings) {
- if (CharOperation.equals(binding.constantPoolName(), elementTypeClassName)) {
- type = binding;
- break;
- }
- }
- }
- }
- return scope.createArrayType(type, dimensions);
- }
- } else {
- TypeBinding type = (TypeBinding) scope.getTypeOrPackage(
- CharOperation.splitOn('/', typeConstantPoolName));
- if (!type.isValidBinding()) {
- ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) type;
- if ((problemReferenceBinding.problemId() & ProblemReasons.InternalNameProvided) != 0
- || (problemReferenceBinding.problemId() & ProblemReasons.NotVisible) != 0) {
- type = problemReferenceBinding.closestMatch();
- } else if ((problemReferenceBinding.problemId() & ProblemReasons.NotFound) != 0 && this.innerClassesBindings != null) {
- // check local inner types to see if this is a anonymous type
- Set innerTypeBindings = this.innerClassesBindings.keySet();
- for (TypeBinding binding : innerTypeBindings) {
- if (CharOperation.equals(binding.constantPoolName(), typeConstantPoolName)) {
- type = binding;
- break;
- }
- }
- }
- }
- return type;
- }
- }
-
- public List traverse(
- MethodBinding methodBinding,
- int maxLocals,
- byte[] bytecodes,
- int codeOffset,
- int codeLength,
- Map frames,
- boolean isClinit,
- Scope scope) {
- Set realJumpTarget = new HashSet<>();
-
- StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
- int[] framePositions = stackMapFrameCodeStream.getFramePositions();
- int pc = codeOffset;
- int index;
- int[] constantPoolOffsets = this.constantPool.offsets;
- byte[] poolContents = this.constantPool.poolContent;
-
- // set initial values for frame positions
- int indexInFramePositions = 0;
- int framePositionsLength = framePositions.length;
- int currentFramePosition = framePositions[0];
-
- // set initial values for exception markers
- int indexInExceptionMarkers = 0;
- ExceptionMarker[] exceptionMarkers= stackMapFrameCodeStream.getExceptionMarkers();
- int exceptionsMarkersLength = exceptionMarkers == null ? 0 : exceptionMarkers.length;
- boolean hasExceptionMarkers = exceptionsMarkersLength != 0;
- ExceptionMarker exceptionMarker = null;
- if (hasExceptionMarkers) {
- exceptionMarker = exceptionMarkers[0];
- }
-
- StackMapFrame frame = new StackMapFrame(maxLocals);
- if (!isClinit) {
- initializeDefaultLocals(frame, methodBinding, maxLocals, codeLength);
- }
- frame.pc = -1;
- add(frames, frame.duplicate(), scope);
- addRealJumpTarget(realJumpTarget, -1);
- for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
- ExceptionLabel exceptionLabel = this.codeStream.exceptionLabels[i];
- if (exceptionLabel != null) {
- addRealJumpTarget(realJumpTarget, exceptionLabel.position);
- }
- }
- while (true) {
- int currentPC = pc - codeOffset;
- if (hasExceptionMarkers && exceptionMarker.pc == currentPC) {
- frame.numberOfStackItems = 0;
- frame.addStackItem(new VerificationTypeInfo(exceptionMarker.getBinding()));
- indexInExceptionMarkers++;
- if (indexInExceptionMarkers < exceptionsMarkersLength) {
- exceptionMarker = exceptionMarkers[indexInExceptionMarkers];
- } else {
- hasExceptionMarkers = false;
- }
- }
- if (currentFramePosition < currentPC) {
- do {
- indexInFramePositions++;
- if (indexInFramePositions < framePositionsLength) {
- currentFramePosition = framePositions[indexInFramePositions];
- } else {
- currentFramePosition = Integer.MAX_VALUE;
- }
- } while (currentFramePosition < currentPC);
- }
- if (currentFramePosition == currentPC) {
- // need to build a new frame and create a stack map attribute entry
- StackMapFrame currentFrame = frames.get(Integer.valueOf(currentPC));
- if (currentFrame == null) {
- currentFrame = createNewFrame(currentPC, frame, isClinit, methodBinding);
- add(frames, currentFrame, scope);
- } else {
- frame = currentFrame.merge(frame.duplicate(), scope).duplicate();
- }
- indexInFramePositions++;
- if (indexInFramePositions < framePositionsLength) {
- currentFramePosition = framePositions[indexInFramePositions];
- } else {
- currentFramePosition = Integer.MAX_VALUE;
- }
- }
- byte opcode = (byte) u1At(bytecodes, 0, pc);
- inspectFrame(currentPC, frame);
- switch (opcode) {
- case Opcodes.OPC_nop:
- pc++;
- break;
- case Opcodes.OPC_aconst_null:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.NULL));
- pc++;
- break;
- case Opcodes.OPC_iconst_m1:
- case Opcodes.OPC_iconst_0:
- case Opcodes.OPC_iconst_1:
- case Opcodes.OPC_iconst_2:
- case Opcodes.OPC_iconst_3:
- case Opcodes.OPC_iconst_4:
- case Opcodes.OPC_iconst_5:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
- pc++;
- break;
- case Opcodes.OPC_lconst_0:
- case Opcodes.OPC_lconst_1:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
- pc++;
- break;
- case Opcodes.OPC_fconst_0:
- case Opcodes.OPC_fconst_1:
- case Opcodes.OPC_fconst_2:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
- pc++;
- break;
- case Opcodes.OPC_dconst_0:
- case Opcodes.OPC_dconst_1:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
- pc++;
- break;
- case Opcodes.OPC_bipush:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.BYTE));
- pc += 2;
- break;
- case Opcodes.OPC_sipush:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.SHORT));
- pc += 3;
- break;
- case Opcodes.OPC_ldc:
- index = u1At(bytecodes, 1, pc);
- switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
- case ClassFileConstants.StringTag:
- frame
- .addStackItem(new VerificationTypeInfo(scope.getJavaLangString()));
- break;
- case ClassFileConstants.IntegerTag:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
- break;
- case ClassFileConstants.FloatTag:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
- break;
- case ClassFileConstants.ClassTag:
- frame.addStackItem(new VerificationTypeInfo(scope.getJavaLangClass()));
- }
- pc += 2;
- break;
- case Opcodes.OPC_ldc_w:
- index = u2At(bytecodes, 1, pc);
- switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
- case ClassFileConstants.StringTag:
- frame
- .addStackItem(new VerificationTypeInfo(scope.getJavaLangString()));
- break;
- case ClassFileConstants.IntegerTag:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
- break;
- case ClassFileConstants.FloatTag:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
- break;
- case ClassFileConstants.ClassTag:
- frame.addStackItem(new VerificationTypeInfo(scope.getJavaLangClass()));
- }
- pc += 3;
- break;
- case Opcodes.OPC_ldc2_w:
- index = u2At(bytecodes, 1, pc);
- switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
- case ClassFileConstants.DoubleTag:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
- break;
- case ClassFileConstants.LongTag:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
- break;
- }
- pc += 3;
- break;
- case Opcodes.OPC_iload:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
- pc += 2;
- break;
- case Opcodes.OPC_lload:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
- pc += 2;
- break;
- case Opcodes.OPC_fload:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
- pc += 2;
- break;
- case Opcodes.OPC_dload:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
- pc += 2;
- break;
- case Opcodes.OPC_aload:
- index = u1At(bytecodes, 1, pc);
- VerificationTypeInfo localsN = retrieveLocal(currentPC, index);
- frame.addStackItem(localsN);
- pc += 2;
- break;
- case Opcodes.OPC_iload_0:
- case Opcodes.OPC_iload_1:
- case Opcodes.OPC_iload_2:
- case Opcodes.OPC_iload_3:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
- pc++;
- break;
- case Opcodes.OPC_lload_0:
- case Opcodes.OPC_lload_1:
- case Opcodes.OPC_lload_2:
- case Opcodes.OPC_lload_3:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
- pc++;
- break;
- case Opcodes.OPC_fload_0:
- case Opcodes.OPC_fload_1:
- case Opcodes.OPC_fload_2:
- case Opcodes.OPC_fload_3:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
- pc++;
- break;
- case Opcodes.OPC_dload_0:
- case Opcodes.OPC_dload_1:
- case Opcodes.OPC_dload_2:
- case Opcodes.OPC_dload_3:
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
- pc++;
- break;
- case Opcodes.OPC_aload_0:
- VerificationTypeInfo locals0 = frame.locals[0];
- if (locals0 == null || locals0.tag != VerificationTypeInfo.ITEM_UNINITIALIZED_THIS) {
- // special case to handle uninitialized object
- locals0 = retrieveLocal(currentPC, 0);
- }
- frame.addStackItem(locals0);
- pc++;
- break;
- case Opcodes.OPC_aload_1:
- VerificationTypeInfo locals1 = retrieveLocal(currentPC, 1);
- frame.addStackItem(locals1);
- pc++;
- break;
- case Opcodes.OPC_aload_2:
- VerificationTypeInfo locals2 = retrieveLocal(currentPC, 2);
- frame.addStackItem(locals2);
- pc++;
- break;
- case Opcodes.OPC_aload_3:
- VerificationTypeInfo locals3 = retrieveLocal(currentPC, 3);
- frame.addStackItem(locals3);
- pc++;
- break;
- case Opcodes.OPC_iaload:
- frame.numberOfStackItems -=2;
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
- pc++;
- break;
- case Opcodes.OPC_laload:
- frame.numberOfStackItems -=2;
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
- pc++;
- break;
- case Opcodes.OPC_faload:
- frame.numberOfStackItems -=2;
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
- pc++;
- break;
- case Opcodes.OPC_daload:
- frame.numberOfStackItems -=2;
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
- pc++;
- break;
- case Opcodes.OPC_aaload:
- frame.numberOfStackItems--;
- frame.replaceWithElementType();
- pc++;
- break;
- case Opcodes.OPC_baload:
- frame.numberOfStackItems -=2;
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.BYTE));
- pc++;
- break;
- case Opcodes.OPC_caload:
- frame.numberOfStackItems -=2;
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.CHAR));
- pc++;
- break;
- case Opcodes.OPC_saload:
- frame.numberOfStackItems -=2;
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.SHORT));
- pc++;
- break;
- case Opcodes.OPC_istore:
- case Opcodes.OPC_lstore:
- case Opcodes.OPC_fstore:
- case Opcodes.OPC_dstore:
- frame.numberOfStackItems--;
- pc += 2;
- break;
- case Opcodes.OPC_astore:
- index = u1At(bytecodes, 1, pc);
- frame.numberOfStackItems--;
- pc += 2;
- break;
- case Opcodes.OPC_astore_0:
- frame.locals[0] = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- pc++;
- break;
- case Opcodes.OPC_astore_1:
- case Opcodes.OPC_astore_2:
- case Opcodes.OPC_astore_3:
- case Opcodes.OPC_istore_0:
- case Opcodes.OPC_istore_1:
- case Opcodes.OPC_istore_2:
- case Opcodes.OPC_istore_3:
- case Opcodes.OPC_lstore_0:
- case Opcodes.OPC_lstore_1:
- case Opcodes.OPC_lstore_2:
- case Opcodes.OPC_lstore_3:
- case Opcodes.OPC_fstore_0:
- case Opcodes.OPC_fstore_1:
- case Opcodes.OPC_fstore_2:
- case Opcodes.OPC_fstore_3:
- case Opcodes.OPC_dstore_0:
- case Opcodes.OPC_dstore_1:
- case Opcodes.OPC_dstore_2:
- case Opcodes.OPC_dstore_3:
- frame.numberOfStackItems--;
- pc++;
- break;
- case Opcodes.OPC_iastore:
- case Opcodes.OPC_lastore:
- case Opcodes.OPC_fastore:
- case Opcodes.OPC_dastore:
- case Opcodes.OPC_aastore:
- case Opcodes.OPC_bastore:
- case Opcodes.OPC_castore:
- case Opcodes.OPC_sastore:
- frame.numberOfStackItems-=3;
- pc++;
- break;
- case Opcodes.OPC_pop:
- frame.numberOfStackItems--;
- pc++;
- break;
- case Opcodes.OPC_pop2:
- int numberOfStackItems = frame.numberOfStackItems;
- switch(frame.stackItems[numberOfStackItems - 1].id()) {
- case TypeIds.T_long :
- case TypeIds.T_double :
- frame.numberOfStackItems--;
- break;
- default:
- frame.numberOfStackItems -= 2;
- }
- pc++;
- break;
- case Opcodes.OPC_dup:
- frame.addStackItem(frame.stackItems[frame.numberOfStackItems - 1]);
- pc++;
- break;
- case Opcodes.OPC_dup_x1:
- VerificationTypeInfo info = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- VerificationTypeInfo info2 = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- frame.addStackItem(info);
- frame.addStackItem(info2);
- frame.addStackItem(info);
- pc++;
- break;
- case Opcodes.OPC_dup_x2:
- info = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- info2 = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- switch(info2.id()) {
- case TypeIds.T_long :
- case TypeIds.T_double :
- frame.addStackItem(info);
- frame.addStackItem(info2);
- frame.addStackItem(info);
- break;
- default:
- numberOfStackItems = frame.numberOfStackItems;
- VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
- frame.numberOfStackItems--;
- frame.addStackItem(info);
- frame.addStackItem(info3);
- frame.addStackItem(info2);
- frame.addStackItem(info);
- }
- pc++;
- break;
- case Opcodes.OPC_dup2:
- info = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- switch(info.id()) {
- case TypeIds.T_double :
- case TypeIds.T_long :
- frame.addStackItem(info);
- frame.addStackItem(info);
- break;
- default:
- info2 = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- frame.addStackItem(info2);
- frame.addStackItem(info);
- frame.addStackItem(info2);
- frame.addStackItem(info);
- }
- pc++;
- break;
- case Opcodes.OPC_dup2_x1:
- info = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- info2 = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- switch(info.id()) {
- case TypeIds.T_double :
- case TypeIds.T_long :
- frame.addStackItem(info);
- frame.addStackItem(info2);
- frame.addStackItem(info);
- break;
- default:
- VerificationTypeInfo info3 = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- frame.addStackItem(info2);
- frame.addStackItem(info);
- frame.addStackItem(info3);
- frame.addStackItem(info2);
- frame.addStackItem(info);
- }
- pc++;
- break;
- case Opcodes.OPC_dup2_x2:
- numberOfStackItems = frame.numberOfStackItems;
- info = frame.stackItems[numberOfStackItems - 1];
- frame.numberOfStackItems--;
- info2 = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- switch(info.id()) {
- case TypeIds.T_long :
- case TypeIds.T_double :
- switch(info2.id()) {
- case TypeIds.T_long :
- case TypeIds.T_double :
- // form 4
- frame.addStackItem(info);
- frame.addStackItem(info2);
- frame.addStackItem(info);
- break;
- default:
- // form 2
- numberOfStackItems = frame.numberOfStackItems;
- VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
- frame.numberOfStackItems--;
- frame.addStackItem(info);
- frame.addStackItem(info3);
- frame.addStackItem(info2);
- frame.addStackItem(info);
- }
- break;
- default:
- numberOfStackItems = frame.numberOfStackItems;
- VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
- frame.numberOfStackItems--;
- switch(info3.id()) {
- case TypeIds.T_long :
- case TypeIds.T_double :
- // form 3
- frame.addStackItem(info2);
- frame.addStackItem(info);
- frame.addStackItem(info3);
- frame.addStackItem(info2);
- frame.addStackItem(info);
- break;
- default:
- // form 1
- numberOfStackItems = frame.numberOfStackItems;
- VerificationTypeInfo info4 = frame.stackItems[numberOfStackItems - 1];
- frame.numberOfStackItems--;
- frame.addStackItem(info2);
- frame.addStackItem(info);
- frame.addStackItem(info4);
- frame.addStackItem(info3);
- frame.addStackItem(info2);
- frame.addStackItem(info);
- }
- }
- pc++;
- break;
- case Opcodes.OPC_swap:
- numberOfStackItems = frame.numberOfStackItems;
- info = frame.stackItems[numberOfStackItems - 1];
- info2 = frame.stackItems[numberOfStackItems - 2];
- frame.stackItems[numberOfStackItems - 1] = info2;
- frame.stackItems[numberOfStackItems - 2] = info;
- pc++;
- break;
- case Opcodes.OPC_iadd:
- case Opcodes.OPC_ladd:
- case Opcodes.OPC_fadd:
- case Opcodes.OPC_dadd:
- case Opcodes.OPC_isub:
- case Opcodes.OPC_lsub:
- case Opcodes.OPC_fsub:
- case Opcodes.OPC_dsub:
- case Opcodes.OPC_imul:
- case Opcodes.OPC_lmul:
- case Opcodes.OPC_fmul:
- case Opcodes.OPC_dmul:
- case Opcodes.OPC_idiv:
- case Opcodes.OPC_ldiv:
- case Opcodes.OPC_fdiv:
- case Opcodes.OPC_ddiv:
- case Opcodes.OPC_irem:
- case Opcodes.OPC_lrem:
- case Opcodes.OPC_frem:
- case Opcodes.OPC_drem:
- case Opcodes.OPC_ishl:
- case Opcodes.OPC_lshl:
- case Opcodes.OPC_ishr:
- case Opcodes.OPC_lshr:
- case Opcodes.OPC_iushr:
- case Opcodes.OPC_lushr:
- case Opcodes.OPC_iand:
- case Opcodes.OPC_land:
- case Opcodes.OPC_ior:
- case Opcodes.OPC_lor:
- case Opcodes.OPC_ixor:
- case Opcodes.OPC_lxor:
- frame.numberOfStackItems--;
- pc++;
- break;
- case Opcodes.OPC_ineg:
- case Opcodes.OPC_lneg:
- case Opcodes.OPC_fneg:
- case Opcodes.OPC_dneg:
- pc++;
- break;
- case Opcodes.OPC_iinc:
- pc += 3;
- break;
- case Opcodes.OPC_i2l:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
- pc++;
- break;
- case Opcodes.OPC_i2f:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
- pc++;
- break;
- case Opcodes.OPC_i2d:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
- pc++;
- break;
- case Opcodes.OPC_l2i:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
- pc++;
- break;
- case Opcodes.OPC_l2f:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
- pc++;
- break;
- case Opcodes.OPC_l2d:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
- pc++;
- break;
- case Opcodes.OPC_f2i:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
- pc++;
- break;
- case Opcodes.OPC_f2l:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
- pc++;
- break;
- case Opcodes.OPC_f2d:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
- pc++;
- break;
- case Opcodes.OPC_d2i:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
- pc++;
- break;
- case Opcodes.OPC_d2l:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
- pc++;
- break;
- case Opcodes.OPC_d2f:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
- pc++;
- break;
- case Opcodes.OPC_i2b:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.BYTE);
- pc++;
- break;
- case Opcodes.OPC_i2c:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.CHAR);
- pc++;
- break;
- case Opcodes.OPC_i2s:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.SHORT);
- pc++;
- break;
- case Opcodes.OPC_lcmp:
- case Opcodes.OPC_fcmpl:
- case Opcodes.OPC_fcmpg:
- case Opcodes.OPC_dcmpl:
- case Opcodes.OPC_dcmpg:
- frame.numberOfStackItems-=2;
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
- pc++;
- break;
- case Opcodes.OPC_ifeq:
- case Opcodes.OPC_ifne:
- case Opcodes.OPC_iflt:
- case Opcodes.OPC_ifge:
- case Opcodes.OPC_ifgt:
- case Opcodes.OPC_ifle:
- frame.numberOfStackItems--;
- int jumpPC = currentPC + i2At(bytecodes, 1, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
- pc += 3;
- break;
- case Opcodes.OPC_if_icmpeq:
- case Opcodes.OPC_if_icmpne:
- case Opcodes.OPC_if_icmplt:
- case Opcodes.OPC_if_icmpge:
- case Opcodes.OPC_if_icmpgt:
- case Opcodes.OPC_if_icmple:
- case Opcodes.OPC_if_acmpeq:
- case Opcodes.OPC_if_acmpne:
- frame.numberOfStackItems -= 2;
- jumpPC = currentPC + i2At(bytecodes, 1, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
- pc += 3;
- break;
- case Opcodes.OPC_goto:
- jumpPC = currentPC + i2At(bytecodes, 1, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
- pc += 3;
- addRealJumpTarget(realJumpTarget, pc - codeOffset);
- break;
- case Opcodes.OPC_tableswitch:
- frame.numberOfStackItems--;
- pc++;
- while (((pc - codeOffset) & 0x03) != 0) {
- pc++;
- }
- // default offset
- jumpPC = currentPC + i4At(bytecodes, 0, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
- pc += 4; // default
- int low = i4At(bytecodes, 0, pc);
- pc += 4;
- int high = i4At(bytecodes, 0, pc);
- pc += 4;
- int length = high - low + 1;
- for (int i = 0; i < length; i++) {
- // pair offset
- jumpPC = currentPC + i4At(bytecodes, 0, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
- pc += 4;
- }
- break;
- case Opcodes.OPC_lookupswitch:
- frame.numberOfStackItems--;
- pc++;
- while (((pc - codeOffset) & 0x03) != 0) {
- pc++;
- }
- jumpPC = currentPC + i4At(bytecodes, 0, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
- pc += 4; // default offset
- int npairs = (int) u4At(bytecodes, 0, pc);
- pc += 4; // npair value
- for (int i = 0; i < npairs; i++) {
- pc += 4; // case value
- // pair offset
- jumpPC = currentPC + i4At(bytecodes, 0, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
- pc += 4;
- }
- break;
- case Opcodes.OPC_ireturn:
- case Opcodes.OPC_lreturn:
- case Opcodes.OPC_freturn:
- case Opcodes.OPC_dreturn:
- case Opcodes.OPC_areturn:
- frame.numberOfStackItems--;
- pc++;
- addRealJumpTarget(realJumpTarget, pc - codeOffset);
- break;
- case Opcodes.OPC_return:
- pc++;
- addRealJumpTarget(realJumpTarget, pc - codeOffset);
- break;
- case Opcodes.OPC_getstatic:
- index = u2At(bytecodes, 1, pc);
- int nameAndTypeIndex = u2At(poolContents, 3,
- constantPoolOffsets[index]);
- int utf8index = u2At(poolContents, 3,
- constantPoolOffsets[nameAndTypeIndex]);
- char[] descriptor = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- TypeBinding typeBinding = getTypeBinding(descriptor, scope, false);
- if (typeBinding != null) {
- frame.addStackItem(new VerificationTypeInfo(typeBinding));
- }
- pc += 3;
- break;
- case Opcodes.OPC_putstatic:
- frame.numberOfStackItems--;
- pc += 3;
- break;
- case Opcodes.OPC_getfield:
- index = u2At(bytecodes, 1, pc);
- nameAndTypeIndex = u2At(poolContents, 3,
- constantPoolOffsets[index]);
- utf8index = u2At(poolContents, 3,
- constantPoolOffsets[nameAndTypeIndex]);
- descriptor = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- frame.numberOfStackItems--;
- typeBinding = getTypeBinding(descriptor, scope, false);
- if (typeBinding != null) {
- frame.addStackItem(new VerificationTypeInfo(typeBinding));
- }
- pc += 3;
- break;
- case Opcodes.OPC_putfield:
- frame.numberOfStackItems -= 2;
- pc += 3;
- break;
- case Opcodes.OPC_invokevirtual:
- index = u2At(bytecodes, 1, pc);
- nameAndTypeIndex = u2At(poolContents, 3,
- constantPoolOffsets[index]);
- utf8index = u2At(poolContents, 3,
- constantPoolOffsets[nameAndTypeIndex]);
- descriptor = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- utf8index = u2At(poolContents, 1,
- constantPoolOffsets[nameAndTypeIndex]);
- char[] name = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
- char[] returnType = getReturnType(descriptor);
- typeBinding = getTypeBinding(returnType, scope, false);
- if (typeBinding != null) {
- frame.addStackItem(new VerificationTypeInfo(typeBinding));
- }
- pc += 3;
- break;
- case Opcodes.OPC_invokedynamic:
- index = u2At(bytecodes, 1, pc);
- nameAndTypeIndex = u2At(poolContents, 3,
- constantPoolOffsets[index]);
- utf8index = u2At(poolContents, 3,
- constantPoolOffsets[nameAndTypeIndex]);
- descriptor = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- frame.numberOfStackItems -= getParametersCount(descriptor);
- returnType = getReturnType(descriptor);
- typeBinding = getTypeBinding(returnType, scope, false);
- if (typeBinding != null) {
- frame.addStackItem(new VerificationTypeInfo(typeBinding));
- }
- pc += 5;
- break;
- case Opcodes.OPC_invokespecial:
- index = u2At(bytecodes, 1, pc);
- nameAndTypeIndex = u2At(poolContents, 3,
- constantPoolOffsets[index]);
- utf8index = u2At(poolContents, 3,
- constantPoolOffsets[nameAndTypeIndex]);
- descriptor = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- utf8index = u2At(poolContents, 1,
- constantPoolOffsets[nameAndTypeIndex]);
- name = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- frame.numberOfStackItems -= getParametersCount(descriptor);
- if (CharOperation.equals(ConstantPool.Init, name)) {
- // constructor
- frame.stackItems[frame.numberOfStackItems - 1].tag = VerificationTypeInfo.ITEM_OBJECT;
- }
- frame.numberOfStackItems--;
- returnType = getReturnType(descriptor);
- typeBinding = getTypeBinding(returnType, scope, false);
- if (typeBinding != null) {
- frame.addStackItem(new VerificationTypeInfo(typeBinding));
- }
- pc += 3;
- break;
- case Opcodes.OPC_invokestatic:
- index = u2At(bytecodes, 1, pc);
- nameAndTypeIndex = u2At(poolContents, 3,
- constantPoolOffsets[index]);
- utf8index = u2At(poolContents, 3,
- constantPoolOffsets[nameAndTypeIndex]);
- descriptor = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- utf8index = u2At(poolContents, 1,
- constantPoolOffsets[nameAndTypeIndex]);
- name = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- frame.numberOfStackItems -= getParametersCount(descriptor);
- returnType = getReturnType(descriptor);
- typeBinding = getTypeBinding(returnType, scope, false);
- if (typeBinding != null) {
- frame.addStackItem(new VerificationTypeInfo(typeBinding));
- }
- pc += 3;
- break;
- case Opcodes.OPC_invokeinterface:
- index = u2At(bytecodes, 1, pc);
- nameAndTypeIndex = u2At(poolContents, 3,
- constantPoolOffsets[index]);
- utf8index = u2At(poolContents, 3,
- constantPoolOffsets[nameAndTypeIndex]);
- descriptor = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- utf8index = u2At(poolContents, 1,
- constantPoolOffsets[nameAndTypeIndex]);
- name = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- // we don't need count and args
- // u1At(bytecodes, 3, pc); // count
- // u1At(bytecodes, 4, pc); // extra args
- frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
- returnType = getReturnType(descriptor);
- typeBinding = getTypeBinding(returnType, scope, false);
- if (typeBinding != null) {
- frame.addStackItem(new VerificationTypeInfo(typeBinding));
- }
- pc += 5;
- break;
- case Opcodes.OPC_new:
- index = u2At(bytecodes, 1, pc);
- utf8index = u2At(poolContents, 1,
- constantPoolOffsets[index]);
- char[] className = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- typeBinding = getNewTypeBinding(className, scope);
- VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(VerificationTypeInfo.ITEM_UNINITIALIZED, typeBinding);
- verificationTypeInfo.offset = currentPC;
- frame.addStackItem(verificationTypeInfo);
- pc += 3;
- break;
- case Opcodes.OPC_newarray:
- TypeBinding arrayType = null;
- switch (u1At(bytecodes, 1, pc)) {
- case ClassFileConstants.INT_ARRAY :
- arrayType = scope.createArrayType(TypeBinding.INT, 1);
- break;
- case ClassFileConstants.BYTE_ARRAY :
- arrayType = scope.createArrayType(TypeBinding.BYTE, 1);
- break;
- case ClassFileConstants.BOOLEAN_ARRAY :
- arrayType = scope.createArrayType(TypeBinding.BOOLEAN, 1);
- break;
- case ClassFileConstants.SHORT_ARRAY :
- arrayType = scope.createArrayType(TypeBinding.SHORT, 1);
- break;
- case ClassFileConstants.CHAR_ARRAY :
- arrayType = scope.createArrayType(TypeBinding.CHAR, 1);
- break;
- case ClassFileConstants.LONG_ARRAY :
- arrayType = scope.createArrayType(TypeBinding.LONG, 1);
- break;
- case ClassFileConstants.FLOAT_ARRAY :
- arrayType = scope.createArrayType(TypeBinding.FLOAT, 1);
- break;
- case ClassFileConstants.DOUBLE_ARRAY :
- arrayType = scope.createArrayType(TypeBinding.DOUBLE, 1);
- break;
- }
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(arrayType);
- pc += 2;
- break;
- case Opcodes.OPC_anewarray:
- index = u2At(bytecodes, 1, pc);
- utf8index = u2At(poolContents, 1,
- constantPoolOffsets[index]);
- className = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- frame.numberOfStackItems--;
- typeBinding = getANewArrayTypeBinding(className, scope);
- if (typeBinding != null) {
- if (typeBinding.isArrayType()) {
- ArrayBinding arrayBinding = (ArrayBinding) typeBinding;
- frame.addStackItem(new VerificationTypeInfo(scope.createArrayType(arrayBinding.leafComponentType(), arrayBinding.dimensions + 1)));
- } else {
- frame.addStackItem(new VerificationTypeInfo(scope.createArrayType(typeBinding, 1)));
- }
- }
- pc += 3;
- break;
- case Opcodes.OPC_arraylength:
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
- pc++;
- break;
- case Opcodes.OPC_athrow:
- frame.numberOfStackItems--;
- pc++;
- addRealJumpTarget(realJumpTarget, pc - codeOffset);
- break;
- case Opcodes.OPC_checkcast:
- index = u2At(bytecodes, 1, pc);
- utf8index = u2At(poolContents, 1,
- constantPoolOffsets[index]);
- className = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- typeBinding = getTypeBinding(className, scope, true);
- if (typeBinding != null) {
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(typeBinding);
- }
- pc += 3;
- break;
- case Opcodes.OPC_instanceof:
- // no need to know the class index = u2At(bytecodes, 1, pc);
- frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
- pc += 3;
- break;
- case Opcodes.OPC_monitorenter:
- case Opcodes.OPC_monitorexit:
- frame.numberOfStackItems--;
- pc++;
- break;
- case Opcodes.OPC_wide:
- opcode = (byte) u1At(bytecodes, 1, pc);
- if (opcode == Opcodes.OPC_iinc) {
- // index = u2At(bytecodes, 2, pc);
- // i2At(bytecodes, 4, pc); // const
- // we don't need the index and the const value
- pc += 6;
- } else {
- index = u2At(bytecodes, 2, pc);
- // need to handle iload, fload, aload, lload, dload, istore, fstore, astore, lstore or dstore
- switch(opcode) {
- case Opcodes.OPC_iload :
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.INT));
- break;
- case Opcodes.OPC_fload :
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.FLOAT));
- break;
- case Opcodes.OPC_aload :
- localsN = frame.locals[index];
- if (localsN == null) {
- localsN = retrieveLocal(currentPC, index);
- }
- frame.addStackItem(localsN);
- break;
- case Opcodes.OPC_lload :
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.LONG));
- break;
- case Opcodes.OPC_dload :
- frame.addStackItem(new VerificationTypeInfo(TypeBinding.DOUBLE));
- break;
- case Opcodes.OPC_istore :
- frame.numberOfStackItems--;
- break;
- case Opcodes.OPC_fstore :
- frame.numberOfStackItems--;
- break;
- case Opcodes.OPC_astore :
- frame.locals[index] = frame.stackItems[frame.numberOfStackItems - 1];
- frame.numberOfStackItems--;
- break;
- case Opcodes.OPC_lstore :
- frame.numberOfStackItems--;
- break;
- case Opcodes.OPC_dstore :
- frame.numberOfStackItems--;
- break;
- }
- pc += 4;
- }
- break;
- case Opcodes.OPC_multianewarray:
- index = u2At(bytecodes, 1, pc);
- utf8index = u2At(poolContents, 1,
- constantPoolOffsets[index]);
- className = utf8At(poolContents,
- constantPoolOffsets[utf8index] + 3, u2At(
- poolContents, 1,
- constantPoolOffsets[utf8index]));
- int dimensions = u1At(bytecodes, 3, pc); // dimensions
- frame.numberOfStackItems -= dimensions;
- // class name is already the name of the right array type with all dimensions
- typeBinding = getTypeBinding(className, scope, false);
- if (typeBinding != null) {
- frame.addStackItem(new VerificationTypeInfo(typeBinding));
- }
- pc += 4;
- break;
- case Opcodes.OPC_ifnull:
- case Opcodes.OPC_ifnonnull:
- frame.numberOfStackItems--;
- jumpPC = currentPC + i2At(bytecodes, 1, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
- pc += 3;
- break;
- case Opcodes.OPC_goto_w:
- jumpPC = currentPC + i4At(bytecodes, 1, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
- pc += 5;
- addRealJumpTarget(realJumpTarget, pc - codeOffset); // handle infinite loop
- break;
- default: // should not occur
- if (this.codeStream.methodDeclaration != null) {
- this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError(
- Messages.bind(
- Messages.abort_invalidOpcode,
- new Object[] {
- Byte.valueOf(opcode),
- Integer.valueOf(pc),
- new String(methodBinding.shortReadableName()),
- }),
- this.codeStream.methodDeclaration);
- } else {
- this.codeStream.lambdaExpression.scope.problemReporter().abortDueToInternalError(
- Messages.bind(
- Messages.abort_invalidOpcode,
- new Object[] {
- Byte.valueOf(opcode),
- Integer.valueOf(pc),
- new String(methodBinding.shortReadableName()),
- }),
- this.codeStream.lambdaExpression);
- }
- break;
- }
- if (pc >= (codeLength + codeOffset)) {
- break;
- }
- }
- return filterFakeFrames(realJumpTarget, frames, codeLength);
- }
-
- private void inspectFrame(int currentPC, StackMapFrame frame) {
- // Plant a breakpoint at the call site to conveniently hover.
- }
-
- private StackMapFrame createNewFrame(int currentPC, StackMapFrame frame, boolean isClinit, MethodBinding methodBinding) {
- StackMapFrame newFrame = frame.duplicate();
- newFrame.pc = currentPC;
- // initialize locals
- initializeLocals(isClinit ? true : methodBinding.isStatic(), currentPC, newFrame);
- return newFrame;
- }
-
- private int getDimensions(char[] returnType) {
- int dimensions = 0;
- while (returnType[dimensions] == '[') {
- dimensions++;
- }
- return dimensions;
- }
-
- private void addRealJumpTarget(Set realJumpTarget, int pc) {
- realJumpTarget.add(Integer.valueOf(pc));
- }
-
- private void addRealJumpTarget(Set realJumpTarget, int pc, Map frames, StackMapFrame frame, Scope scope) {
- realJumpTarget.add(Integer.valueOf(pc));
- add(frames, frame, scope);
- }
-
- private void add(Map frames, StackMapFrame frame, Scope scope) {
- Integer key = Integer.valueOf(frame.pc);
- StackMapFrame existingFrame = frames.get(key);
- if(existingFrame == null) {
- frames.put(key, frame);
- } else {
- // we need to merge
- frames.put(key, existingFrame.merge(frame, scope));
- }
- }
-
- private final int u1At(byte[] reference, int relativeOffset,
- int structOffset) {
- return (reference[relativeOffset + structOffset] & 0xFF);
- }
-
- private final int u2At(byte[] reference, int relativeOffset,
- int structOffset) {
- int position = relativeOffset + structOffset;
- return ((reference[position++] & 0xFF) << 8)
- + (reference[position] & 0xFF);
- }
-
- private final long u4At(byte[] reference, int relativeOffset,
- int structOffset) {
- int position = relativeOffset + structOffset;
- return (((reference[position++] & 0xFFL) << 24)
- + ((reference[position++] & 0xFF) << 16)
- + ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF));
- }
-
- private final int i2At(byte[] reference, int relativeOffset, int structOffset) {
- int position = relativeOffset + structOffset;
- return (reference[position++] << 8) + (reference[position] & 0xFF);
- }
-
- public char[] utf8At(byte[] reference, int absoluteOffset,
- int bytesAvailable) {
- int length = bytesAvailable;
- char outputBuf[] = new char[bytesAvailable];
- int outputPos = 0;
- int readOffset = absoluteOffset;
-
- while (length != 0) {
- int x = reference[readOffset++] & 0xFF;
- length--;
- if ((0x80 & x) != 0) {
- if ((x & 0x20) != 0) {
- length -= 2;
- x = ((x & 0xF) << 12)
- | ((reference[readOffset++] & 0x3F) << 6)
- | (reference[readOffset++] & 0x3F);
- } else {
- length--;
- x = ((x & 0x1F) << 6) | (reference[readOffset++] & 0x3F);
- }
- }
- outputBuf[outputPos++] = (char) x;
- }
-
- if (outputPos != bytesAvailable) {
- System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]),
- 0, outputPos);
- }
- return outputBuf;
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ClassFilePool.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ClassFilePool.java
deleted file mode 100644
index 7c0c8fa..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ClassFilePool.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2017 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler;
-
-import java.util.Arrays;
-
-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-
-public class ClassFilePool {
- public static final int POOL_SIZE = 25; // need to have enough for 2 units
- ClassFile[] classFiles;
-
-private ClassFilePool() {
- // prevent instantiation
- this.classFiles = new ClassFile[POOL_SIZE];
-}
-
-public static ClassFilePool newInstance() {
- return new ClassFilePool();
-}
-
-public synchronized ClassFile acquire(SourceTypeBinding typeBinding) {
- for (int i = 0; i < POOL_SIZE; i++) {
- ClassFile classFile = this.classFiles[i];
- if (classFile == null) {
- ClassFile newClassFile = new ClassFile(typeBinding);
- this.classFiles[i] = newClassFile;
- newClassFile.isShared = true;
- return newClassFile;
- }
- if (!classFile.isShared) {
- classFile.reset(typeBinding, typeBinding.scope.compilerOptions());
- classFile.isShared = true;
- return classFile;
- }
- }
- return new ClassFile(typeBinding);
-}
-public synchronized ClassFile acquireForModule(ModuleBinding moduleBinding, CompilerOptions options) {
- for (int i = 0; i < POOL_SIZE; i++) {
- ClassFile classFile = this.classFiles[i];
- if (classFile == null) {
- ClassFile newClassFile = new ClassFile(moduleBinding, options);
- this.classFiles[i] = newClassFile;
- newClassFile.isShared = true;
- return newClassFile;
- }
- if (!classFile.isShared) {
- classFile.reset(null, options);
- classFile.isShared = true;
- return classFile;
- }
- }
- return new ClassFile(moduleBinding, options);
-}
-public synchronized void release(ClassFile classFile) {
- classFile.isShared = false;
-}
-public void reset() {
- Arrays.fill(this.classFiles, null);
-}
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/CompilationResult.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/CompilationResult.java
deleted file mode 100644
index fff9399..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/CompilationResult.java
+++ /dev/null
@@ -1,494 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2023 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * Christoph Läubrich - Enhance the BuildContext with the discovered annotations #674
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler;
-
-import java.util.ArrayList;
-/**
- * A compilation result consists of all information returned by the compiler for
- * a single compiled compilation source unit. This includes:
- *
- * the compilation unit that was compiled
- * for each type produced by compiling the compilation unit, its binary and optionally its principal structure
- * any problems (errors or warnings) produced
- * dependency info
- *
- *
- * The principle structure and binary may be null if the compiler could not produce them.
- * If neither could be produced, there is no corresponding entry for the type.
- *
- * The dependency info includes type references such as supertypes, field types, method
- * parameter and return types, local variable types, types of intermediate expressions, etc.
- * It also includes the namespaces (packages) in which names were looked up.
- * It does not include finer grained dependencies such as information about
- * specific fields and methods which were referenced, but does contain their
- * declaring types and any other types used to locate such fields or methods.
- */
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.jdt.core.compiler.CategorizedProblem;
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.core.compiler.IProblem;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
-import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
-import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
-import org.eclipse.jdt.internal.compiler.util.Util;
-
-@SuppressWarnings({ "rawtypes", "unchecked" })
-public class CompilationResult {
-
- public CategorizedProblem problems[];
- public CategorizedProblem tasks[];
- public int problemCount;
- public int taskCount;
- public ICompilationUnit compilationUnit;
- private Map problemsMap;
- private Set firstErrors;
- private final int maxProblemPerUnit;
- public char[][][] qualifiedReferences;
- public char[][] simpleNameReferences;
- public char[][] rootReferences;
- public boolean hasAnnotations = false;
- public boolean hasFunctionalTypes = false;
- public int lineSeparatorPositions[];
- public RecoveryScannerData recoveryScannerData;
- public Map compiledTypes = new Hashtable(11);
- public int unitIndex, totalUnitsKnown;
- public boolean hasBeenAccepted = false;
- public char[] fileName;
- public boolean hasInconsistentToplevelHierarchies = false; // record the fact some toplevel types have inconsistent hierarchies
- public boolean hasSyntaxError = false;
- public char[][] packageName;
- public boolean checkSecondaryTypes = false; // check for secondary types which were created after the initial buildTypeBindings call
- private int numberOfErrors;
- private boolean hasMandatoryErrors;
- public List annotations = new ArrayList<>(1);
- private List scheduledProblems;
-
- private static final int[] EMPTY_LINE_ENDS = Util.EMPTY_INT_ARRAY;
- private static final Comparator PROBLEM_COMPARATOR = new Comparator() {
- @Override
- public int compare(Object o1, Object o2) {
- return ((CategorizedProblem) o1).getSourceStart() - ((CategorizedProblem) o2).getSourceStart();
- }
- };
-
-public CompilationResult(char[] fileName, int unitIndex, int totalUnitsKnown, int maxProblemPerUnit){
- this.fileName = fileName;
- this.unitIndex = unitIndex;
- this.totalUnitsKnown = totalUnitsKnown;
- this.maxProblemPerUnit = maxProblemPerUnit;
-}
-
-public CompilationResult(ICompilationUnit compilationUnit, int unitIndex, int totalUnitsKnown, int maxProblemPerUnit){
- this.fileName = compilationUnit.getFileName();
- this.compilationUnit = compilationUnit;
- this.unitIndex = unitIndex;
- this.totalUnitsKnown = totalUnitsKnown;
- this.maxProblemPerUnit = maxProblemPerUnit;
-}
-
-private int computePriority(CategorizedProblem problem){
- final int P_STATIC = 10000;
- final int P_OUTSIDE_METHOD = 40000;
- final int P_FIRST_ERROR = 20000;
- final int P_ERROR = 100000;
-
- int priority = 10000 - problem.getSourceLineNumber(); // early problems first
- if (priority < 0) priority = 0;
- if (problem.isError()){
- priority += P_ERROR;
- }
- ReferenceContext context = this.problemsMap == null ? null : this.problemsMap.get(problem);
- if (context != null){
- if (context instanceof AbstractMethodDeclaration){
- AbstractMethodDeclaration method = (AbstractMethodDeclaration) context;
- if (method.isStatic()) {
- priority += P_STATIC;
- }
- } else {
- priority += P_OUTSIDE_METHOD;
- }
- if (this.firstErrors.contains(problem)){ // if context is null, firstErrors is null too
- priority += P_FIRST_ERROR;
- }
- } else {
- priority += P_OUTSIDE_METHOD;
- }
- return priority;
-}
-
-public CategorizedProblem[] getAllProblems() {
- CategorizedProblem[] onlyProblems = getProblems();
- int onlyProblemCount = onlyProblems != null ? onlyProblems.length : 0;
- CategorizedProblem[] onlyTasks = getTasks();
- int onlyTaskCount = onlyTasks != null ? onlyTasks.length : 0;
- if (onlyTaskCount == 0) {
- return onlyProblems;
- }
- if (onlyProblemCount == 0) {
- return onlyTasks;
- }
- int totalNumberOfProblem = onlyProblemCount + onlyTaskCount;
- CategorizedProblem[] allProblems = new CategorizedProblem[totalNumberOfProblem];
- int allProblemIndex = 0;
- int taskIndex = 0;
- int problemIndex = 0;
- while (taskIndex + problemIndex < totalNumberOfProblem) {
- CategorizedProblem nextTask = null;
- CategorizedProblem nextProblem = null;
- if (taskIndex < onlyTaskCount) {
- nextTask = onlyTasks[taskIndex];
- }
- if (problemIndex < onlyProblemCount) {
- nextProblem = onlyProblems[problemIndex];
- }
- // select the next problem
- CategorizedProblem currentProblem = null;
- if (nextProblem != null) {
- if (nextTask != null) {
- if (nextProblem.getSourceStart() < nextTask.getSourceStart()) {
- currentProblem = nextProblem;
- problemIndex++;
- } else {
- currentProblem = nextTask;
- taskIndex++;
- }
- } else {
- currentProblem = nextProblem;
- problemIndex++;
- }
- } else {
- if (nextTask != null) {
- currentProblem = nextTask;
- taskIndex++;
- }
- }
- allProblems[allProblemIndex++] = currentProblem;
- }
- return allProblems;
-}
-
-public ClassFile[] getClassFiles() {
- ClassFile[] classFiles = new ClassFile[this.compiledTypes.size()];
- this.compiledTypes.values().toArray(classFiles);
- return classFiles;
-}
-
-/**
- * Answer the initial compilation unit corresponding to the present compilation result
- */
-public ICompilationUnit getCompilationUnit(){
- return this.compilationUnit;
-}
-
-/**
- * Answer the errors encountered during compilation.
- */
-public CategorizedProblem[] getErrors() {
- CategorizedProblem[] reportedProblems = getProblems();
- int errorCount = 0;
- for (int i = 0; i < this.problemCount; i++) {
- if (reportedProblems[i].isError()) errorCount++;
- }
- if (errorCount == this.problemCount) return reportedProblems;
- CategorizedProblem[] errors = new CategorizedProblem[errorCount];
- int index = 0;
- for (int i = 0; i < this.problemCount; i++) {
- if (reportedProblems[i].isError()) errors[index++] = reportedProblems[i];
- }
- return errors;
-}
-
-
-/**
- * Answer the initial file name
- */
-public char[] getFileName(){
- return this.fileName;
-}
-
-public int[] getLineSeparatorPositions() {
- return this.lineSeparatorPositions == null ? CompilationResult.EMPTY_LINE_ENDS : this.lineSeparatorPositions;
-}
-
-/**
- * Answer the problems (errors and warnings) encountered during compilation.
- *
- * This is not a compiler internal API - it has side-effects !
- * It is intended to be used only once all problems have been detected,
- * and makes sure the problems slot as the exact size of the number of
- * problems.
- */
-public CategorizedProblem[] getProblems() {
- // Re-adjust the size of the problems if necessary.
- if (this.problems != null) {
- if (this.problemCount != this.problems.length) {
- System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount]), 0, this.problemCount);
- }
-
- if (this.maxProblemPerUnit > 0 && this.problemCount > this.maxProblemPerUnit){
- quickPrioritize(this.problems, 0, this.problemCount - 1);
- this.problemCount = this.maxProblemPerUnit;
- System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount]), 0, this.problemCount);
- }
-
- // Stable sort problems per source positions.
- Arrays.sort(this.problems, 0, this.problems.length, CompilationResult.PROBLEM_COMPARATOR);
- //quickSort(problems, 0, problems.length-1);
- }
- return this.problems;
-}
-/**
- * Same as getProblems() but don't answer problems that actually concern the enclosing package.
- */
-public CategorizedProblem[] getCUProblems() {
- // Re-adjust the size of the problems if necessary and filter package problems
- if (this.problems != null) {
- CategorizedProblem[] filteredProblems = new CategorizedProblem[this.problemCount];
- int keep = 0;
- for (int i=0; i< this.problemCount; i++) {
- CategorizedProblem problem = this.problems[i];
- if (problem.getID() != IProblem.MissingNonNullByDefaultAnnotationOnPackage) {
- filteredProblems[keep++] = problem;
- } else if (this.compilationUnit != null) {
- if (CharOperation.equals(this.compilationUnit.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME)) {
- filteredProblems[keep++] = problem;
- }
- }
- }
- if (keep < this.problemCount) {
- System.arraycopy(filteredProblems, 0, filteredProblems = new CategorizedProblem[keep], 0, keep);
- this.problemCount = keep;
- }
- this.problems = filteredProblems;
- if (this.maxProblemPerUnit > 0 && this.problemCount > this.maxProblemPerUnit){
- quickPrioritize(this.problems, 0, this.problemCount - 1);
- this.problemCount = this.maxProblemPerUnit;
- System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount]), 0, this.problemCount);
- }
-
- // Stable sort problems per source positions.
- Arrays.sort(this.problems, 0, this.problems.length, CompilationResult.PROBLEM_COMPARATOR);
- //quickSort(problems, 0, problems.length-1);
- }
- return this.problems;
-}
-
-/**
- * Answer the tasks (TO-DO, ...) encountered during compilation.
- *
- * This is not a compiler internal API - it has side-effects !
- * It is intended to be used only once all problems have been detected,
- * and makes sure the problems slot as the exact size of the number of
- * problems.
- */
-public CategorizedProblem[] getTasks() {
- // Re-adjust the size of the tasks if necessary.
- if (this.tasks != null) {
-
- if (this.taskCount != this.tasks.length) {
- System.arraycopy(this.tasks, 0, (this.tasks = new CategorizedProblem[this.taskCount]), 0, this.taskCount);
- }
- // Stable sort problems per source positions.
- Arrays.sort(this.tasks, 0, this.tasks.length, CompilationResult.PROBLEM_COMPARATOR);
- //quickSort(tasks, 0, tasks.length-1);
- }
- return this.tasks;
-}
-
-public boolean hasErrors() {
- return this.numberOfErrors != 0;
-}
-
-public boolean hasMandatoryErrors() {
- return this.hasMandatoryErrors;
-}
-
-public boolean hasProblems() {
- return this.problemCount != 0;
-}
-
-public boolean hasTasks() {
- return this.taskCount != 0;
-}
-
-public boolean hasWarnings() {
- if (this.problems != null)
- for (int i = 0; i < this.problemCount; i++) {
- if (this.problems[i].isWarning())
- return true;
- }
- return false;
-}
-
-private void quickPrioritize(CategorizedProblem[] problemList, int left, int right) {
- if (left >= right) return;
- // sort the problems by their priority... starting with the highest priority
- int original_left = left;
- int original_right = right;
- int mid = computePriority(problemList[left + (right - left) / 2]);
- do {
- while (computePriority(problemList[right]) < mid)
- right--;
- while (mid < computePriority(problemList[left]))
- left++;
- if (left <= right) {
- CategorizedProblem tmp = problemList[left];
- problemList[left] = problemList[right];
- problemList[right] = tmp;
- left++;
- right--;
- }
- } while (left <= right);
- if (original_left < right)
- quickPrioritize(problemList, original_left, right);
- if (left < original_right)
- quickPrioritize(problemList, left, original_right);
-}
-
-/*
- * Record the compilation unit result's package name
- */
-public void recordPackageName(char[][] packName) {
- this.packageName = packName;
-}
-
-public void record(CategorizedProblem newProblem, ReferenceContext referenceContext) {
- record(newProblem, referenceContext, true);
- return;
-}
-
-public void record(CategorizedProblem newProblem, ReferenceContext referenceContext, boolean mandatoryError) {
- //new Exception("VERBOSE PROBLEM REPORTING").printStackTrace();
- if(newProblem.getID() == IProblem.Task) {
- recordTask(newProblem);
- return;
- }
- if (this.problemCount == 0) {
- this.problems = new CategorizedProblem[5];
- } else if (this.problemCount == this.problems.length) {
- System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount * 2]), 0, this.problemCount);
- }
- this.problems[this.problemCount++] = newProblem;
- if (referenceContext != null){
- if (this.problemsMap == null) this.problemsMap = new HashMap(5);
- if (this.firstErrors == null) this.firstErrors = new HashSet(5);
- if (newProblem.isError() && !referenceContext.hasErrors()) this.firstErrors.add(newProblem);
- this.problemsMap.put(newProblem, referenceContext);
- }
- if (newProblem.isError()) {
- this.numberOfErrors++;
- if (mandatoryError) this.hasMandatoryErrors = true;
- if ((newProblem.getID() & IProblem.Syntax) != 0) {
- this.hasSyntaxError = true;
- }
- }
-}
-
-ReferenceContext getContext(CategorizedProblem problem) {
- if (problem != null) {
- return this.problemsMap.get(problem);
- }
- return null;
-}
-
-/**
- * For now, remember the compiled type using its compound name.
- */
-public void record(char[] typeName, ClassFile classFile) {
- SourceTypeBinding sourceType = classFile.referenceBinding;
- if (sourceType != null && !sourceType.isLocalType() && sourceType.isHierarchyInconsistent()) {
- this.hasInconsistentToplevelHierarchies = true;
- }
- this.compiledTypes.put(typeName, classFile);
-}
-
-private void recordTask(CategorizedProblem newProblem) {
- if (this.taskCount == 0) {
- this.tasks = new CategorizedProblem[5];
- } else if (this.taskCount == this.tasks.length) {
- System.arraycopy(this.tasks, 0, (this.tasks = new CategorizedProblem[this.taskCount * 2]), 0, this.taskCount);
- }
- this.tasks[this.taskCount++] = newProblem;
-}
-public void removeProblem(CategorizedProblem problem) {
- if (this.problemsMap != null) this.problemsMap.remove(problem);
- if (this.firstErrors != null) this.firstErrors.remove(problem);
- if (problem.isError()) {
- this.numberOfErrors--;
- }
- this.problemCount--;
-}
-public CompilationResult tagAsAccepted(){
- this.hasBeenAccepted = true;
- this.problemsMap = null; // flush
- this.firstErrors = null; // flush
- return this;
-}
-
-@Override
-public String toString(){
- StringBuilder buffer = new StringBuilder();
- if (this.fileName != null){
- buffer.append("Filename : ").append(this.fileName).append('\n'); //$NON-NLS-1$
- }
- if (this.compiledTypes != null){
- buffer.append("COMPILED type(s) \n"); //$NON-NLS-1$
- Iterator keys = this.compiledTypes.keySet().iterator();
- while (keys.hasNext()) {
- char[] typeName = (char[]) keys.next();
- buffer.append("\t - ").append(typeName).append('\n'); //$NON-NLS-1$
-
- }
- } else {
- buffer.append("No COMPILED type\n"); //$NON-NLS-1$
- }
- if (this.problems != null){
- buffer.append(this.problemCount).append(" PROBLEM(s) detected \n"); //$NON-NLS-1$
- for (int i = 0; i < this.problemCount; i++){
- buffer.append("\t - ").append(this.problems[i]).append('\n'); //$NON-NLS-1$
- }
- } else {
- buffer.append("No PROBLEM\n"); //$NON-NLS-1$
- }
- return buffer.toString();
-}
-
-public void scheduleProblem(Runnable task) {
- if (this.scheduledProblems == null)
- this.scheduledProblems = new ArrayList<>();
- this.scheduledProblems.add(task);
-}
-
-public void materializeProblems() {
- if (this.scheduledProblems != null) {
- for (Runnable task : this.scheduledProblems) {
- task.run();
- }
- }
-}
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/Compiler.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/Compiler.java
deleted file mode 100644
index d608607..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/Compiler.java
+++ /dev/null
@@ -1,1117 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * Stephan Herrmann - contributions for
- * bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment
- * bug 186342 - [compiler][null] Using annotations for null checking
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler;
-
-import org.eclipse.jdt.core.compiler.*;
-import org.eclipse.jdt.internal.compiler.env.*;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.parser.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-import java.io.*;
-import java.util.*;
-
-public class Compiler implements ITypeRequestor, ProblemSeverities {
- public Parser parser;
- public ICompilerRequestor requestor;
- public CompilerOptions options;
- public ProblemReporter problemReporter;
- protected PrintWriter out; // output for messages that are not sent to problemReporter
- public CompilerStats stats;
- public CompilationProgress progress;
- public int remainingIterations = 1;
-
- // management of unit to be processed
- //public CompilationUnitResult currentCompilationUnitResult;
- public CompilationUnitDeclaration[] unitsToProcess;
- public int totalUnits; // (totalUnits-1) gives the last unit in unitToProcess
-
- private Map aptProblems;
-
- // name lookup
- public LookupEnvironment lookupEnvironment;
-
- // ONCE STABILIZED, THESE SHOULD RETURN TO A FINAL FIELD
- public static boolean DEBUG = false;
- public int parseThreshold = -1;
-
- public AbstractAnnotationProcessorManager annotationProcessorManager;
- public int annotationProcessorStartIndex = 0;
- public ReferenceBinding[] referenceBindings;
- public boolean useSingleThread = true; // by default the compiler will not use worker threads to read/process/write
-
- // number of initial units parsed at once (-1: none)
-
- /*
- * Static requestor reserved to listening compilation results in debug mode,
- * so as for example to monitor compiler activity independantly from a particular
- * builder implementation. It is reset at the end of compilation, and should not
- * persist any information after having been reset.
- */
- public static IDebugRequestor DebugRequestor = null;
-
- /**
- * Answer a new compiler using the given name environment and compiler options.
- * The environment and options will be in effect for the lifetime of the compiler.
- * When the compiler is run, compilation results are sent to the given requestor.
- *
- * @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
- * Environment used by the compiler in order to resolve type and package
- * names. The name environment implements the actual connection of the compiler
- * to the outside world (e.g. in batch mode the name environment is performing
- * pure file accesses, reuse previous build state or connection to repositories).
- * Note: the name environment is responsible for implementing the actual classpath
- * rules.
- *
- * @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
- * Configurable part for problem handling, allowing the compiler client to
- * specify the rules for handling problems (stop on first error or accumulate
- * them all) and at the same time perform some actions such as opening a dialog
- * in UI when compiling interactively.
- * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
- *
- * @param settings java.util.Map
- * The settings that control the compiler behavior.
- *
- * @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
- * Component which will receive and persist all compilation results and is intended
- * to consume them as they are produced. Typically, in a batch compiler, it is
- * responsible for writing out the actual .class files to the file system.
- * @see org.eclipse.jdt.internal.compiler.CompilationResult
- *
- * @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
- * Factory used inside the compiler to create problem descriptors. It allows the
- * compiler client to supply its own representation of compilation problems in
- * order to avoid object conversions. Note that the factory is not supposed
- * to accumulate the created problems, the compiler will gather them all and hand
- * them back as part of the compilation unit result.
- *
- * @deprecated this constructor is kept to preserve 3.1 and 3.2M4 compatibility
- */
- public Compiler(
- INameEnvironment environment,
- IErrorHandlingPolicy policy,
- Map settings,
- final ICompilerRequestor requestor,
- IProblemFactory problemFactory) {
- this(environment, policy, new CompilerOptions(settings), requestor, problemFactory, null /* printwriter */, null /* progress */);
- }
-
- /**
- * Answer a new compiler using the given name environment and compiler options.
- * The environment and options will be in effect for the lifetime of the compiler.
- * When the compiler is run, compilation results are sent to the given requestor.
- *
- * @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
- * Environment used by the compiler in order to resolve type and package
- * names. The name environment implements the actual connection of the compiler
- * to the outside world (e.g. in batch mode the name environment is performing
- * pure file accesses, reuse previous build state or connection to repositories).
- * Note: the name environment is responsible for implementing the actual classpath
- * rules.
- *
- * @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
- * Configurable part for problem handling, allowing the compiler client to
- * specify the rules for handling problems (stop on first error or accumulate
- * them all) and at the same time perform some actions such as opening a dialog
- * in UI when compiling interactively.
- * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
- *
- * @param settings java.util.Map
- * The settings that control the compiler behavior.
- *
- * @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
- * Component which will receive and persist all compilation results and is intended
- * to consume them as they are produced. Typically, in a batch compiler, it is
- * responsible for writing out the actual .class files to the file system.
- * @see org.eclipse.jdt.internal.compiler.CompilationResult
- *
- * @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
- * Factory used inside the compiler to create problem descriptors. It allows the
- * compiler client to supply its own representation of compilation problems in
- * order to avoid object conversions. Note that the factory is not supposed
- * to accumulate the created problems, the compiler will gather them all and hand
- * them back as part of the compilation unit result.
- *
- * @param parseLiteralExpressionsAsConstants boolean
- * This parameter is used to optimize the literals or leave them as they are in the source.
- * If you put true, "Hello" + " world" will be converted to "Hello world".
- *
- * @deprecated this constructor is kept to preserve 3.1 and 3.2M4 compatibility
- */
- public Compiler(
- INameEnvironment environment,
- IErrorHandlingPolicy policy,
- Map settings,
- final ICompilerRequestor requestor,
- IProblemFactory problemFactory,
- boolean parseLiteralExpressionsAsConstants) {
- this(environment, policy, new CompilerOptions(settings, parseLiteralExpressionsAsConstants), requestor, problemFactory, null /* printwriter */, null /* progress */);
- }
-
- /**
- * Answer a new compiler using the given name environment and compiler options.
- * The environment and options will be in effect for the lifetime of the compiler.
- * When the compiler is run, compilation results are sent to the given requestor.
- *
- * @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
- * Environment used by the compiler in order to resolve type and package
- * names. The name environment implements the actual connection of the compiler
- * to the outside world (e.g. in batch mode the name environment is performing
- * pure file accesses, reuse previous build state or connection to repositories).
- * Note: the name environment is responsible for implementing the actual classpath
- * rules.
- *
- * @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
- * Configurable part for problem handling, allowing the compiler client to
- * specify the rules for handling problems (stop on first error or accumulate
- * them all) and at the same time perform some actions such as opening a dialog
- * in UI when compiling interactively.
- * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
- *
- * @param options org.eclipse.jdt.internal.compiler.impl.CompilerOptions
- * The options that control the compiler behavior.
- *
- * @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
- * Component which will receive and persist all compilation results and is intended
- * to consume them as they are produced. Typically, in a batch compiler, it is
- * responsible for writing out the actual .class files to the file system.
- * @see org.eclipse.jdt.internal.compiler.CompilationResult
- *
- * @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
- * Factory used inside the compiler to create problem descriptors. It allows the
- * compiler client to supply its own representation of compilation problems in
- * order to avoid object conversions. Note that the factory is not supposed
- * to accumulate the created problems, the compiler will gather them all and hand
- * them back as part of the compilation unit result.
- */
- public Compiler(
- INameEnvironment environment,
- IErrorHandlingPolicy policy,
- CompilerOptions options,
- final ICompilerRequestor requestor,
- IProblemFactory problemFactory) {
- this(environment, policy, options, requestor, problemFactory, null /* printwriter */, null /* progress */);
- }
-
- /**
- * Answer a new compiler using the given name environment and compiler options.
- * The environment and options will be in effect for the lifetime of the compiler.
- * When the compiler is run, compilation results are sent to the given requestor.
- *
- * @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
- * Environment used by the compiler in order to resolve type and package
- * names. The name environment implements the actual connection of the compiler
- * to the outside world (e.g. in batch mode the name environment is performing
- * pure file accesses, reuse previous build state or connection to repositories).
- * Note: the name environment is responsible for implementing the actual classpath
- * rules.
- *
- * @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
- * Configurable part for problem handling, allowing the compiler client to
- * specify the rules for handling problems (stop on first error or accumulate
- * them all) and at the same time perform some actions such as opening a dialog
- * in UI when compiling interactively.
- * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
- *
- * @param options org.eclipse.jdt.internal.compiler.impl.CompilerOptions
- * The options that control the compiler behavior.
- *
- * @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
- * Component which will receive and persist all compilation results and is intended
- * to consume them as they are produced. Typically, in a batch compiler, it is
- * responsible for writing out the actual .class files to the file system.
- * @see org.eclipse.jdt.internal.compiler.CompilationResult
- *
- * @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
- * Factory used inside the compiler to create problem descriptors. It allows the
- * compiler client to supply its own representation of compilation problems in
- * order to avoid object conversions. Note that the factory is not supposed
- * to accumulate the created problems, the compiler will gather them all and hand
- * them back as part of the compilation unit result.
- * @deprecated
- */
- public Compiler(
- INameEnvironment environment,
- IErrorHandlingPolicy policy,
- CompilerOptions options,
- final ICompilerRequestor requestor,
- IProblemFactory problemFactory,
- PrintWriter out) {
- this(environment, policy, options, requestor, problemFactory, out, null /* progress */);
- }
-
- public Compiler(
- INameEnvironment environment,
- IErrorHandlingPolicy policy,
- CompilerOptions options,
- final ICompilerRequestor requestor,
- IProblemFactory problemFactory,
- PrintWriter out,
- CompilationProgress progress) {
-
- this.options = options;
- this.progress = progress;
-
- // wrap requestor in DebugRequestor if one is specified
- if(DebugRequestor == null) {
- this.requestor = requestor;
- } else {
- this.requestor = new ICompilerRequestor(){
- @Override
- public void acceptResult(CompilationResult result){
- if (DebugRequestor.isActive()){
- DebugRequestor.acceptDebugResult(result);
- }
- requestor.acceptResult(result);
- }
- };
- }
- this.problemReporter = new ProblemReporter(policy, this.options, problemFactory);
- this.lookupEnvironment = new LookupEnvironment(this, this.options, this.problemReporter, environment);
- this.out = out == null ? new PrintWriter(System.out, true) : out;
- this.stats = new CompilerStats();
- initializeParser();
- }
-
- /**
- * Add an additional binary type
- */
- @Override
- public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
- if (this.options.verbose) {
- this.out.println(
- Messages.bind(Messages.compilation_loadBinary, new String(binaryType.getName())));
-// new Exception("TRACE BINARY").printStackTrace(System.out);
-// System.out.println();
- }
- LookupEnvironment env = packageBinding.environment;
- env.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
- }
-
- /**
- * Add an additional compilation unit into the loop
- * -> build compilation unit declarations, their bindings and record their results.
- */
- @Override
- public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) {
- // Switch the current policy and compilation result for this unit to the requested one.
- CompilationResult unitResult =
- new CompilationResult(sourceUnit, this.totalUnits, this.totalUnits, this.options.maxProblemsPerUnit);
- unitResult.checkSecondaryTypes = true;
- try {
- if (this.options.verbose) {
- String count = String.valueOf(this.totalUnits + 1);
- this.out.println(
- Messages.bind(Messages.compilation_request,
- new String[] {
- count,
- count,
- new String(sourceUnit.getFileName())
- }));
- }
- // diet parsing for large collection of unit
- CompilationUnitDeclaration parsedUnit;
- if (this.totalUnits < this.parseThreshold) {
- parsedUnit = this.parser.parse(sourceUnit, unitResult);
- } else {
- parsedUnit = this.parser.dietParse(sourceUnit, unitResult);
- }
- // initial type binding creation
- this.lookupEnvironment.buildTypeBindings(parsedUnit, accessRestriction);
- addCompilationUnit(sourceUnit, parsedUnit);
-
- // binding resolution
- this.lookupEnvironment.completeTypeBindings(parsedUnit);
- } catch (AbortCompilationUnit e) {
- // at this point, currentCompilationUnitResult may not be sourceUnit, but some other
- // one requested further along to resolve sourceUnit.
- if (unitResult.compilationUnit == sourceUnit) { // only report once
- this.requestor.acceptResult(unitResult.tagAsAccepted());
- } else {
- throw e; // want to abort enclosing request to compile
- }
- }
- }
-
- /**
- * Add additional source types
- */
- @Override
- public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) {
- this.problemReporter.abortDueToInternalError(
- Messages.bind(Messages.abort_againstSourceModel, new String[] { String.valueOf(sourceTypes[0].getName()), String.valueOf(sourceTypes[0].getFileName()) }));
- }
-
- protected synchronized void addCompilationUnit(
- ICompilationUnit sourceUnit,
- CompilationUnitDeclaration parsedUnit) {
-
- if (this.unitsToProcess == null)
- return; // not collecting units
-
- // append the unit to the list of ones to process later on
- int size = this.unitsToProcess.length;
- if (this.totalUnits == size)
- // when growing reposition units starting at position 0
- System.arraycopy(
- this.unitsToProcess,
- 0,
- (this.unitsToProcess = new CompilationUnitDeclaration[size * 2]),
- 0,
- this.totalUnits);
- this.unitsToProcess[this.totalUnits++] = parsedUnit;
- }
-
- /**
- * Add the initial set of compilation units into the loop
- * -> build compilation unit declarations, their bindings and record their results.
- */
- protected void beginToCompile(ICompilationUnit[] sourceUnits) {
- int maxUnits = sourceUnits.length;
- this.totalUnits = 0;
- this.unitsToProcess = new CompilationUnitDeclaration[maxUnits];
-
- internalBeginToCompile(sourceUnits, maxUnits);
- }
-
- /**
- * Checks whether the compilation has been canceled and reports the given progress to the compiler progress.
- */
- protected void reportProgress(String taskDecription) {
- if (this.progress != null) {
- if (this.progress.isCanceled()) {
- // Only AbortCompilation can stop the compiler cleanly.
- // We check cancellation again following the call to compile.
- throw new AbortCompilation(true, null);
- }
- this.progress.setTaskName(taskDecription);
- }
- }
-
- /**
- * Checks whether the compilation has been canceled and reports the given work increment to the compiler progress.
- */
- protected void reportWorked(int workIncrement, int currentUnitIndex) {
- if (this.progress != null) {
- if (this.progress.isCanceled()) {
- // Only AbortCompilation can stop the compiler cleanly.
- // We check cancellation again following the call to compile.
- throw new AbortCompilation(true, null);
- }
- this.progress.worked(workIncrement, (this.totalUnits* this.remainingIterations) - currentUnitIndex - 1);
- }
- }
-
- public void compile(ICompilationUnit[] sourceUnits) {
- compile(sourceUnits, false);
- }
- /**
- * General API
- * -> compile each of supplied files
- * -> recompile any required types for which we have an incomplete principle structure
- */
- private void compile(ICompilationUnit[] sourceUnits, boolean lastRound) {
- this.stats.startTime = System.currentTimeMillis();
- try {
- // build and record parsed units
- reportProgress(Messages.compilation_beginningToCompile);
-
- if (this.options.complianceLevel >= ClassFileConstants.JDK9) {
- // in Java 9 the compiler must never ask the oracle for a module that is contained in the input units:
- sortModuleDeclarationsFirst(sourceUnits);
- }
- if (this.annotationProcessorManager == null) {
- beginToCompile(sourceUnits);
- } else {
- ICompilationUnit[] originalUnits = sourceUnits.clone(); // remember source units in case a source type collision occurs
- try {
- beginToCompile(sourceUnits);
- if (!lastRound) {
- processAnnotations();
- }
- if (!this.options.generateClassFiles) {
- // -proc:only was set on the command line
- return;
- }
- } catch (SourceTypeCollisionException e) {
- backupAptProblems();
- reset();
- // a generated type was referenced before it was created
- // the compiler either created a MissingType or found a BinaryType for it
- // so add the processor's generated files & start over,
- // but remember to only pass the generated files to the annotation processor
- int originalLength = originalUnits.length;
- int newProcessedLength = e.newAnnotationProcessorUnits.length;
- ICompilationUnit[] combinedUnits = new ICompilationUnit[originalLength + newProcessedLength];
- System.arraycopy(originalUnits, 0, combinedUnits, 0, originalLength);
- System.arraycopy(e.newAnnotationProcessorUnits, 0, combinedUnits, originalLength, newProcessedLength);
- this.annotationProcessorStartIndex = originalLength;
- compile(combinedUnits, e.isLastRound);
- return;
- }
- }
- // Restore the problems before the results are processed and cleaned up.
- restoreAptProblems();
- processCompiledUnits(0, lastRound);
- } catch (AbortCompilation e) {
- this.handleInternalException(e, null);
- }
- if (this.options.verbose) {
- if (this.totalUnits > 1) {
- this.out.println(
- Messages.bind(Messages.compilation_units, String.valueOf(this.totalUnits)));
- } else {
- this.out.println(
- Messages.bind(Messages.compilation_unit, String.valueOf(this.totalUnits)));
- }
- }
- }
-
- private void sortModuleDeclarationsFirst(ICompilationUnit[] sourceUnits) {
- Arrays.sort(sourceUnits, (u1, u2) -> {
- char[] fn1 = u1.getFileName();
- char[] fn2 = u2.getFileName();
- boolean isMod1 = CharOperation.endsWith(fn1, TypeConstants.MODULE_INFO_FILE_NAME) || CharOperation.endsWith(fn1, TypeConstants.MODULE_INFO_CLASS_NAME);
- boolean isMod2 = CharOperation.endsWith(fn2, TypeConstants.MODULE_INFO_FILE_NAME) || CharOperation.endsWith(fn2, TypeConstants.MODULE_INFO_CLASS_NAME);
- if (isMod1 == isMod2)
- return 0;
- return isMod1 ? -1 : 1;
- });
- }
-
- static class APTProblem {
- CategorizedProblem problem;
- ReferenceContext context;
- APTProblem(CategorizedProblem problem, ReferenceContext context) {
- this.problem = problem;
- this.context = context;
- }
- }
-
- protected void backupAptProblems() {
- if (this.unitsToProcess == null) return;
- for (int i = 0; i < this.totalUnits; i++) {
- CompilationUnitDeclaration unitDecl = this.unitsToProcess[i];
- CompilationResult result = unitDecl.compilationResult;
- if (result != null && result.hasErrors()) {
- CategorizedProblem[] errors = result.getErrors();
- for (CategorizedProblem problem : errors) {
- if (problem.getCategoryID() == CategorizedProblem.CAT_UNSPECIFIED) {
- if (this.aptProblems == null) {
- this.aptProblems = new HashMap<>();
- }
- APTProblem[] problems = this.aptProblems.get(new String(unitDecl.getFileName()));
- if (problems == null) {
- this.aptProblems.put(
- new String(unitDecl.getFileName()),
- new APTProblem[] { new APTProblem(problem, result.getContext(problem)) });
- } else {
- APTProblem[] temp = new APTProblem[problems.length + 1];
- System.arraycopy(problems, 0, temp, 0, problems.length);
- temp[problems.length] = new APTProblem(problem, result.getContext(problem));
- this.aptProblems.put(new String(unitDecl.getFileName()), temp);
- }
- }
- }
- }
- }
- }
-
- protected void restoreAptProblems() {
- if (this.unitsToProcess != null && this.aptProblems!= null) {
- for (int i = 0; i < this.totalUnits; i++) {
- CompilationUnitDeclaration unitDecl = this.unitsToProcess[i];
- APTProblem[] problems = this.aptProblems.get(new String(unitDecl.getFileName()));
- if (problems != null) {
- for (APTProblem problem : problems) {
- unitDecl.compilationResult.record(problem.problem, problem.context);
- }
- }
- }
- }
- this.aptProblems = null; // No need for this.
- }
-
- protected void processCompiledUnits(int startingIndex, boolean lastRound) throws java.lang.Error {
- CompilationUnitDeclaration unit = null;
- ProcessTaskManager processingTask = null;
- try {
- if (this.useSingleThread) {
- // process all units (some more could be injected in the loop by the lookup environment)
- for (int i = startingIndex; i < this.totalUnits; i++) {
- unit = this.unitsToProcess[i];
- if (unit.compilationResult != null && unit.compilationResult.hasBeenAccepted)
- continue;
- reportProgress(Messages.bind(Messages.compilation_processing, new String(unit.getFileName())));
- try {
- if (this.options.verbose)
- this.out.println(
- Messages.bind(Messages.compilation_process,
- new String[] {
- String.valueOf(i + 1),
- String.valueOf(this.totalUnits),
- new String(this.unitsToProcess[i].getFileName())
- }));
- process(unit, i);
- } finally {
- // cleanup compilation unit result, but only if not annotation processed.
- if (this.annotationProcessorManager == null || shouldCleanup(i))
- unit.cleanUp();
- }
- if (this.annotationProcessorManager == null) {
- this.unitsToProcess[i] = null; // release reference to processed unit declaration
- }
-
- reportWorked(1, i);
- this.stats.lineCount += unit.compilationResult.lineSeparatorPositions.length;
- long acceptStart = System.currentTimeMillis();
- this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
- this.stats.generateTime += System.currentTimeMillis() - acceptStart; // record accept time as part of generation
- if (this.options.verbose)
- this.out.println(
- Messages.bind(Messages.compilation_done,
- new String[] {
- String.valueOf(i + 1),
- String.valueOf(this.totalUnits),
- new String(unit.getFileName())
- }));
- }
- } else {
- processingTask = new ProcessTaskManager(this, startingIndex);
- int acceptedCount = 0;
- // process all units (some more could be injected in the loop by the lookup environment)
- // the processTask can continue to process units until its fixed sized cache is full then it must wait
- // for this this thread to accept the units as they appear (it only waits if no units are available)
- while (true) {
- try {
- unit = processingTask.removeNextUnit(); // waits if no units are in the processed queue
- } catch (Error | RuntimeException e) {
- unit = processingTask.unitToProcess;
- throw e;
- }
- if (unit == null) break;
- reportWorked(1, acceptedCount++);
- this.stats.lineCount += unit.compilationResult.lineSeparatorPositions.length;
- this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
- if (this.options.verbose)
- this.out.println(
- Messages.bind(Messages.compilation_done,
- new String[] {
- String.valueOf(acceptedCount),
- String.valueOf(this.totalUnits),
- new String(unit.getFileName())
- }));
- }
- }
- if (!lastRound) {
- if (this.annotationProcessorManager != null && this.totalUnits > this.annotationProcessorStartIndex) {
- int backup = this.annotationProcessorStartIndex;
- int prevUnits = this.totalUnits;
- processAnnotations();
- // Clean up the units that were left out previously for annotation processing.
- for (int i = backup; i < prevUnits; i++) {
- this.unitsToProcess[i].cleanUp();
- }
- processCompiledUnits(backup, lastRound);
- }
- }
- } catch (AbortCompilation e) {
- this.handleInternalException(e, unit);
- } catch (Error | RuntimeException e) {
- this.handleInternalException(e, unit, null);
- throw e; // rethrow
- } finally {
- if (processingTask != null) {
- processingTask.shutdown();
- processingTask = null;
- }
- reset();
- this.annotationProcessorStartIndex = 0;
- this.stats.endTime = System.currentTimeMillis();
- this.stats.overallTime += this.stats.endTime - this.stats.startTime;
- }
- }
-
- public synchronized CompilationUnitDeclaration getUnitToProcess(int next) {
- if (next < this.totalUnits) {
- CompilationUnitDeclaration unit = this.unitsToProcess[next];
- if (this.annotationProcessorManager == null || next < this.annotationProcessorStartIndex) {
- this.unitsToProcess[next] = null; // release reference to processed unit declaration
- }
- return unit;
- }
- return null;
- }
-
- /*
- * Returns whether the compilation unit at the given index should be
- * cleaned up after processing. This basically means whether or not
- * the unit is still required for annotation processing.
- */
- public boolean shouldCleanup(int index) {
- return index < this.annotationProcessorStartIndex;
- }
-
- public void setBinaryTypes(ReferenceBinding[] binaryTypes) {
- this.referenceBindings = binaryTypes;
- }
- /*
- * Compiler crash recovery in case of unexpected runtime exceptions
- */
- protected void handleInternalException(
- Throwable internalException,
- CompilationUnitDeclaration unit,
- CompilationResult result) {
-
- if (result == null && unit != null) {
- result = unit.compilationResult; // current unit being processed ?
- }
- // Lookup environment may be in middle of connecting types
- if (result == null && this.lookupEnvironment.unitBeingCompleted != null) {
- result = this.lookupEnvironment.unitBeingCompleted.compilationResult;
- }
- if (result == null) {
- synchronized (this) {
- if (this.unitsToProcess != null && this.totalUnits > 0)
- result = this.unitsToProcess[this.totalUnits - 1].compilationResult;
- }
- }
- // last unit in beginToCompile ?
-
- boolean needToPrint = true;
- if (result != null) {
- /* create and record a compilation problem */
- // only keep leading portion of the trace
- String[] pbArguments = new String[] {
- Messages.bind(Messages.compilation_internalError, Util.getExceptionSummary(internalException)),
- };
-
- result
- .record(
- this.problemReporter
- .createProblem(
- result.getFileName(),
- IProblem.Unclassified,
- pbArguments,
- pbArguments,
- Error, // severity
- 0, // source start
- 0, // source end
- 0, // line number
- 0),// column number
- unit, true);
-
- /* hand back the compilation result */
- if (!result.hasBeenAccepted) {
- this.requestor.acceptResult(result.tagAsAccepted());
- needToPrint = false;
- }
- }
- if (needToPrint) {
- /* dump a stack trace to the console */
- internalException.printStackTrace();
- }
- }
-
- /*
- * Compiler recovery in case of internal AbortCompilation event
- */
- protected void handleInternalException(
- AbortCompilation abortException,
- CompilationUnitDeclaration unit) {
-
- /* special treatment for SilentAbort: silently cancelling the compilation process */
- if (abortException.isSilent) {
- if (abortException.silentException == null) {
- return;
- }
- throw abortException.silentException;
- }
-
- /* uncomment following line to see where the abort came from */
- // abortException.printStackTrace();
-
- // Exception may tell which compilation result it is related, and which problem caused it
- CompilationResult result = abortException.compilationResult;
- if (result == null && unit != null) {
- result = unit.compilationResult; // current unit being processed ?
- }
- // Lookup environment may be in middle of connecting types
- if (result == null && this.lookupEnvironment.unitBeingCompleted != null) {
- result = this.lookupEnvironment.unitBeingCompleted.compilationResult;
- }
- if (result == null) {
- synchronized (this) {
- if (this.unitsToProcess != null && this.totalUnits > 0)
- result = this.unitsToProcess[this.totalUnits - 1].compilationResult;
- }
- }
- // last unit in beginToCompile ?
- if (result != null && !result.hasBeenAccepted) {
- /* distant problem which could not be reported back there? */
- if (abortException.problem != null) {
- recordDistantProblem: {
- CategorizedProblem distantProblem = abortException.problem;
- CategorizedProblem[] knownProblems = result.problems;
- for (int i = 0; i < result.problemCount; i++) {
- if (knownProblems[i] == distantProblem) { // already recorded
- break recordDistantProblem;
- }
- }
- if (distantProblem instanceof DefaultProblem) { // fixup filename TODO (philippe) should improve API to make this official
- ((DefaultProblem) distantProblem).setOriginatingFileName(result.getFileName());
- }
- result.record(distantProblem, unit, true);
- }
- } else {
- /* distant internal exception which could not be reported back there */
- if (abortException.exception != null) {
- this.handleInternalException(abortException.exception, null, result);
- return;
- }
- }
- /* hand back the compilation result */
- if (!result.hasBeenAccepted) {
- this.requestor.acceptResult(result.tagAsAccepted());
- }
- } else {
- abortException.printStackTrace();
- }
- }
-
- public void initializeParser() {
-
- this.parser = new Parser(this.problemReporter, this.options.parseLiteralExpressionsAsConstants);
- }
-
- private void abortIfPreviewNotAllowed(ICompilationUnit[] sourceUnits, int maxUnits) {
- if (!this.options.enablePreviewFeatures)
- return;
- try {
- if (this.options.sourceLevel != ClassFileConstants.getLatestJDKLevel()) {
- this.problemReporter.abortDueToPreviewEnablingNotAllowed(CompilerOptions.versionFromJdkLevel(this.options.sourceLevel), CompilerOptions.getLatestVersion());
- }
- } catch (AbortCompilation a) {
- // best effort to find a way for reporting this problem: report on the first source
- if (a.compilationResult == null) {
- a.compilationResult = new CompilationResult(sourceUnits[0], 0, maxUnits, this.options.maxProblemsPerUnit);
- }
- throw a;
- }
- }
- /**
- * Add the initial set of compilation units into the loop
- * -> build compilation unit declarations, their bindings and record their results.
- */
- protected void internalBeginToCompile(ICompilationUnit[] sourceUnits, int maxUnits) {
- abortIfPreviewNotAllowed(sourceUnits,maxUnits);
- if (!this.useSingleThread && maxUnits >= ReadManager.THRESHOLD)
- this.parser.readManager = new ReadManager(sourceUnits, maxUnits);
- try {
- // Switch the current policy and compilation result for this unit to the requested one.
- for (int i = 0; i < maxUnits; i++) {
- CompilationResult unitResult = null;
- try {
- if (this.options.verbose) {
- this.out.println(
- Messages.bind(Messages.compilation_request,
- new String[] {
- String.valueOf(i + 1),
- String.valueOf(maxUnits),
- new String(sourceUnits[i].getFileName())
- }));
- }
- // diet parsing for large collection of units
- CompilationUnitDeclaration parsedUnit;
- unitResult = new CompilationResult(sourceUnits[i], i, maxUnits, this.options.maxProblemsPerUnit);
- long parseStart = System.currentTimeMillis();
- if (this.totalUnits < this.parseThreshold) {
- parsedUnit = this.parser.parse(sourceUnits[i], unitResult);
- } else {
- parsedUnit = this.parser.dietParse(sourceUnits[i], unitResult);
- }
- long resolveStart = System.currentTimeMillis();
- this.stats.parseTime += resolveStart - parseStart;
- // initial type binding creation
- this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
- this.stats.resolveTime += System.currentTimeMillis() - resolveStart;
- addCompilationUnit(sourceUnits[i], parsedUnit);
- ImportReference currentPackage = parsedUnit.currentPackage;
- if (currentPackage != null) {
- unitResult.recordPackageName(currentPackage.tokens);
- }
- //} catch (AbortCompilationUnit e) {
- // requestor.acceptResult(unitResult.tagAsAccepted());
- } catch (AbortCompilation a) {
- // best effort to find a way for reporting this problem:
- if (a.compilationResult == null)
- a.compilationResult = unitResult;
- throw a;
- } finally {
- sourceUnits[i] = null; // no longer hold onto the unit
- }
- }
- } finally { // especially on AbortCompilation
- if (this.parser.readManager != null) {
- this.parser.readManager.shutdown();
- this.parser.readManager = null;
- }
- }
- // binding resolution
- this.lookupEnvironment.completeTypeBindings();
- }
-
- /**
- * Process a compilation unit already parsed and build.
- */
- public void process(CompilationUnitDeclaration unit, int i) {
- this.lookupEnvironment.unitBeingCompleted = unit;
- long parseStart = System.currentTimeMillis();
-
- this.parser.getMethodBodies(unit);
-
- long resolveStart = System.currentTimeMillis();
- this.stats.parseTime += resolveStart - parseStart;
-
- // fault in fields & methods
- if (unit.scope != null)
- unit.scope.faultInTypes();
-
- // verify inherited methods
- if (unit.scope != null)
- unit.scope.verifyMethods(this.lookupEnvironment.methodVerifier());
-
- // type checking
- unit.resolve();
-
- long analyzeStart = System.currentTimeMillis();
- this.stats.resolveTime += analyzeStart - resolveStart;
-
- //No need of analysis or generation of code if statements are not required
- if (!this.options.ignoreMethodBodies) unit.analyseCode(); // flow analysis
-
- long generateStart = System.currentTimeMillis();
- this.stats.analyzeTime += generateStart - analyzeStart;
-
- if (!this.options.ignoreMethodBodies) unit.generateCode(); // code generation
-
- // reference info
- if (this.options.produceReferenceInfo && unit.scope != null)
- unit.scope.storeDependencyInfo();
-
- // finalize problems (suppressWarnings)
- unit.finalizeProblems();
-
- this.stats.generateTime += System.currentTimeMillis() - generateStart;
-
- // refresh the total number of units known at this stage
- unit.compilationResult.totalUnitsKnown = this.totalUnits;
-
- this.lookupEnvironment.unitBeingCompleted = null;
- }
-
- protected void processAnnotations() {
- int newUnitSize = 0;
- int newClassFilesSize = 0;
- int bottom = this.annotationProcessorStartIndex;
- int top = this.totalUnits;
- ReferenceBinding[] binaryTypeBindingsTemp = this.referenceBindings;
- if (top == 0 && binaryTypeBindingsTemp == null) return;
- this.referenceBindings = null;
- do {
- // extract units to process
- int length = top - bottom;
- CompilationUnitDeclaration[] currentUnits = new CompilationUnitDeclaration[length];
- int index = 0;
- for (int i = bottom; i < top; i++) {
- CompilationUnitDeclaration currentUnit = this.unitsToProcess[i];
- currentUnits[index++] = currentUnit;
- }
- if (index != length) {
- System.arraycopy(currentUnits, 0, (currentUnits = new CompilationUnitDeclaration[index]), 0, index);
- }
- this.annotationProcessorManager.processAnnotations(currentUnits, binaryTypeBindingsTemp, false);
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=407841
- // It is possible that during the #processAnnotations() call, some units in the next batch would have been
- // brought forward and compiled already. If there are any such, process them for annotations then and there.
- // This would avoid the complications of marking some units as compiled but not-annotation-processed-yet.
- if (top < this.totalUnits) {
- length = this.totalUnits - top; // NOTE: Reuse the same variable, but make sure it's not used after this point
- CompilationUnitDeclaration[] addedUnits = new CompilationUnitDeclaration[length];
- System.arraycopy(this.unitsToProcess, top, addedUnits, 0, length);
- this.annotationProcessorManager.processAnnotations(addedUnits, binaryTypeBindingsTemp, false);
- }
- this.annotationProcessorStartIndex = top;
- ICompilationUnit[] newUnits = this.annotationProcessorManager.getNewUnits();
- newUnitSize = newUnits.length;
- ReferenceBinding[] newClassFiles = this.annotationProcessorManager.getNewClassFiles();
- binaryTypeBindingsTemp = newClassFiles;
- newClassFilesSize = newClassFiles.length;
- if (newUnitSize != 0) {
- ICompilationUnit[] newProcessedUnits = newUnits.clone(); // remember new units in case a source type collision occurs
- try {
- this.lookupEnvironment.isProcessingAnnotations = true;
- internalBeginToCompile(newUnits, newUnitSize);
- } catch (SourceTypeCollisionException e) {
- e.newAnnotationProcessorUnits = newProcessedUnits;
- throw e;
- } finally {
- this.lookupEnvironment.isProcessingAnnotations = false;
- this.annotationProcessorManager.reset();
- }
- bottom = top;
- top = this.totalUnits; // last unit added
- this.annotationProcessorStartIndex = top;
- } else {
- bottom = top;
- this.annotationProcessorManager.reset();
- }
- } while (newUnitSize != 0 || newClassFilesSize != 0);
-
- this.annotationProcessorManager.processAnnotations(null, null, true);
- // process potential units added in the final round see 329156
- ICompilationUnit[] newUnits = this.annotationProcessorManager.getNewUnits();
- newUnitSize = newUnits.length;
- try {
- if (newUnitSize != 0) {
- ICompilationUnit[] newProcessedUnits = newUnits.clone(); // remember new units in case a source type collision occurs
- try {
- this.lookupEnvironment.isProcessingAnnotations = true;
- internalBeginToCompile(newUnits, newUnitSize);
- } catch (SourceTypeCollisionException e) {
- e.isLastRound = true;
- e.newAnnotationProcessorUnits = newProcessedUnits;
- throw e;
- }
- }
- } finally {
- this.lookupEnvironment.isProcessingAnnotations = false;
- this.annotationProcessorManager.reset();
- this.annotationProcessorManager.cleanUp();
- }
- // Units added in final round don't get annotation processed
- this.annotationProcessorStartIndex = this.totalUnits;
- }
-
- public void reset() {
- this.lookupEnvironment.reset();
- this.parser.scanner.source = null;
- this.unitsToProcess = null;
- if (DebugRequestor != null) DebugRequestor.reset();
- this.problemReporter.reset();
- }
-
- /**
- * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process
- */
- public CompilationUnitDeclaration resolve(
- CompilationUnitDeclaration unit,
- ICompilationUnit sourceUnit,
- boolean verifyMethods,
- boolean analyzeCode,
- boolean generateCode) {
-
- try {
- if (unit == null) {
- // build and record parsed units
- this.parseThreshold = 0; // will request a full parse
- beginToCompile(new ICompilationUnit[] { sourceUnit });
- // find the right unit from what was injected via accept(ICompilationUnit,..):
- for (int i=0; i= this.size)
- this.availableIndex = 0;
- if (this.sleepCount <= -1)
- notify(); // wake up writing thread to accept next unit - could be the last one - must avoid deadlock
-}
-
-public CompilationUnitDeclaration removeNextUnit() throws Error {
- CompilationUnitDeclaration next = null;
- boolean yield = false;
- synchronized (this) {
- next = this.units[this.currentIndex];
- if (next == null || this.caughtException != null) {
- do {
- if (this.processingThread == null) {
- if (this.caughtException != null) {
- // rethrow the caught exception from the processingThread in the main compiler thread
- if (this.caughtException instanceof Error)
- throw (Error) this.caughtException;
- throw (RuntimeException) this.caughtException;
- }
- return null;
- }
- //System.out.print('r');
- //if (this.sleepCount > 0) throw new IllegalStateException(Integer.valueOf(this.sleepCount).toString());
- this.sleepCount = -1;
- try {
- wait(100);
- } catch (InterruptedException ignore) {
- // ignore
- }
- this.sleepCount = 0;
- next = this.units[this.currentIndex];
- } while (next == null);
- }
-
- this.units[this.currentIndex++] = null;
- if (this.currentIndex >= this.size)
- this.currentIndex = 0;
- if (this.sleepCount >= 1 && ++this.sleepCount > 4) {
- notify(); // wake up processing thread to add next unit but only after removing some elements first
- yield = this.sleepCount > 8;
- }
- }
- if (yield)
- Thread.yield();
- return next;
-}
-
-@Override
-public void run() {
- boolean noAnnotations = this.compiler.annotationProcessorManager == null;
- while (this.processingThread != null) {
- this.unitToProcess = null;
- int index = -1;
- boolean cleanup = noAnnotations || this.compiler.shouldCleanup(this.unitIndex);
- try {
- synchronized (this) {
- if (this.processingThread == null) return;
-
- this.unitToProcess = this.compiler.getUnitToProcess(this.unitIndex);
- if (this.unitToProcess == null) {
- this.processingThread = null;
- return;
- }
- index = this.unitIndex++;
- if (this.unitToProcess.compilationResult.hasBeenAccepted)
- continue;
- }
-
- try {
- this.compiler.reportProgress(Messages.bind(Messages.compilation_processing, new String(this.unitToProcess.getFileName())));
- if (this.compiler.options.verbose)
- this.compiler.out.println(
- Messages.bind(Messages.compilation_process,
- new String[] {
- String.valueOf(index + 1),
- String.valueOf(this.compiler.totalUnits),
- new String(this.unitToProcess.getFileName())
- }));
- this.compiler.process(this.unitToProcess, index);
- } finally {
- // cleanup compilation unit result, but only if not annotation processed.
- if (this.unitToProcess != null && cleanup)
- this.unitToProcess.cleanUp();
- }
-
- addNextUnit(this.unitToProcess);
- } catch (Error | RuntimeException e) {
- synchronized (this) {
- this.processingThread = null;
- this.caughtException = e;
- }
- return;
- }
- }
-}
-
-public void shutdown() {
- try {
- Thread t = null;
- synchronized (this) {
- if (this.processingThread != null) {
- t = this.processingThread;
- this.processingThread = null;
- notifyAll();
- }
- }
- if (t != null)
- t.join(250); // do not wait forever
- } catch (InterruptedException ignored) {
- // ignore
- }
-}
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ReadManager.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ReadManager.java
deleted file mode 100644
index 42ab9de..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/ReadManager.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2013 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler;
-
-import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
-
-public class ReadManager implements Runnable {
- ICompilationUnit[] units;
- int nextFileToRead;
- ICompilationUnit[] filesRead;
- char[][] contentsRead;
- int readyToReadPosition;
- int nextAvailablePosition;
- Thread[] readingThreads;
- char[] readInProcessMarker = new char[0];
- int sleepingThreadCount;
- private Throwable caughtException;
-
- static final int START_CUSHION = 5;
- public static final int THRESHOLD = 10;
- static final int CACHE_SIZE = 15; // do not waste memory by keeping too many files in memory
-
-public ReadManager(ICompilationUnit[] files, int length) {
- // start the background threads to read the file's contents
- int threadCount = Runtime.getRuntime().availableProcessors() + 1;
- if (threadCount < 2) {
- threadCount = 0;
- } else if (threadCount > CACHE_SIZE) {
- threadCount = CACHE_SIZE;
- }
-
- if (threadCount > 0) {
- synchronized (this) {
- this.units = new ICompilationUnit[length];
- System.arraycopy(files, 0, this.units, 0, length);
- this.nextFileToRead = START_CUSHION; // skip some files to reduce the number of times we have to wait
- this.filesRead = new ICompilationUnit[CACHE_SIZE];
- this.contentsRead = new char[CACHE_SIZE][];
- this.readyToReadPosition = 0;
- this.nextAvailablePosition = 0;
- this.sleepingThreadCount = 0;
- this.readingThreads = new Thread[threadCount];
- for (int i = threadCount; --i >= 0;) {
- this.readingThreads[i] = new Thread(this, "Compiler Source File Reader"); //$NON-NLS-1$
- this.readingThreads[i].setDaemon(true);
- this.readingThreads[i].start();
- }
- }
- }
-}
-
-public char[] getContents(ICompilationUnit unit) throws Error {
- Thread[] rThreads = this.readingThreads;
- if (rThreads == null || this.units.length == 0) {
- if (this.caughtException != null) {
- // rethrow the caught exception from the readingThreads in the main compiler thread
- if (this.caughtException instanceof Error)
- throw (Error) this.caughtException;
- throw (RuntimeException) this.caughtException;
- }
- return unit.getContents();
- }
-
- boolean yield = this.sleepingThreadCount == rThreads.length;
- char[] result = null;
- synchronized (this) {
- if (unit == this.filesRead[this.readyToReadPosition]) {
- result = this.contentsRead[this.readyToReadPosition];
- while (result == this.readInProcessMarker || result == null) {
- // let the readingThread know we're waiting
- //System.out.print('|');
- this.contentsRead[this.readyToReadPosition] = null;
- try {
- wait(250);
- } catch (InterruptedException ignore) { // ignore
- }
- if (this.caughtException != null) {
- // rethrow the caught exception from the readingThreads in the main compiler thread
- if (this.caughtException instanceof Error)
- throw (Error) this.caughtException;
- throw (RuntimeException) this.caughtException;
- }
- result = this.contentsRead[this.readyToReadPosition];
- }
- // free spot for next file
- this.filesRead[this.readyToReadPosition] = null;
- this.contentsRead[this.readyToReadPosition] = null;
- if (++this.readyToReadPosition >= this.contentsRead.length)
- this.readyToReadPosition = 0;
- if (this.sleepingThreadCount > 0) {
- //System.out.print('+');
- //System.out.print(this.nextFileToRead);
- notify();
- }
- } else {
- // must make sure we're reading ahead of the unit
- int unitIndex = 0;
- for (int l = this.units.length; unitIndex < l; unitIndex++)
- if (this.units[unitIndex] == unit) break;
- if (unitIndex == this.units.length) {
- // attempting to read a unit that was not included in the initial files - should not happen
- this.units = new ICompilationUnit[0]; // stop looking for more
- } else if (unitIndex >= this.nextFileToRead) {
- // start over
- //System.out.println(unitIndex + " vs " + this.nextFileToRead);
- this.nextFileToRead = unitIndex + START_CUSHION;
- this.readyToReadPosition = 0;
- this.nextAvailablePosition = 0;
- this.filesRead = new ICompilationUnit[CACHE_SIZE];
- this.contentsRead = new char[CACHE_SIZE][];
- notifyAll();
- }
- }
- }
- if (yield)
- Thread.yield(); // ensure other threads get a chance
- if (result != null)
- return result;
- //System.out.print('-');
- return unit.getContents();
-}
-
-@Override
-public void run() {
- try {
- while (this.readingThreads != null && this.nextFileToRead < this.units.length) {
- ICompilationUnit unit = null;
- int position = -1;
- synchronized (this) {
- if (this.readingThreads == null) return;
-
- while (this.filesRead[this.nextAvailablePosition] != null) {
- this.sleepingThreadCount++;
- try {
- wait(250); // wait until a spot in contents is available
- } catch (InterruptedException e) { // ignore
- }
- this.sleepingThreadCount--;
- if (this.readingThreads == null) return;
- }
-
- if (this.nextFileToRead >= this.units.length) return;
- unit = this.units[this.nextFileToRead++];
- position = this.nextAvailablePosition;
- if (++this.nextAvailablePosition >= this.contentsRead.length)
- this.nextAvailablePosition = 0;
- this.filesRead[position] = unit;
- this.contentsRead[position] = this.readInProcessMarker; // mark the spot so we know its being read
- }
- char[] result = unit.getContents();
- synchronized (this) {
- if (this.filesRead[position] == unit) {
- if (this.contentsRead[position] == null) // wake up main thread which is waiting for this file
- notifyAll();
- this.contentsRead[position] = result;
- }
- }
- }
- } catch (Error | RuntimeException e) {
- synchronized (this) {
- this.caughtException = e;
- shutdown();
- }
- return;
- }
-}
-
-public synchronized void shutdown() {
- this.readingThreads = null; // mark the read manager as shutting down so that the reading threads stop
- notifyAll();
-}
-}
\ No newline at end of file
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/AnnotationDiscoveryVisitor.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/AnnotationDiscoveryVisitor.java
deleted file mode 100644
index 8998514..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/AnnotationDiscoveryVisitor.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2023 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-
-import org.eclipse.jdt.internal.compiler.ASTVisitor;
-import org.eclipse.jdt.internal.compiler.apt.model.ElementImpl;
-import org.eclipse.jdt.internal.compiler.apt.model.Factory;
-import org.eclipse.jdt.internal.compiler.apt.util.ManyToMany;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Annotation;
-import org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.RecordComponent;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
-import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.AptSourceLocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
-import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.RecordComponentBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-
-/**
- * This class is used to visit the JDT compiler internal AST to discover annotations,
- * in the course of dispatching to annotation processors.
- */
-public class AnnotationDiscoveryVisitor extends ASTVisitor {
- final BaseProcessingEnvImpl _env;
- final Factory _factory;
- /**
- * Collects a many-to-many map of annotation types to
- * the elements they appear on.
- */
- final ManyToMany _annoToElement;
-
- public AnnotationDiscoveryVisitor(BaseProcessingEnvImpl env) {
- this._env = env;
- this._factory = env.getFactory();
- this._annoToElement = new ManyToMany<>();
- }
-
- @Override
- public boolean visit(Argument argument, BlockScope scope) {
- Annotation[] annotations = argument.annotations;
- ReferenceContext referenceContext = scope.referenceContext();
- if (referenceContext instanceof AbstractMethodDeclaration) {
- MethodBinding binding = ((AbstractMethodDeclaration) referenceContext).binding;
- if (binding != null) {
- TypeDeclaration typeDeclaration = scope.referenceType();
- typeDeclaration.binding.resolveTypesFor(binding);
- if (argument.binding != null) {
- argument.binding = new AptSourceLocalVariableBinding(argument.binding, binding);
- }
- }
- if (annotations != null && argument.binding != null) {
- this.resolveAnnotations(
- scope,
- annotations,
- argument.binding);
- }
- }
- return false;
- }
-
- @Override
- public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
- Annotation[] annotations = constructorDeclaration.annotations;
- if (annotations != null) {
- MethodBinding constructorBinding = constructorDeclaration.binding;
- if (constructorBinding == null) {
- return false;
- }
- ((SourceTypeBinding) constructorBinding.declaringClass).resolveTypesFor(constructorBinding);
- this.resolveAnnotations(
- constructorDeclaration.scope,
- annotations,
- constructorBinding);
- }
-
- TypeParameter[] typeParameters = constructorDeclaration.typeParameters;
- if (typeParameters != null) {
- int typeParametersLength = typeParameters.length;
- for (int i = 0; i < typeParametersLength; i++) {
- typeParameters[i].traverse(this, constructorDeclaration.scope);
- }
- }
-
- Argument[] arguments = constructorDeclaration.arguments;
- if (arguments != null) {
- int argumentLength = arguments.length;
- for (int i = 0; i < argumentLength; i++) {
- arguments[i].traverse(this, constructorDeclaration.scope);
- }
- }
- return false;
- }
-
- @Override
- public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
- Annotation[] annotations = fieldDeclaration.annotations;
- if (annotations != null) {
- FieldBinding fieldBinding = fieldDeclaration.binding;
- if (fieldBinding == null) {
- return false;
- }
- ((SourceTypeBinding) fieldBinding.declaringClass).resolveTypeFor(fieldBinding);
- if (fieldDeclaration.binding == null) {
- return false;
- }
- this.resolveAnnotations(scope, annotations, fieldBinding);
- }
- return false;
- }
-
- @Override
- public boolean visit(RecordComponent recordComponent, BlockScope scope) {
- Annotation[] annotations = recordComponent.annotations;
- if (annotations != null) {
- RecordComponentBinding recordComponentBinding = recordComponent.binding;
- if (recordComponentBinding == null) {
- return false;
- }
- ((SourceTypeBinding) recordComponentBinding.declaringRecord).resolveTypeFor(recordComponentBinding);
- if (recordComponent.binding == null) {
- return false;
- }
- this.resolveAnnotations(scope, annotations, recordComponentBinding);
- }
- return false;
- }
- @Override
- public boolean visit(TypeParameter typeParameter, ClassScope scope) {
- Annotation[] annotations = typeParameter.annotations;
- if (annotations != null) {
- TypeVariableBinding binding = typeParameter.binding;
- if (binding == null) {
- return false;
- }
- this.resolveAnnotations(scope.referenceContext.initializerScope, annotations, binding);
- }
- return false;
- }
-
- @Override
- public boolean visit(TypeParameter typeParameter, BlockScope scope) {
- Annotation[] annotations = typeParameter.annotations;
- if (annotations != null) {
- TypeVariableBinding binding = typeParameter.binding;
- if (binding == null) {
- return false;
- }
- // when we get here, it is guaranteed that class type parameters are connected, but method type parameters may not be.
- MethodBinding methodBinding = (MethodBinding) binding.declaringElement;
- ((SourceTypeBinding) methodBinding.declaringClass).resolveTypesFor(methodBinding);
- this.resolveAnnotations(scope, annotations, binding);
- }
- return false;
- }
-
- @Override
- public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
- Annotation[] annotations = methodDeclaration.annotations;
- if (annotations != null) {
- MethodBinding methodBinding = methodDeclaration.binding;
- if (methodBinding == null) {
- return false;
- }
- ((SourceTypeBinding) methodBinding.declaringClass).resolveTypesFor(methodBinding);
- this.resolveAnnotations(
- methodDeclaration.scope,
- annotations,
- methodBinding);
- }
-
- TypeParameter[] typeParameters = methodDeclaration.typeParameters;
- if (typeParameters != null) {
- int typeParametersLength = typeParameters.length;
- for (int i = 0; i < typeParametersLength; i++) {
- typeParameters[i].traverse(this, methodDeclaration.scope);
- }
- }
-
- Argument[] arguments = methodDeclaration.arguments;
- if (arguments != null) {
- int argumentLength = arguments.length;
- for (int i = 0; i < argumentLength; i++) {
- arguments[i].traverse(this, methodDeclaration.scope);
- }
- }
- return false;
- }
-
- @Override
- public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
- SourceTypeBinding binding = memberTypeDeclaration.binding;
- if (binding == null) {
- return false;
- }
- Annotation[] annotations = memberTypeDeclaration.annotations;
- if (annotations != null) {
- this.resolveAnnotations(
- memberTypeDeclaration.staticInitializerScope,
- annotations,
- binding);
- }
- return true;
- }
-
- @Override
- public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
- SourceTypeBinding binding = typeDeclaration.binding;
- if (binding == null) {
- return false;
- }
- Annotation[] annotations = typeDeclaration.annotations;
- if (annotations != null) {
- this.resolveAnnotations(
- typeDeclaration.staticInitializerScope,
- annotations,
- binding);
- }
- return true;
- }
- @Override
- public boolean visit(ModuleDeclaration module, CompilationUnitScope scope) {
- ModuleBinding binding = module.binding;
- if (binding == null) {
- return false;
- }
- //module.resolveTypeDirectives(scope);
- // The above call also resolvesAnnotations <=== actually this doesn't populate _annoToElement which is what we need
-
- Annotation[] annotations = module.annotations;
- if (annotations != null) {
- this.resolveAnnotations(module.scope,
- annotations,
- binding);
- }
- return true;
- }
-
- private void resolveAnnotations(BlockScope scope, Annotation[] annotations, Binding currentBinding) {
-
- int length = annotations == null ? 0 : annotations.length;
- if (length == 0)
- return;
-
- boolean old = scope.insideTypeAnnotation;
- scope.insideTypeAnnotation = true;
- currentBinding.getAnnotationTagBits();
- scope.insideTypeAnnotation = old;
- ElementImpl element = (ElementImpl) this._factory.newElement(currentBinding);
- AnnotationBinding [] annotationBindings = element.getPackedAnnotationBindings(); // discovery is never in terms of repeating annotation.
- for (AnnotationBinding binding : annotationBindings) {
- ReferenceBinding annotationType = binding.getAnnotationType();
- if (Annotation.isAnnotationTargetAllowed(scope, annotationType, currentBinding)
- ) { // binding should be resolved, but in case it's not, ignore it: it could have been wrapped into a container.
- TypeElement anno = (TypeElement)this._factory.newElement(annotationType);
- this._annoToElement.put(anno, element);
- }
- }
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/AptProblem.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/AptProblem.java
deleted file mode 100644
index f6128ff..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/AptProblem.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2001, 2007 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
-import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
-
-public class AptProblem extends DefaultProblem {
-
- // The batch compiler does not depend on org.eclipse.jdt.apt.pluggable.core; this
- // is just an arbitrary string to it, namespace notwithstanding. However, the IDE
- // cares about the fact that this string is registered as a marker ID by the
- // org.eclipse.jdt.apt.pluggable.core plug-in.
- private static final String MARKER_ID = "org.eclipse.jdt.apt.pluggable.core.compileProblem"; //$NON-NLS-1$
-
- /** May be null, if it was not possible to identify problem context */
- public final ReferenceContext _referenceContext;
-
- public AptProblem(
- ReferenceContext referenceContext,
- char[] originatingFileName,
- String message,
- int id,
- String[] stringArguments,
- int severity,
- int startPosition,
- int endPosition,
- int line,
- int column)
- {
- super(originatingFileName,
- message,
- id,
- stringArguments,
- severity,
- startPosition,
- endPosition,
- line,
- column);
- this._referenceContext = referenceContext;
- }
-
- @Override
- public int getCategoryID() {
- return CAT_UNSPECIFIED;
- }
-
- @Override
- public String getMarkerType() {
- return MARKER_ID;
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java
deleted file mode 100644
index e16725f..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2018 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- *
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager;
-import org.eclipse.jdt.internal.compiler.Compiler;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
-import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-
-/**
- * This class is the central dispatch point for Java 6 annotation processing.
- * This is created and configured by the JDT core; specifics depend on how
- * compilation is being performed, ie from the command line, via the Tool
- * interface, or within the IDE. This class manages the discovery of annotation
- * processors and other information spanning multiple rounds of processing;
- * context that is valid only within a single round is managed by
- * {@link RoundDispatcher}. There may be multiple instances of this class;
- * there is in general one of these for every Compiler that has annotation
- * processing enabled. Within the IDE there will typically be one for every
- * Java project, because each project potentially has a separate processor path.
- *
- * TODO: do something useful with _supportedOptions and _supportedAnnotationTypes.
- */
-public abstract class BaseAnnotationProcessorManager extends AbstractAnnotationProcessorManager
- implements IProcessorProvider
-{
-
- protected PrintWriter _out;
- protected PrintWriter _err;
- protected BaseProcessingEnvImpl _processingEnv;
- public boolean _isFirstRound = true;
-
- /**
- * The list of processors that have been loaded so far. A processor on this
- * list has been initialized, but may not yet have been called to process().
- */
- protected List _processors = new ArrayList<>();
-
- // Tracing
- protected boolean _printProcessorInfo = false;
- protected boolean _printRounds = false;
- protected int _round;
-
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager#configure(org.eclipse.jdt.internal.compiler.batch.Main, java.lang.String[])
- */
- @Override
- public void configure(Object batchCompiler, String[] options) {
- // Implemented by BatchAnnotationProcessorManager.
- throw new UnsupportedOperationException();
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager#configureFromPlatform(org.eclipse.jdt.internal.compiler.Compiler, java.lang.Object)
- */
- @Override
- public void configureFromPlatform(Compiler compiler, Object compilationUnitLocator, Object javaProject, boolean isTestCode) {
- // Implemented by IdeAnnotationProcessorManager.
- throw new UnsupportedOperationException();
- }
-
- @Override
- public List getDiscoveredProcessors() {
- return this._processors;
- }
-
- @Override
- public ICompilationUnit[] getDeletedUnits() {
- return this._processingEnv.getDeletedUnits();
- }
-
- @Override
- public ICompilationUnit[] getNewUnits() {
- return this._processingEnv.getNewUnits();
- }
-
- @Override
- public ReferenceBinding[] getNewClassFiles() {
- return this._processingEnv.getNewClassFiles();
- }
-
- @Override
- public void reset() {
- this._processingEnv.reset();
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager#setErr(java.io.PrintWriter)
- */
- @Override
- public void setErr(PrintWriter err) {
- this._err = err;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager#setOut(java.io.PrintWriter)
- */
- @Override
- public void setOut(PrintWriter out) {
- this._out = out;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager#setProcessors(java.lang.Object[])
- */
- @Override
- public void setProcessors(Object[] processors) {
- // Only meaningful in batch mode.
- throw new UnsupportedOperationException();
- }
-
- /**
- * A single "round" of processing, in the sense implied in
- * {@link javax.annotation.processing.Processor}.
- *
- * The Java 6 Processor spec contains ambiguities about how processors that support "*" are
- * handled. Eclipse tries to match Sun's implementation in javac. What that actually does is
- * analogous to inspecting the set of annotions found in the root units and adding an
- * "imaginary" annotation if the set is empty. Processors are then called in order of discovery;
- * for each processor, the intersection between the set of root annotations and the set of
- * annotations the processor supports is calculated, and if it is non-empty, the processor is
- * called. If the processor returns true then the intersection (including the
- * imaginary annotation if one exists) is removed from the set of root annotations and the loop
- * continues, until the set is empty. Of course, the imaginary annotation is not actually
- * included in the set of annotations passed in to the processor. A processor's process() method
- * is not called until its intersection set is non-empty, but thereafter it is called on every
- * round. Note that even if a processor is not called in the first round, if it is called in
- * subsequent rounds, it will be called in the order in which the processors were discovered,
- * rather than being added to the end of the list.
- */
- @Override
- public void processAnnotations(CompilationUnitDeclaration[] units, ReferenceBinding[] referenceBindings, boolean isLastRound) {
- if (units != null) {
- for (CompilationUnitDeclaration declaration : units) {
- if (declaration != null && declaration.scope != null) {
- ModuleBinding m = declaration.scope.module();
- if (m != null) {
- this._processingEnv._current_module = m;
- break;
- }
- }
- }
- }
- RoundEnvImpl roundEnv = new RoundEnvImpl(units, referenceBindings, isLastRound, this._processingEnv);
- PrintWriter out = this._out; // closable resource not manages in this class
- PrintWriter traceProcessorInfo = this._printProcessorInfo ? out : null;
- PrintWriter traceRounds = this._printRounds ? out : null;
- if (traceRounds != null) {
- traceRounds.println("Round " + ++this._round + ':'); //$NON-NLS-1$
- }
- RoundDispatcher dispatcher = new RoundDispatcher(
- this, roundEnv, roundEnv.getRootAnnotations(), traceProcessorInfo, traceRounds);
- dispatcher.round();
- if (this._isFirstRound) {
- this._isFirstRound = false;
- }
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseMessagerImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseMessagerImpl.java
deleted file mode 100644
index fd51160..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseMessagerImpl.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2023 BEA Systems, Inc. and others
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - derived base class from BatchMessagerImpl
- *
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.tools.Diagnostic.Kind;
-
-import org.eclipse.jdt.internal.compiler.CompilationResult;
-import org.eclipse.jdt.internal.compiler.apt.model.AnnotationMemberValue;
-import org.eclipse.jdt.internal.compiler.apt.model.AnnotationMirrorImpl;
-import org.eclipse.jdt.internal.compiler.apt.model.ExecutableElementImpl;
-import org.eclipse.jdt.internal.compiler.apt.model.ModuleElementImpl;
-import org.eclipse.jdt.internal.compiler.apt.model.TypeElementImpl;
-import org.eclipse.jdt.internal.compiler.apt.model.VariableElementImpl;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Annotation;
-import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Expression;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.AptSourceLocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
-import org.eclipse.jdt.internal.compiler.util.Util;
-
-public class BaseMessagerImpl {
-
- static final String[] NO_ARGUMENTS = new String[0];
-
- /**
- * Create a CategorizedProblem that can be reported to an ICompilerRequestor, etc.
- *
- * @param e the element against which to report the message. If the element is not
- * in the set of elements being compiled in the current round, the reference context
- * and filename will be set to null.
- * @return a new {@link AptProblem}
- */
- public static AptProblem createProblem(Kind kind, CharSequence msg, Element e,
- AnnotationMirror a, AnnotationValue v) {
- ReferenceContext referenceContext = null;
- Annotation[] elementAnnotations = null;
- int startPosition = 0;
- int endPosition = 0;
- if (e != null) {
- switch(e.getKind()) {
- case MODULE:
- ModuleElementImpl moduleElementImpl = (ModuleElementImpl) e;
- Binding moduleBinding = moduleElementImpl._binding;
- if (moduleBinding instanceof SourceModuleBinding) {
- SourceModuleBinding sourceModuleBinding = (SourceModuleBinding) moduleBinding;
- CompilationUnitDeclaration unitDeclaration = (CompilationUnitDeclaration) sourceModuleBinding.scope.referenceContext();
- referenceContext = unitDeclaration;
- elementAnnotations = unitDeclaration.moduleDeclaration.annotations;
- startPosition = unitDeclaration.moduleDeclaration.sourceStart;
- endPosition = unitDeclaration.moduleDeclaration.sourceEnd;
- }
- break;
- case ANNOTATION_TYPE :
- case INTERFACE :
- case CLASS :
- case ENUM :
- TypeElementImpl typeElementImpl = (TypeElementImpl) e;
- Binding typeBinding = typeElementImpl._binding;
- if (typeBinding instanceof SourceTypeBinding) {
- SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) typeBinding;
- TypeDeclaration typeDeclaration = (TypeDeclaration) sourceTypeBinding.scope.referenceContext();
- referenceContext = typeDeclaration;
- elementAnnotations = typeDeclaration.annotations;
- startPosition = typeDeclaration.sourceStart;
- endPosition = typeDeclaration.sourceEnd;
- }
- break;
- case PACKAGE :
- // nothing to do: there is no reference context for a package
- break;
- case CONSTRUCTOR :
- case METHOD :
- ExecutableElementImpl executableElementImpl = (ExecutableElementImpl) e;
- Binding binding = executableElementImpl._binding;
- if (binding instanceof MethodBinding) {
- MethodBinding methodBinding = (MethodBinding) binding;
- AbstractMethodDeclaration sourceMethod = methodBinding.sourceMethod();
- if (sourceMethod != null) {
- referenceContext = sourceMethod;
- elementAnnotations = sourceMethod.annotations;
- startPosition = sourceMethod.sourceStart;
- endPosition = sourceMethod.sourceEnd;
- }
- }
- break;
- case ENUM_CONSTANT :
- break;
- case EXCEPTION_PARAMETER :
- break;
- case FIELD :
- case PARAMETER :
- VariableElementImpl variableElementImpl = (VariableElementImpl) e;
- binding = variableElementImpl._binding;
- if (binding instanceof FieldBinding) {
- FieldBinding fieldBinding = (FieldBinding) binding;
- FieldDeclaration fieldDeclaration = fieldBinding.sourceField();
- if (fieldDeclaration != null) {
- ReferenceBinding declaringClass = fieldBinding.declaringClass;
- if (declaringClass instanceof SourceTypeBinding) {
- SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) declaringClass;
- TypeDeclaration typeDeclaration = (TypeDeclaration) sourceTypeBinding.scope.referenceContext();
- referenceContext = typeDeclaration;
- }
- elementAnnotations = fieldDeclaration.annotations;
- startPosition = fieldDeclaration.sourceStart;
- endPosition = fieldDeclaration.sourceEnd;
- }
- } else if (binding instanceof AptSourceLocalVariableBinding){
- AptSourceLocalVariableBinding parameterBinding = (AptSourceLocalVariableBinding) binding;
- LocalDeclaration parameterDeclaration = parameterBinding.declaration;
- if (parameterDeclaration != null) {
- MethodBinding methodBinding = parameterBinding.methodBinding;
- if (methodBinding != null) {
- referenceContext = methodBinding.sourceMethod();
- }
- elementAnnotations = parameterDeclaration.annotations;
- startPosition = parameterDeclaration.sourceStart;
- endPosition = parameterDeclaration.sourceEnd;
- }
- }
- break;
- case INSTANCE_INIT :
- case STATIC_INIT :
- break;
- case LOCAL_VARIABLE :
- break;
- case TYPE_PARAMETER :
- default:
- break;
- }
- }
- StringBuilder builder = new StringBuilder();
- if (msg != null) {
- builder.append(msg);
- }
- if (a != null && elementAnnotations != null) {
- AnnotationBinding annotationBinding = ((AnnotationMirrorImpl) a)._binding;
- Annotation annotation = findAnnotation(elementAnnotations, annotationBinding);
- if (annotation != null) {
- startPosition = annotation.sourceStart;
- endPosition = annotation.sourceEnd;
- if (v != null && v instanceof AnnotationMemberValue) {
- MethodBinding methodBinding = ((AnnotationMemberValue) v).getMethodBinding();
- MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
- MemberValuePair memberValuePair = null;
- for (int i = 0; memberValuePair == null && i < memberValuePairs.length; i++) {
- if (methodBinding == memberValuePairs[i].binding) {
- memberValuePair = memberValuePairs[i];
- }
- }
- if (memberValuePair != null) {
- startPosition = memberValuePair.sourceStart;
- endPosition = memberValuePair.sourceEnd;
- }
- }
- }
- }
- int lineNumber = 0;
- int columnNumber = 1;
- char[] fileName = null;
- if (referenceContext != null) {
- CompilationResult result = referenceContext.compilationResult();
- fileName = result.fileName;
- int[] lineEnds = null;
- lineNumber = startPosition >= 0
- ? Util.getLineNumber(startPosition, lineEnds = result.getLineSeparatorPositions(), 0, lineEnds.length-1)
- : 0;
- columnNumber = startPosition >= 0
- ? Util.searchColumnNumber(result.getLineSeparatorPositions(), lineNumber,startPosition)
- : 0;
- }
- int severity;
- switch(kind) {
- case ERROR :
- severity = ProblemSeverities.Error;
- break;
- case NOTE :
- case OTHER:
- severity = ProblemSeverities.Info;
- break;
- default :
- severity = ProblemSeverities.Warning;
- break;
- }
- return new AptProblem(
- referenceContext,
- fileName,
- String.valueOf(builder),
- 0,
- NO_ARGUMENTS,
- severity,
- startPosition,
- endPosition,
- lineNumber,
- columnNumber);
- }
-
- private static Annotation findAnnotation(Annotation[] elementAnnotations, AnnotationBinding annotationBinding) {
- for (int i = 0; i < elementAnnotations.length; i++) {
- Annotation annotation = findAnnotation(elementAnnotations[i], annotationBinding);
- if (annotation != null) {
- return annotation;
- }
- }
- return null;
- }
-
- private static Annotation findAnnotation(Annotation elementAnnotation, AnnotationBinding annotationBinding) {
- if (annotationBinding == elementAnnotation.getCompilerAnnotation()) {
- return elementAnnotation;
- }
-
- MemberValuePair[] memberValuePairs = elementAnnotation.memberValuePairs();
- for (MemberValuePair mvp : memberValuePairs) {
- Expression v = mvp.value;
- if (v instanceof Annotation) {
- Annotation a = findAnnotation((Annotation) v, annotationBinding);
- if (a != null) {
- return a;
- }
- } else if (v instanceof ArrayInitializer) {
- Expression[] expressions = ((ArrayInitializer) v).expressions;
- for (Expression e : expressions) {
- if (e instanceof Annotation) {
- Annotation a = findAnnotation((Annotation) e, annotationBinding);
- if (a != null) {
- return a;
- }
- }
- }
- }
- }
- return null;
- }
-
- public BaseMessagerImpl() {
- super();
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseProcessingEnvImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseProcessingEnvImpl.java
deleted file mode 100644
index 135fb7a..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseProcessingEnvImpl.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2023 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- * IBM Corporation - fix for 342598
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.Messager;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
-import javax.tools.JavaFileManager;
-
-import org.eclipse.jdt.internal.compiler.Compiler;
-import org.eclipse.jdt.internal.compiler.apt.model.ElementsImpl;
-import org.eclipse.jdt.internal.compiler.apt.model.Factory;
-import org.eclipse.jdt.internal.compiler.apt.model.TypesImpl;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
-import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-
-/**
- * Implementation of ProcessingEnvironment that is common to batch and IDE environments.
- */
-public abstract class BaseProcessingEnvImpl implements ProcessingEnvironment {
-
- /**
- * The minimal required Java runtime version (we need to run compiler on)
- */
- public static final SourceVersion MINIMAL_REQUIRED_RUNTIME_VERSION = SourceVersion.RELEASE_17;
- private static final long VERSION_FOR_MINIMAL_RUNTIME = ClassFileConstants.JDK17;
-
- // Initialized in subclasses:
- protected Filer _filer;
- protected Messager _messager;
- protected Map _processorOptions;
- protected Compiler _compiler;
-
- // Initialized in this base class:
- protected Elements _elementUtils;
- protected Types _typeUtils;
- private final List _addedUnits;
- private final List _addedClassFiles;
- private final List _deletedUnits;
- private boolean _errorRaised;
- private final Factory _factory;
- public ModuleBinding _current_module;
-
- public BaseProcessingEnvImpl() {
- this._addedUnits = new ArrayList<>();
- this._addedClassFiles = new ArrayList<>();
- this._deletedUnits = new ArrayList<>();
- this._elementUtils = ElementsImpl.create(this);
- this._typeUtils = new TypesImpl(this);
- this._factory = new Factory(this);
- this._errorRaised = false;
- }
-
- public void addNewUnit(ICompilationUnit unit) {
- this._addedUnits.add(unit);
- }
-
- public void addNewClassFile(ReferenceBinding binding) {
- this._addedClassFiles.add(binding);
- }
-
- public Compiler getCompiler() {
- return this._compiler;
- }
-
- public ICompilationUnit[] getDeletedUnits() {
- ICompilationUnit[] result = new ICompilationUnit[this._deletedUnits.size()];
- this._deletedUnits.toArray(result);
- return result;
- }
-
- public ICompilationUnit[] getNewUnits() {
- ICompilationUnit[] result = new ICompilationUnit[this._addedUnits.size()];
- this._addedUnits.toArray(result);
- return result;
- }
-
- @Override
- public Elements getElementUtils() {
- return this._elementUtils;
- }
-
- @Override
- public Filer getFiler() {
- return this._filer;
- }
-
- @Override
- public Messager getMessager() {
- return this._messager;
- }
-
- @Override
- public Map getOptions() {
- return this._processorOptions;
- }
-
- @Override
- public Types getTypeUtils() {
- return this._typeUtils;
- }
-
- public LookupEnvironment getLookupEnvironment() {
- return this._compiler.lookupEnvironment;
- }
-
- @Override
- public SourceVersion getSourceVersion() {
- final long sourceLevel = this._compiler.options.sourceLevel;
- if (sourceLevel <= ClassFileConstants.JDK1_5) {
- return SourceVersion.RELEASE_5;
- }
- if (sourceLevel == ClassFileConstants.JDK1_6) {
- return SourceVersion.RELEASE_6;
- } else if (sourceLevel == ClassFileConstants.JDK1_7) {
- return SourceVersion.RELEASE_7;
- } else if (sourceLevel == ClassFileConstants.JDK1_8) {
- return SourceVersion.RELEASE_8;
- } else if (sourceLevel == ClassFileConstants.JDK9) {
- return SourceVersion.RELEASE_9;
- } else if (sourceLevel == ClassFileConstants.JDK10) {
- return SourceVersion.RELEASE_10;
- } else if (sourceLevel == ClassFileConstants.JDK11) {
- return SourceVersion.RELEASE_11;
- } else if (sourceLevel == ClassFileConstants.JDK12) {
- return SourceVersion.RELEASE_12;
- } else if (sourceLevel == ClassFileConstants.JDK13) {
- return SourceVersion.RELEASE_13;
- } else if (sourceLevel == ClassFileConstants.JDK14) {
- return SourceVersion.RELEASE_14;
- } else if (sourceLevel == ClassFileConstants.JDK15) {
- return SourceVersion.RELEASE_15;
- } else if (sourceLevel == ClassFileConstants.JDK16) {
- return SourceVersion.RELEASE_16;
- } else if (sourceLevel == ClassFileConstants.JDK17) {
- return SourceVersion.RELEASE_17;
- }
- // From here on we can't use constants that may not be yet defined in
- // minimal required runtime Java version we have to avoid
- // errors like java.lang.NoSuchFieldError: RELEASE_20
- if (sourceLevel > VERSION_FOR_MINIMAL_RUNTIME) {
- try {
- return SourceVersion.valueOf("RELEASE_" + CompilerOptions.versionFromJdkLevel(sourceLevel)); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- // handle call on a minimal release we can run on
- return MINIMAL_REQUIRED_RUNTIME_VERSION;
- }
- } else {
- // to make compiler happy, should never happen
- throw new IllegalStateException("Invalid JDK source level: " + sourceLevel); //$NON-NLS-1$
- }
- }
-
- /**
- * Called when AnnotationProcessorManager has retrieved the list of
- * newly generated compilation units (ie, once per round)
- */
- public void reset() {
- this._addedUnits.clear();
- this._addedClassFiles.clear();
- this._deletedUnits.clear();
- }
-
- /**
- * Has an error been raised in any of the rounds of processing in this build?
- * @return error flag
- */
- public boolean errorRaised()
- {
- return this._errorRaised;
- }
-
- /**
- * Set or clear the errorRaised flag. Typically this will be set by the Messager
- * when an error has been raised, and it will never be cleared.
- */
- public void setErrorRaised(boolean b)
- {
- this._errorRaised = true;
- }
-
- public Factory getFactory()
- {
- return this._factory;
- }
-
- public ReferenceBinding[] getNewClassFiles() {
- ReferenceBinding[] result = new ReferenceBinding[this._addedClassFiles.size()];
- this._addedClassFiles.toArray(result);
- return result;
- }
- @Override
- public boolean isPreviewEnabled() {
- return this._compiler.options.enablePreviewFeatures;
- }
-
- public JavaFileManager getFileManager() {
- return null;
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java
deleted file mode 100644
index e5e904f..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2023 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ServiceConfigurationError;
-import java.util.ServiceLoader;
-
-import javax.annotation.processing.Processor;
-import javax.lang.model.SourceVersion;
-import javax.tools.JavaFileManager;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
-
-import org.eclipse.jdt.internal.compiler.batch.Main;
-import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
-
-/**
- * Java 6 annotation processor manager used when compiling from the command line
- * or via the javax.tools.JavaCompiler interface.
- */
-public class BatchAnnotationProcessorManager extends BaseAnnotationProcessorManager
-{
-
- /**
- * Processors that have been set by calling CompilationTask.setProcessors().
- */
- private List _setProcessors = null;
- private Iterator _setProcessorIter = null;
-
- /**
- * Processors named with the -processor option on the command line.
- */
- private List _commandLineProcessors;
- private Iterator _commandLineProcessorIter = null;
-
- private ServiceLoader _serviceLoader = null;
- private Iterator _serviceLoaderIter;
-
- private ClassLoader _procLoader;
-
- // Set this to true in order to trace processor discovery when -XprintProcessorInfo is specified
- private final static boolean VERBOSE_PROCESSOR_DISCOVERY = true;
- private boolean _printProcessorDiscovery = false;
-
- /**
- * Zero-arg constructor so this object can be easily created via reflection.
- * A BatchAnnotationProcessorManager cannot be used until its
- * {@link #configure(Object, String[])} method has been called.
- */
- public BatchAnnotationProcessorManager()
- {
- }
-
- @Override
- public void configure(Object batchCompiler, String[] commandLineArguments) {
- if (null != this._processingEnv) {
- throw new IllegalStateException(
- "Calling configure() more than once on an AnnotationProcessorManager is not supported"); //$NON-NLS-1$
- }
- BatchProcessingEnvImpl processingEnv = new BatchProcessingEnvImpl(this, (Main) batchCompiler, commandLineArguments);
- this._processingEnv = processingEnv;
- @SuppressWarnings("resource") // fileManager is not opened here
- JavaFileManager fileManager = processingEnv.getFileManager();
- if (fileManager instanceof StandardJavaFileManager) {
- Iterable extends File> location = null;
- if (SourceVersion.latest().compareTo(SourceVersion.RELEASE_8) > 0) {
- location = ((StandardJavaFileManager) fileManager).getLocation(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH);
- }
- if (location != null) {
- this._procLoader = fileManager.getClassLoader(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH);
- } else {
- this._procLoader = fileManager.getClassLoader(StandardLocation.ANNOTATION_PROCESSOR_PATH);
- }
- } else {
- // Fall back to old code
- this._procLoader = fileManager.getClassLoader(StandardLocation.ANNOTATION_PROCESSOR_PATH);
- }
- parseCommandLine(commandLineArguments);
- this._round = 0;
- }
-
- /**
- * If a -processor option was specified in command line arguments,
- * parse it into a list of qualified classnames.
- * @param commandLineArguments contains one string for every space-delimited token on the command line
- */
- private void parseCommandLine(String[] commandLineArguments) {
- List commandLineProcessors = null;
- for (int i = 0; i < commandLineArguments.length; ++i) {
- String option = commandLineArguments[i];
- if ("-XprintProcessorInfo".equals(option)) { //$NON-NLS-1$
- this._printProcessorInfo = true;
- this._printProcessorDiscovery = VERBOSE_PROCESSOR_DISCOVERY;
- }
- else if ("-XprintRounds".equals(option)) { //$NON-NLS-1$
- this._printRounds = true;
- }
- else if ("-processor".equals(option)) { //$NON-NLS-1$
- commandLineProcessors = new ArrayList<>();
- String procs = commandLineArguments[++i];
- commandLineProcessors.addAll(Arrays.asList(procs.split(","))); //$NON-NLS-1$
- break;
- }
- }
- this._commandLineProcessors = commandLineProcessors;
- if (null != this._commandLineProcessors) {
- this._commandLineProcessorIter = this._commandLineProcessors.iterator();
- }
- }
-
- @Override
- public ProcessorInfo discoverNextProcessor() {
- if (null != this._setProcessors) {
- // If setProcessors() was called, use that list until it's empty and then stop.
- if (this._setProcessorIter.hasNext()) {
- Processor p = this._setProcessorIter.next();
- p.init(this._processingEnv);
- ProcessorInfo pi = new ProcessorInfo(p);
- this._processors.add(pi);
- if (this._printProcessorDiscovery && null != this._out) {
- this._out.println("API specified processor: " + pi); //$NON-NLS-1$
- }
- return pi;
- }
- return null;
- }
-
- if (null != this._commandLineProcessors) {
- // If there was a -processor option, iterate over processor names,
- // creating and initializing processors, until no more names are found, then stop.
- if (this._commandLineProcessorIter.hasNext()) {
- String proc = this._commandLineProcessorIter.next();
- try {
- Class> clazz = this._procLoader.loadClass(proc);
- Object o = clazz.getDeclaredConstructor().newInstance();
- Processor p = (Processor) o;
- p.init(this._processingEnv);
- ProcessorInfo pi = new ProcessorInfo(p);
- this._processors.add(pi);
- if (this._printProcessorDiscovery && null != this._out) {
- this._out.println("Command line specified processor: " + pi); //$NON-NLS-1$
- }
- return pi;
- } catch (Exception e) {
- // TODO: better error handling
- throw new AbortCompilation(null, e);
- }
- }
- return null;
- }
-
- // if no processors were explicitly specified with setProcessors()
- // or the command line, search the processor path with ServiceLoader.
- if (null == this._serviceLoader ) {
- this._serviceLoader = ServiceLoader.load(Processor.class, this._procLoader);
- this._serviceLoaderIter = this._serviceLoader.iterator();
- }
- try {
- if (this._serviceLoaderIter.hasNext()) {
- Processor p = this._serviceLoaderIter.next();
- p.init(this._processingEnv);
- ProcessorInfo pi = new ProcessorInfo(p);
- this._processors.add(pi);
- if (this._printProcessorDiscovery && null != this._out) {
- StringBuilder sb = new StringBuilder();
- sb.append("Discovered processor service "); //$NON-NLS-1$
- sb.append(pi);
- sb.append("\n supporting "); //$NON-NLS-1$
- sb.append(pi.getSupportedAnnotationTypesAsString());
- sb.append("\n in "); //$NON-NLS-1$
- sb.append(getProcessorLocation(p));
- this._out.println(sb.toString());
- }
- return pi;
- }
- } catch (ServiceConfigurationError e) {
- // TODO: better error handling
- throw new AbortCompilation(null, e);
- }
- return null;
- }
-
- /**
- * Used only for debugging purposes. Generates output like "file:jar:D:/temp/jarfiles/myJar.jar!/".
- * Surely this code already exists in several hundred other places?
- * @return the location whence a processor class was loaded.
- */
- private String getProcessorLocation(Processor p) {
- // Get the classname in a form that can be passed to ClassLoader.getResource(),
- // e.g., "pa/pb/pc/Outer$Inner.class"
- boolean isMember = false;
- Class> outerClass = p.getClass();
- StringBuilder innerName = new StringBuilder();
- while (outerClass.isMemberClass()) {
- innerName.insert(0, outerClass.getSimpleName());
- innerName.insert(0, '$');
- isMember = true;
- outerClass = outerClass.getEnclosingClass();
- }
- String path = outerClass.getName();
- path = path.replace('.', '/');
- if (isMember) {
- path = path + innerName;
- }
- path = path + ".class"; //$NON-NLS-1$
-
- // Find the URL for the class resource and strip off the resource name itself
- String location = this._procLoader.getResource(path).toString();
- if (location.endsWith(path)) {
- location = location.substring(0, location.length() - path.length());
- }
- return location;
- }
-
- @Override
- public void reportProcessorException(Processor p, Exception e) {
- // TODO: if (verbose) report the processor
- throw new AbortCompilation(null, e);
- }
-
- @Override
- public void setProcessors(Object[] processors) {
- if (!this._isFirstRound) {
- throw new IllegalStateException("setProcessors() cannot be called after processing has begun"); //$NON-NLS-1$
- }
- // Cast all the processors here, rather than failing later.
- // But don't call init() until the processor is actually needed.
- this._setProcessors = new ArrayList<>(processors.length);
- for (Object o : processors) {
- Processor p = (Processor)o;
- this._setProcessors.add(p);
- }
- this._setProcessorIter = this._setProcessors.iterator();
-
- // processors set this way take precedence over anything on the command line
- this._commandLineProcessors = null;
- this._commandLineProcessorIter = null;
- }
-
- @Override
- protected void cleanUp() {
- // the classloader needs to be kept open between rounds, close it at the end:
- if (this._procLoader instanceof URLClassLoader) {
- try {
- ((URLClassLoader) this._procLoader).close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java
deleted file mode 100644
index 66c9a55..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2018 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- * philippe.marschall@netcetera.ch - Fix for 338370
- * IBM Corporation - Fix for validating relative name
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URI;
-import java.util.HashSet;
-
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.FilerException;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.tools.FileObject;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardLocation;
-import javax.tools.JavaFileManager.Location;
-
-import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-
-/**
- * Implementation of Filer used when compilation is driven by command line
- * or by Tool interface. This version does not need to keep track of
- * dependencies.
- */
-public class BatchFilerImpl implements Filer {
-
- protected final BaseAnnotationProcessorManager _dispatchManager;
- protected final BatchProcessingEnvImpl _env;
- protected final JavaFileManager _fileManager;
- protected final HashSet _createdFiles;
-
- public BatchFilerImpl(BaseAnnotationProcessorManager dispatchManager, BatchProcessingEnvImpl env)
- {
- this._dispatchManager = dispatchManager;
- this._fileManager = env._fileManager;
- this._env = env;
- this._createdFiles = new HashSet<>();
- }
-
- public void addNewUnit(ICompilationUnit unit) {
- this._env.addNewUnit(unit);
- }
-
- public void addNewClassFile(ReferenceBinding binding) {
- this._env.addNewClassFile(binding);
- }
-
- /* (non-Javadoc)
- * @see javax.annotation.processing.Filer#createClassFile(java.lang.CharSequence, javax.lang.model.element.Element[])
- */
- @Override
- public JavaFileObject createClassFile(CharSequence name,
- Element... originatingElements) throws IOException {
- JavaFileObject jfo = this._fileManager.getJavaFileForOutput(
- StandardLocation.CLASS_OUTPUT, name.toString(), JavaFileObject.Kind.CLASS, null);
- URI uri = jfo.toUri();
- if (this._createdFiles.contains(uri)) {
- throw new FilerException("Class file already created : " + name); //$NON-NLS-1$
- }
-
- this._createdFiles.add(uri);
- return new HookedJavaFileObject(jfo, jfo.getName(), name.toString(), this);
- }
-
- /* (non-Javadoc)
- * @see javax.annotation.processing.Filer#createResource(javax.tools.JavaFileManager.Location, java.lang.CharSequence, java.lang.CharSequence, javax.lang.model.element.Element[])
- */
- @Override
- public FileObject createResource(Location location, CharSequence pkg,
- CharSequence relativeName, Element... originatingElements)
- throws IOException {
- validateName(relativeName);
- FileObject fo = this._fileManager.getFileForOutput(
- location, pkg.toString(), relativeName.toString(), null);
- URI uri = fo.toUri();
- if (this._createdFiles.contains(uri)) {
- throw new FilerException("Resource already created : " + location + '/' + pkg + '/' + relativeName); //$NON-NLS-1$
- }
-
- this._createdFiles.add(uri);
- return fo;
- }
-
- private static void validateName(CharSequence relativeName) {
- int length = relativeName.length();
- if (length == 0) {
- throw new IllegalArgumentException("relative path cannot be empty"); //$NON-NLS-1$
- }
- String path = relativeName.toString();
- if (path.indexOf('\\') != -1) {
- // normalize the path with '/'
- path = path.replace('\\', '/');
- }
- if (path.charAt(0) == '/') {
- throw new IllegalArgumentException("relative path is absolute"); //$NON-NLS-1$
- }
- boolean hasDot = false;
- for (int i = 0; i < length; i++) {
- switch(path.charAt(i)) {
- case '/' :
- if (hasDot) {
- throw new IllegalArgumentException("relative name " + relativeName + " is not relative"); //$NON-NLS-1$ //$NON-NLS-2$
- }
- break;
- case '.' :
- hasDot = true;
- break;
- default:
- hasDot = false;
- }
- }
- if (hasDot) {
- throw new IllegalArgumentException("relative name " + relativeName + " is not relative"); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
-
- /* (non-Javadoc)
- * @see javax.annotation.processing.Filer#createSourceFile(java.lang.CharSequence, javax.lang.model.element.Element[])
- */
- @Override
- public JavaFileObject createSourceFile(CharSequence name,
- Element... originatingElements) throws IOException {
- String moduleAndPkgString = name.toString();
- int slash = moduleAndPkgString.indexOf('/');
- String mod = null;
- if (slash != -1) {
- name = moduleAndPkgString.substring(slash + 1, name.length());
- mod = moduleAndPkgString.substring(0, slash);
- }
- TypeElement typeElement = this._env._elementUtils.getTypeElement(name);
- if (typeElement != null) {
- throw new FilerException("Source file already exists : " + moduleAndPkgString); //$NON-NLS-1$
- }
- Location location = mod == null ? StandardLocation.SOURCE_OUTPUT : this._fileManager.getLocationForModule(StandardLocation.SOURCE_OUTPUT, mod);
- JavaFileObject jfo = this._fileManager.getJavaFileForOutput(location, name.toString(), JavaFileObject.Kind.SOURCE, null);
- URI uri = jfo.toUri();
- if (this._createdFiles.contains(uri)) {
- throw new FilerException("Source file already created : " + name); //$NON-NLS-1$
- }
-
- this._createdFiles.add(uri);
- // hook the file object's writers to create compilation unit and add to addedUnits()
- return new HookedJavaFileObject(jfo, jfo.getName(), name.toString(), this);
- }
-
- /* (non-Javadoc)
- * @see javax.annotation.processing.Filer#getResource(javax.tools.JavaFileManager.Location, java.lang.CharSequence, java.lang.CharSequence)
- */
- @Override
- public FileObject getResource(Location location, CharSequence pkg,
- CharSequence relativeName) throws IOException {
- validateName(relativeName);
- FileObject fo = this._fileManager.getFileForInput(
- location, pkg.toString(), relativeName.toString());
- if (fo == null) {
- throw new FileNotFoundException("Resource does not exist : " + location + '/' + pkg + '/' + relativeName); //$NON-NLS-1$
- }
- URI uri = fo.toUri();
- if (this._createdFiles.contains(uri)) {
- throw new FilerException("Resource already created : " + location + '/' + pkg + '/' + relativeName); //$NON-NLS-1$
- }
- return fo;
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchMessagerImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchMessagerImpl.java
deleted file mode 100644
index 1f0e9b2..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchMessagerImpl.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006-2009 BEA Systems, Inc. and others
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- *
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import javax.annotation.processing.Messager;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.tools.Diagnostic.Kind;
-
-import org.eclipse.jdt.core.compiler.CategorizedProblem;
-import org.eclipse.jdt.internal.compiler.batch.Main;
-
-/**
- * An implementation of Messager that reports messages via the Compiler
- */
-public class BatchMessagerImpl extends BaseMessagerImpl implements Messager {
-
- private final Main _compiler;
- private final BaseProcessingEnvImpl _processingEnv;
-
- public BatchMessagerImpl(BaseProcessingEnvImpl processingEnv, Main compiler) {
- this._compiler = compiler;
- this._processingEnv = processingEnv;
- }
-
- /* (non-Javadoc)
- * @see javax.annotation.processing.Messager#printMessage(javax.tools.Diagnostic.Kind, java.lang.CharSequence)
- */
- @Override
- public void printMessage(Kind kind, CharSequence msg) {
- printMessage(kind, msg, null, null, null);
- }
-
- /* (non-Javadoc)
- * @see javax.annotation.processing.Messager#printMessage(javax.tools.Diagnostic.Kind, java.lang.CharSequence, javax.lang.model.element.Element)
- */
- @Override
- public void printMessage(Kind kind, CharSequence msg, Element e) {
- printMessage(kind, msg, e, null, null);
- }
-
- /* (non-Javadoc)
- * @see javax.annotation.processing.Messager#printMessage(javax.tools.Diagnostic.Kind, java.lang.CharSequence, javax.lang.model.element.Element, javax.lang.model.element.AnnotationMirror)
- */
- @Override
- public void printMessage(Kind kind, CharSequence msg, Element e,
- AnnotationMirror a) {
- printMessage(kind, msg, e, a, null);
-
- }
-
- /* (non-Javadoc)
- * @see javax.annotation.processing.Messager#printMessage(javax.tools.Diagnostic.Kind, java.lang.CharSequence, javax.lang.model.element.Element, javax.lang.model.element.AnnotationMirror, javax.lang.model.element.AnnotationValue)
- */
- @Override
- public void printMessage(Kind kind, CharSequence msg, Element e,
- AnnotationMirror a, AnnotationValue v) {
- if (kind == Kind.ERROR) {
- this._processingEnv.setErrorRaised(true);
- }
- CategorizedProblem problem = createProblem(kind, msg, e, a, v);
- if (problem != null) {
- this._compiler.addExtraProblems(problem);
- }
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java
deleted file mode 100644
index 0643446..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2023 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- *
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import java.lang.reflect.Field;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.tools.JavaFileManager;
-
-import org.eclipse.jdt.internal.compiler.apt.util.EclipseFileManager;
-import org.eclipse.jdt.internal.compiler.batch.Main;
-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
-
-/**
- * The implementation of ProcessingEnvironment that is used when compilation is
- * driven by the command line or by the Tool interface. This environment uses
- * the JavaFileManager provided by the compiler.
- */
-public class BatchProcessingEnvImpl extends BaseProcessingEnvImpl {
-
- protected final BaseAnnotationProcessorManager _dispatchManager;
- protected final JavaFileManager _fileManager;
- protected final Main _compilerOwner;
-
- public BatchProcessingEnvImpl(BaseAnnotationProcessorManager dispatchManager, Main batchCompiler,
- String[] commandLineArguments)
- {
- super();
- this._compilerOwner = batchCompiler;
- this._compiler = batchCompiler.batchCompiler;
- this._dispatchManager = dispatchManager;
- Class> c = null;
- try {
- c = Class.forName("org.eclipse.jdt.internal.compiler.tool.EclipseCompilerImpl"); //$NON-NLS-1$
- } catch (ClassNotFoundException e) {
- // ignore
- }
- Field field = null;
- JavaFileManager javaFileManager = null;
- if (c != null) {
- try {
- field = c.getField("fileManager"); //$NON-NLS-1$
- } catch (SecurityException e) {
- // ignore
- } catch (IllegalArgumentException e) {
- // ignore
- } catch (NoSuchFieldException e) {
- // ignore
- }
- }
- if (field != null) {
- try {
- javaFileManager = (JavaFileManager) field.get(batchCompiler);
- } catch (IllegalArgumentException e) {
- // ignore
- } catch (IllegalAccessException e) {
- // ignore
- }
- }
- if (javaFileManager != null) {
- this._fileManager = javaFileManager;
- } else {
- String encoding = batchCompiler.options.get(CompilerOptions.OPTION_Encoding);
- Charset charset = encoding != null ? Charset.forName(encoding) : null;
- JavaFileManager manager = new EclipseFileManager(batchCompiler.compilerLocale, charset);
- ArrayList options = new ArrayList<>();
- options.addAll(Arrays.asList(commandLineArguments));
- for (Iterator iterator = options.iterator(); iterator.hasNext(); ) {
- manager.handleOption(iterator.next(), iterator);
- }
- this._fileManager = manager;
- }
- this._processorOptions = Collections.unmodifiableMap(parseProcessorOptions(commandLineArguments));
- this._filer = new BatchFilerImpl(this._dispatchManager, this);
- this._messager = new BatchMessagerImpl(this, this._compilerOwner);
- }
-
- /**
- * Parse the -A command line arguments so that they can be delivered to
- * processors with {@link javax.annotation.processing.ProcessingEnvironment#getOptions()}. In Sun's Java 6
- * version of javac, unlike in the Java 5 apt tool, only the -A options are
- * passed to processors, not the other command line options; that behavior
- * is repeated here.
- * @param args the equivalent of the args array from the main() method.
- * @return a map of key to value, or key to null if there is no value for
- * a particular key. The "-A" is stripped from the key, so a command-line
- * argument like "-Afoo=bar" will result in an entry with key "foo" and
- * value "bar".
- */
- private Map parseProcessorOptions(String[] args) {
- Map options = new LinkedHashMap<>();
- for (String arg : args) {
- if (!arg.startsWith("-A")) { //$NON-NLS-1$
- continue;
- }
- int equals = arg.indexOf('=');
- if (equals == 2) {
- // option begins "-A=" - not valid
- Exception e = new IllegalArgumentException("-A option must have a key before the equals sign"); //$NON-NLS-1$
- throw new AbortCompilation(null, e);
- }
- if (equals == arg.length() - 1) {
- // option ends with "=" - not valid
- options.put(arg.substring(2, equals), null);
- } else if (equals == -1) {
- // no value
- options.put(arg.substring(2), null);
- } else {
- // value and key
- options.put(arg.substring(2, equals), arg.substring(equals + 1));
- }
- }
- return options;
- }
- @Override
- public JavaFileManager getFileManager() {
- return this._fileManager;
- }
-
- @Override
- public Locale getLocale() {
- return this._compilerOwner.compilerLocale;
- }
-
- public boolean shouldIgnoreOptionalProblems(char[] fileName) {
- return Main.shouldIgnoreOptionalProblems(this._compilerOwner.ignoreOptionalProblemsFromFolders, fileName);
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/HookedJavaFileObject.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/HookedJavaFileObject.java
deleted file mode 100644
index 7776c12..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/HookedJavaFileObject.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2023 BEA Systems, Inc. and others
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- *
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.Writer;
-
-import javax.tools.ForwardingJavaFileObject;
-import javax.tools.JavaFileObject;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
-import org.eclipse.jdt.internal.compiler.env.IBinaryType;
-import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-
-/**
- * A delegating JavaFileObject that hooks the close() methods of the Writer
- * or OutputStream objects that it produces, and notifies the annotation
- * dispatch manager when a new compilation unit is produced.
- */
-public class HookedJavaFileObject extends
- ForwardingJavaFileObject
-{
- // A delegating Writer that passes all commands to its contained Writer,
- // but hooks close() to notify the annotation dispatch manager of the new unit.
- private class ForwardingWriter extends Writer {
- private final Writer _w;
- ForwardingWriter(Writer w) {
- this._w = w;
- }
- @Override
- public Writer append(char c) throws IOException {
- return this._w.append(c);
- }
- @Override
- public Writer append(CharSequence csq, int start, int end)
- throws IOException {
- return this._w.append(csq, start, end);
- }
- @Override
- public Writer append(CharSequence csq) throws IOException {
- return this._w.append(csq);
- }
- // This is the only interesting method - it has to notify the
- // dispatch manager of the new file.
- @Override
- public void close() throws IOException {
- this._w.close();
- closed();
- }
- @Override
- public void flush() throws IOException {
- this._w.flush();
- }
- @Override
- public void write(char[] cbuf) throws IOException {
- this._w.write(cbuf);
- }
- @Override
- public void write(int c) throws IOException {
- this._w.write(c);
- }
- @Override
- public void write(String str, int off, int len)
- throws IOException {
- this._w.write(str, off, len);
- }
- @Override
- public void write(String str) throws IOException {
- this._w.write(str);
- }
- @Override
- public void write(char[] cbuf, int off, int len)
- throws IOException {
- this._w.write(cbuf, off, len);
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return new ForwardingWriter(this._w);
- }
- @Override
- public int hashCode() {
- return this._w.hashCode();
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final ForwardingWriter other = (ForwardingWriter) obj;
- if (this._w == null) {
- if (other._w != null)
- return false;
- } else if (!this._w.equals(other._w))
- return false;
- return true;
- }
- @Override
- public String toString() {
- return "ForwardingWriter wrapping " + this._w.toString(); //$NON-NLS-1$
- }
- }
-
- // A delegating Writer that passes all commands to its contained Writer,
- // but hooks close() to notify the annotation dispatch manager of the new unit.
- private class ForwardingOutputStream extends OutputStream {
- private final OutputStream _os;
-
- ForwardingOutputStream(OutputStream os) {
- this._os = os;
- }
-
- @Override
- public void close() throws IOException {
- this._os.close();
- closed();
- }
- @Override
- public void flush() throws IOException {
- this._os.flush();
- }
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- this._os.write(b, off, len);
- }
- @Override
- public void write(byte[] b) throws IOException {
- this._os.write(b);
- }
- @Override
- public void write(int b) throws IOException {
- this._os.write(b);
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return new ForwardingOutputStream(this._os);
- }
- @Override
- public int hashCode() {
- return this._os.hashCode();
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final ForwardingOutputStream other = (ForwardingOutputStream) obj;
- if (this._os == null) {
- if (other._os != null)
- return false;
- } else if (!this._os.equals(other._os))
- return false;
- return true;
- }
- @Override
- public String toString() {
- return "ForwardingOutputStream wrapping " + this._os.toString(); //$NON-NLS-1$
- }
- }
-
- /**
- * The Filer implementation that we need to notify when a new file is created.
- */
- protected final BatchFilerImpl _filer;
-
- /**
- * The name of the file that is created; this is passed to the CompilationUnit constructor,
- * and ultimately to the java.io.File constructor, so it is a normal pathname, just like
- * what would be on the compiler command line.
- */
- protected final String _fileName;
-
-
-
- /**
- * A compilation unit is created when the writer or stream is closed. Only do this once.
- */
- private boolean _closed = false;
-
- private final String _typeName;
-
- public HookedJavaFileObject(JavaFileObject fileObject, String fileName, String typeName, BatchFilerImpl filer) {
- super(fileObject);
- this._filer = filer;
- this._fileName = fileName;
- this._typeName = typeName;
- }
-
- @SuppressWarnings("resource") // ForwardingOutputStream forwards close() too
- @Override
- public OutputStream openOutputStream() throws IOException {
- return new ForwardingOutputStream(super.openOutputStream());
- }
-
- @SuppressWarnings("resource") // ForwardingWriter forwards close() too
- @Override
- public Writer openWriter() throws IOException {
- return new ForwardingWriter(super.openWriter());
- }
-
- protected void closed() {
- if (!this._closed) {
- this._closed = true;
- //TODO: support encoding
- switch(this.getKind()) {
- case SOURCE :
- CompilationUnit unit = new CompilationUnit(null, this._fileName, null /* encoding */, null, this._filer._env.shouldIgnoreOptionalProblems(this._fileName.toCharArray()), null);
- this._filer.addNewUnit(unit);
- break;
- case CLASS :
- IBinaryType binaryType = null;
- try {
- binaryType = ClassFileReader.read(this._fileName);
- } catch (ClassFormatException e) {
- /* When the annotation processor produces garbage, javac seems to show some resilience, by hooking the source type,
- which since is resolved can answer annotations during discovery - Not sure if this sanctioned by the spec, to be taken
- up with Oracle. Here we mimic the bug, see that addNewClassFile is simply collecting ReferenceBinding's, so adding
- a SourceTypeBinding works just fine.
- */
- ReferenceBinding type = this._filer._env._compiler.lookupEnvironment.getType(CharOperation.splitOn('.', this._typeName.toCharArray()));
- if (type != null)
- this._filer.addNewClassFile(type);
- } catch (IOException e) {
- // ignore
- }
- if (binaryType != null) {
- char[] name = binaryType.getName();
- ReferenceBinding type = this._filer._env._compiler.lookupEnvironment.getType(CharOperation.splitOn('/', name));
- if (type != null && type.isValidBinding()) {
- if (type.isBinaryBinding()) {
- this._filer.addNewClassFile(type);
- } else {
- BinaryTypeBinding binaryBinding = new BinaryTypeBinding(type.getPackage(), binaryType, this._filer._env._compiler.lookupEnvironment, true);
- this._filer.addNewClassFile(binaryBinding);
- }
- }
- }
- break;
- case HTML:
- case OTHER:
- break;
- }
- }
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/IProcessorProvider.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/IProcessorProvider.java
deleted file mode 100644
index ae4e7dc..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/IProcessorProvider.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- *
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import java.util.List;
-
-import javax.annotation.processing.Processor;
-
-/**
- * Implementors know how to discover annotation processors, and maintain a list of processors that
- * have been discovered and initialized so far.
- */
-public interface IProcessorProvider {
-
- /**
- * Return the next processor that can be discovered, according to the order and discovery rules
- * of the provider (see, for instance, {@link Processor}.
- * @return a ProcessorInfo wrapping an initialized Processor, or null if there are
- * no more processors to be discovered.
- */
- ProcessorInfo discoverNextProcessor();
-
- /**
- * @return the list of all processors that have been discovered so far. This list will grow when
- * {@link #discoverNextProcessor()} is called.
- */
- List getDiscoveredProcessors();
-
- /**
- * Called when a processor throws an exception. This may abort compilation, throw an
- * unchecked exception, etc; the caller should not assume that this method will return.
- *
- * @param p the processor, if known, or null if not.
- */
- void reportProcessorException(Processor p, Exception e);
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/ProcessorInfo.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/ProcessorInfo.java
deleted file mode 100644
index 9248929..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/ProcessorInfo.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2011 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- *
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import java.util.Iterator;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.annotation.processing.Processor;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.TypeElement;
-
-/**
- * Cached information associated with a {@link Processor} in the context
- * of annotation processor dispatch.
- *
- * This class supports inclusion in a collection by implementing
- * equals() and hashCode(). Its concept of identity is based on
- * the class object of the Processor that it wraps; so, for instance,
- * it is not possible to have a Set that contains more than one
- * instance of a particular Processor class. In fact, it is possible
- * to have more than one instance of a Processor if there are multiple
- * build threads, but within the context of a particular dispatch
- * manager, there will only be one of any given Processor class.
- */
-public class ProcessorInfo {
- final Processor _processor;
- final Set _supportedOptions;
- final SourceVersion _supportedSourceVersion;
-
- private final Pattern _supportedAnnotationTypesPattern;
- private final boolean _supportsStar;
- private boolean _hasBeenCalled;
-
- /**
- * Create a ProcessorInfo wrapping a particular Processor. The Processor must already have been
- * initialized (that is,
- * {@link Processor#init(javax.annotation.processing.ProcessingEnvironment)} must already have
- * been called). Its getSupportedXXX() methods will be called and the results will be cached.
- */
- public ProcessorInfo(Processor p)
- {
- this._processor = p;
- this._hasBeenCalled = false;
- this._supportedSourceVersion = p.getSupportedSourceVersion();
- this._supportedOptions = p.getSupportedOptions();
- Set supportedAnnotationTypes = p.getSupportedAnnotationTypes();
-
- boolean supportsStar = false;
- if (null != supportedAnnotationTypes && !supportedAnnotationTypes.isEmpty()) {
- StringBuilder regex = new StringBuilder();
- Iterator iName = supportedAnnotationTypes.iterator();
- while (true) {
- String name = iName.next();
- supportsStar |= "*".equals(name); //$NON-NLS-1$
- String escapedName1 = name.replace(".", "\\."); //$NON-NLS-1$ //$NON-NLS-2$
- String escapedName2 = escapedName1.replace("*", ".*"); //$NON-NLS-1$ //$NON-NLS-2$
- regex.append(escapedName2);
- if (!iName.hasNext()) {
- break;
- }
- regex.append('|');
- }
- this._supportedAnnotationTypesPattern = Pattern.compile(regex.toString());
- }
- else {
- this._supportedAnnotationTypesPattern = null;
- }
- this._supportsStar = supportsStar;
- }
-
- /**
- * Compute the subset of annotations that are described by annotationTypes,
- * and determine whether the processor should be called. A processor will be called if it has
- * any annotations to process, or if it supports "*", or if it was called in a previous round.
- * If the return value of this method is true once for a given processor, then it will always be true on
- * subsequent calls.
- *
- * @param annotations a set of annotation types
- * @param result an empty modifiable set, which upon return will contain a subset of annotations, which may be empty but will not be null.
- * @return true if the processor should be called on this round.
- */
- public boolean computeSupportedAnnotations(Set annotations, Set result)
- {
- if (null != annotations && !annotations.isEmpty() && null != this._supportedAnnotationTypesPattern) {
- for (TypeElement annotation : annotations) {
- Matcher matcher = this._supportedAnnotationTypesPattern.matcher(annotation.getQualifiedName().toString());
- if (matcher.matches()) {
- result.add(annotation);
- }
- }
- }
- boolean call = this._hasBeenCalled || this._supportsStar || !result.isEmpty();
- this._hasBeenCalled |= call;
- return call;
- }
-
- /**
- * @return true if the processor included "*" among its list of supported annotations.
- */
- public boolean supportsStar()
- {
- return this._supportsStar;
- }
-
- /**
- * Must be called at the beginning of a build to ensure that no information is
- * carried over from the previous build. In particular, processors are
- * required to be called on every round after the round in which they are
- * first called; this method resets the "has been called" flag.
- */
- public void reset()
- {
- this._hasBeenCalled = false;
- }
-
- @Override
- public int hashCode() {
- return this._processor.getClass().hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final ProcessorInfo other = (ProcessorInfo) obj;
- if (!this._processor.getClass().equals(other._processor.getClass()))
- return false;
- return true;
- }
-
- @Override
- public String toString()
- {
- return this._processor.getClass().getName();
- }
-
- /**
- * @return a string representing the set of supported annotation types, in a format
- * suitable for debugging. The format is unspecified and subject to change.
- */
- public String getSupportedAnnotationTypesAsString()
- {
- StringBuilder sb = new StringBuilder();
- sb.append('[');
- Iterator iAnnots = this._processor.getSupportedAnnotationTypes().iterator();
- boolean hasNext = iAnnots.hasNext();
- while (hasNext) {
- sb.append(iAnnots.next());
- hasNext = iAnnots.hasNext();
- if (hasNext) {
- sb.append(',');
- }
- }
- sb.append(']');
- return sb.toString();
- }
-}
-
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundDispatcher.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundDispatcher.java
deleted file mode 100644
index 15131a4..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundDispatcher.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2015 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- *
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import java.io.PrintWriter;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.processing.RoundEnvironment;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-
-/**
- * Manages context during a single round of annotation processing.
- */
-public class RoundDispatcher {
-
- private final Set _unclaimedAnnotations;
- private final RoundEnvironment _roundEnv;
- private final IProcessorProvider _provider;
- private boolean _searchForStar = false;
- private final PrintWriter _traceProcessorInfo;
- private final PrintWriter _traceRounds;
-
- /**
- * Processors discovered so far. This list may grow during the
- * course of a round, as additional processors are discovered.
- */
- private final List _processors;
-
- /**
- * @param rootAnnotations a possibly empty but non-null set of annotations on the
- * root compilation units of this round. A local copy of the set will be made, to
- * avoid modifying the set passed in.
- * @param traceProcessorInfo a PrintWriter that processor trace output will be sent
- * to, or null if tracing is not desired.
- */
- public RoundDispatcher(
- IProcessorProvider provider,
- RoundEnvironment env,
- Set rootAnnotations,
- PrintWriter traceProcessorInfo,
- PrintWriter traceRounds)
- {
- this._provider = provider;
- this._processors = provider.getDiscoveredProcessors();
- this._roundEnv = env;
- this._unclaimedAnnotations = new HashSet<>(rootAnnotations);
- this._traceProcessorInfo = traceProcessorInfo;
- this._traceRounds = traceRounds;
- }
-
- /**
- * Handle a complete round, dispatching to all appropriate processors.
- */
- public void round()
- {
- if (null != this._traceRounds) {
- StringBuilder sbElements = new StringBuilder();
- sbElements.append("\tinput files: {"); //$NON-NLS-1$
- Iterator extends Element> iElements = this._roundEnv.getRootElements().iterator();
- boolean hasNext = iElements.hasNext();
- while (hasNext) {
- sbElements.append(iElements.next());
- hasNext = iElements.hasNext();
- if (hasNext) {
- sbElements.append(',');
- }
- }
- sbElements.append('}');
- this._traceRounds.println(sbElements.toString());
-
- StringBuilder sbAnnots = new StringBuilder();
- sbAnnots.append("\tannotations: ["); //$NON-NLS-1$
- Iterator iAnnots = this._unclaimedAnnotations.iterator();
- hasNext = iAnnots.hasNext();
- while (hasNext) {
- sbAnnots.append(iAnnots.next());
- hasNext = iAnnots.hasNext();
- if (hasNext) {
- sbAnnots.append(',');
- }
- }
- sbAnnots.append(']');
- this._traceRounds.println(sbAnnots.toString());
-
- this._traceRounds.println("\tlast round: " + this._roundEnv.processingOver()); //$NON-NLS-1$
- }
-
- // If there are no root annotations, try to find a processor that claims "*"
- this._searchForStar = this._unclaimedAnnotations.isEmpty();
-
- // Iterate over all the already-found processors, giving each one a chance at the unclaimed
- // annotations. If a processor is called at all, it is called on every subsequent round
- // including the final round, but it may be called with an empty set of annotations.
- for (ProcessorInfo pi : this._processors) {
- handleProcessor(pi);
- }
-
- // If there are any unclaimed annotations, or if there were no root annotations and
- // we have not yet run into a processor that claimed "*", continue discovery.
- while (this._searchForStar || !this._unclaimedAnnotations.isEmpty()) {
- ProcessorInfo pi = this._provider.discoverNextProcessor();
- if (null == pi) {
- // There are no more processors to be discovered.
- break;
- }
- handleProcessor(pi);
- }
-
- // TODO: If !unclaimedAnnos.isEmpty(), issue a warning.
- }
-
- /**
- * Evaluate a single processor. Depending on the unclaimed annotations,
- * the annotations this processor supports, and whether it has already been
- * called in a previous round, possibly call its process() method.
- */
- private void handleProcessor(ProcessorInfo pi)
- {
- try {
- Set annotationsToProcess = new HashSet<>();
- boolean shouldCall = pi.computeSupportedAnnotations(
- this._unclaimedAnnotations, annotationsToProcess);
- if (shouldCall) {
- boolean claimed = pi._processor.process(annotationsToProcess, this._roundEnv);
- if (null != this._traceProcessorInfo && !this._roundEnv.processingOver()) {
- StringBuilder sb = new StringBuilder();
- sb.append("Processor "); //$NON-NLS-1$
- sb.append(pi._processor.getClass().getName());
- sb.append(" matches ["); //$NON-NLS-1$
- Iterator i = annotationsToProcess.iterator();
- boolean hasNext = i.hasNext();
- while (hasNext) {
- sb.append(i.next());
- hasNext = i.hasNext();
- if (hasNext) {
- sb.append(' ');
- }
- }
- sb.append("] and returns "); //$NON-NLS-1$
- sb.append(claimed);
- this._traceProcessorInfo.println(sb.toString());
- }
- if (claimed) {
- // The processor claimed its annotations.
- this._unclaimedAnnotations.removeAll(annotationsToProcess);
- if (pi.supportsStar()) {
- this._searchForStar = false;
- }
- }
- }
- } catch (Throwable e) {
- // If a processor throws an exception (as opposed to reporting an error),
- // report it and abort compilation by throwing AbortCompilation.
- this._provider.reportProcessorException(pi._processor, new Exception(e));
- }
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java
deleted file mode 100644
index 7117c2c..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2019 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * IBM Corporation - Fix for bug 328575
- * het@google.com - Bug 415274 - Annotation processing throws a NPE in getElementsAnnotatedWith()
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.dispatch;
-
-import java.lang.annotation.Annotation;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.annotation.processing.RoundEnvironment;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.ElementFilter;
-
-import org.eclipse.jdt.internal.compiler.apt.model.Factory;
-import org.eclipse.jdt.internal.compiler.apt.model.TypeElementImpl;
-import org.eclipse.jdt.internal.compiler.apt.util.ManyToMany;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TagBits;
-
-public class RoundEnvImpl implements RoundEnvironment
-{
- private final BaseProcessingEnvImpl _processingEnv;
- private final boolean _isLastRound;
- private final CompilationUnitDeclaration[] _units;
- private final ManyToMany _annoToUnit;
- private final ReferenceBinding[] _binaryTypes;
- private final Factory _factory;
- private Set _rootElements = null;
-
- public RoundEnvImpl(CompilationUnitDeclaration[] units, ReferenceBinding[] binaryTypeBindings, boolean isLastRound, BaseProcessingEnvImpl env) {
- this._processingEnv = env;
- this._isLastRound = isLastRound;
- this._units = units;
- this._factory = this._processingEnv.getFactory();
-
- // Discover the annotations that will be passed to Processor.process()
- AnnotationDiscoveryVisitor visitor = new AnnotationDiscoveryVisitor(this._processingEnv);
- if (this._units != null) {
- for (CompilationUnitDeclaration unit : this._units) {
- unit.scope.environment.suppressImportErrors = true;
- unit.traverse(visitor, unit.scope);
- unit.scope.environment.suppressImportErrors = false;
- }
- }
- this._annoToUnit = visitor._annoToElement;
- if (binaryTypeBindings != null) collectAnnotations(binaryTypeBindings);
- this._binaryTypes = binaryTypeBindings;
- }
-
- private void collectAnnotations(ReferenceBinding[] referenceBindings) {
- for (ReferenceBinding referenceBinding : referenceBindings) {
- // collect all annotations from the binary types
- if (referenceBinding instanceof ParameterizedTypeBinding) {
- referenceBinding = ((ParameterizedTypeBinding) referenceBinding).genericType();
- }
- AnnotationBinding[] annotationBindings = Factory.getPackedAnnotationBindings(referenceBinding.getAnnotations());
- for (AnnotationBinding annotationBinding : annotationBindings) {
- TypeElement anno = (TypeElement)this._factory.newElement(annotationBinding.getAnnotationType());
- Element element = this._factory.newElement(referenceBinding);
- this._annoToUnit.put(anno, element);
- }
- FieldBinding[] fieldBindings = referenceBinding.fields();
- for (FieldBinding fieldBinding : fieldBindings) {
- annotationBindings = Factory.getPackedAnnotationBindings(fieldBinding.getAnnotations());
- for (AnnotationBinding annotationBinding : annotationBindings) {
- TypeElement anno = (TypeElement)this._factory.newElement(annotationBinding.getAnnotationType());
- Element element = this._factory.newElement(fieldBinding);
- this._annoToUnit.put(anno, element);
- }
- }
- MethodBinding[] methodBindings = referenceBinding.methods();
- for (MethodBinding methodBinding : methodBindings) {
- annotationBindings = Factory.getPackedAnnotationBindings(methodBinding.getAnnotations());
- for (AnnotationBinding annotationBinding : annotationBindings) {
- TypeElement anno = (TypeElement)this._factory.newElement(annotationBinding.getAnnotationType());
- Element element = this._factory.newElement(methodBinding);
- this._annoToUnit.put(anno, element);
- }
- }
- ReferenceBinding[] memberTypes = referenceBinding.memberTypes();
- collectAnnotations(memberTypes);
- }
- }
-
- /**
- * Return the set of annotation types that were discovered on the root elements.
- * This does not include inherited annotations, only those directly on the root
- * elements.
- * @return a set of annotation types, possibly empty.
- */
- public Set getRootAnnotations()
- {
- return Collections.unmodifiableSet(this._annoToUnit.getKeySet());
- }
-
- @Override
- public boolean errorRaised()
- {
- return this._processingEnv.errorRaised();
- }
-
- /**
- * From the set of root elements and their enclosed elements, return the subset that are annotated
- * with {@code a}. If {@code a} is annotated with the {@link java.lang.annotation.Inherited}
- * annotation, include those elements that inherit the annotation from their superclasses.
- * Note that {@link java.lang.annotation.Inherited} only applies to classes (i.e. TypeElements).
- */
- @Override
- public Set extends Element> getElementsAnnotatedWith(TypeElement a)
- {
- if (a.getKind() != ElementKind.ANNOTATION_TYPE) {
- throw new IllegalArgumentException("Argument must represent an annotation type"); //$NON-NLS-1$
- }
- Binding annoBinding = ((TypeElementImpl)a)._binding;
- if (0 != (annoBinding.getAnnotationTagBits() & TagBits.AnnotationInherited)) {
- Set annotatedElements = new HashSet<>(this._annoToUnit.getValues(a));
- // For all other root elements that are TypeElements, and for their recursively enclosed
- // types, add each element if it has a superclass are annotated with 'a'
- ReferenceBinding annoTypeBinding = (ReferenceBinding) annoBinding;
- for (TypeElement element : ElementFilter.typesIn(getRootElements())) {
- ReferenceBinding typeBinding = (ReferenceBinding)((TypeElementImpl)element)._binding;
- addAnnotatedElements(annoTypeBinding, typeBinding, annotatedElements);
- }
- return Collections.unmodifiableSet(annotatedElements);
- }
- return Collections.unmodifiableSet(this._annoToUnit.getValues(a));
- }
-
- /**
- * For every type in types that is a class and that is annotated with anno, either directly or by inheritance,
- * add that type to result. Recursively descend on each types's child classes as well.
- * @param anno the compiler binding for an annotation type
- * @param type a type, not necessarily a class
- * @param result must be a modifiable Set; will accumulate annotated classes
- */
- private void addAnnotatedElements(ReferenceBinding anno, ReferenceBinding type, Set result) {
- if (type.isClass()) {
- if (inheritsAnno(type, anno)) {
- result.add(this._factory.newElement(type));
- }
- }
- for (ReferenceBinding element : type.memberTypes()) {
- addAnnotatedElements(anno, element, result);
- }
- }
-
- /**
- * Check whether an element has a superclass that is annotated with an @Inherited annotation.
- * @param element must be a class (not an interface, enum, etc.).
- * @param anno must be an annotation type, and must be @Inherited
- * @return true if element has a superclass that is annotated with anno
- */
- private boolean inheritsAnno(ReferenceBinding element, ReferenceBinding anno) {
- ReferenceBinding searchedElement = element;
- do {
- if (searchedElement instanceof ParameterizedTypeBinding) {
- searchedElement = ((ParameterizedTypeBinding) searchedElement).genericType();
- }
- AnnotationBinding[] annos = Factory.getPackedAnnotationBindings(searchedElement.getAnnotations());
- for (AnnotationBinding annoBinding : annos) {
- if (annoBinding.getAnnotationType() == anno) { //$IDENTITY-COMPARISON$
- // element is annotated with anno
- return true;
- }
- }
- } while (null != (searchedElement = searchedElement.superclass()));
- return false;
- }
-
- @Override
- public Set extends Element> getElementsAnnotatedWith(Class extends Annotation> a)
- {
- String canonicalName = a.getCanonicalName();
- if (canonicalName == null) {
- // null for anonymous and local classes or an array of those
- throw new IllegalArgumentException("Argument must represent an annotation type"); //$NON-NLS-1$
- }
- TypeElement annoType = this._processingEnv.getElementUtils().getTypeElement(canonicalName);
- if (annoType == null) {
- return Collections.emptySet();
- }
- return getElementsAnnotatedWith(annoType);
- }
-
- @Override
- public Set extends Element> getRootElements()
- {
- if (this._units == null) {
- return Collections.emptySet();
- }
- if (this._rootElements == null) {
- Set elements = new HashSet<>(this._units.length);
- for (CompilationUnitDeclaration unit : this._units) {
- if (unit.moduleDeclaration != null && unit.moduleDeclaration.binding != null) {
- Element m = this._factory.newElement(unit.moduleDeclaration.binding);
- elements.add(m);
- continue;
- }
- if (null == unit.scope || null == unit.scope.topLevelTypes)
- continue;
- for (SourceTypeBinding binding : unit.scope.topLevelTypes) {
- Element element = this._factory.newElement(binding);
- if (null == element) {
- throw new IllegalArgumentException("Top-level type binding could not be converted to element: " + binding); //$NON-NLS-1$
- }
- elements.add(element);
- }
- }
- if (this._binaryTypes != null) {
- for (ReferenceBinding typeBinding : this._binaryTypes) {
- Element element = this._factory.newElement(typeBinding);
- if (null == element) {
- throw new IllegalArgumentException("Top-level type binding could not be converted to element: " + typeBinding); //$NON-NLS-1$
- }
- elements.add(element);
- ModuleBinding binding = typeBinding.module();
- if (binding != null) {
- Element m = this._factory.newElement(binding);
- elements.add(m);
- }
- }
- }
- this._rootElements = elements;
- }
- return this._rootElements;
- }
-
- @Override
- public boolean processingOver()
- {
- return this._isLastRound;
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMemberValue.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMemberValue.java
deleted file mode 100644
index fae18b9..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMemberValue.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2017 Vladimir Piskarev and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Vladimir Piskarev - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-
-public class AnnotationMemberValue extends AnnotationValueImpl {
-
- private final MethodBinding _methodBinding;
-
- /**
- * @param value
- * The JDT representation of a compile-time constant. See
- * {@link org.eclipse.jdt.internal.compiler.lookup.ElementValuePair#getValue()} for possible object types:
- *
- * {@link org.eclipse.jdt.internal.compiler.impl.Constant} for member
- * of primitive type or String
- * {@link org.eclipse.jdt.internal.compiler.lookup.TypeBinding} for a member value of type
- * {@link java.lang.Class}
- * {@link org.eclipse.jdt.internal.compiler.lookup.FieldBinding} for an enum constant
- * {@link org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding} for an annotation instance
- * Object[] for a member value of array type, where the
- * array entries are one of the above
- *
- * @param methodBinding the method binding that defined this member value pair
- */
- public AnnotationMemberValue(BaseProcessingEnvImpl env, Object value, MethodBinding methodBinding) {
- super(env, value, methodBinding.returnType);
- this._methodBinding = methodBinding;
- }
-
- /**
- * @return the method binding that defined this member value pair.
- */
- public MethodBinding getMethodBinding() {
- return this._methodBinding;
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java
deleted file mode 100644
index 78d075b..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java
+++ /dev/null
@@ -1,561 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2016 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * het@google.com - Bug 441790
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.MirroredTypeException;
-import javax.lang.model.type.MirroredTypesException;
-import javax.lang.model.type.TypeMirror;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.impl.Constant;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
-
-public class AnnotationMirrorImpl implements AnnotationMirror, InvocationHandler {
-
- public final BaseProcessingEnvImpl _env;
- public final AnnotationBinding _binding;
-
- /* package */ AnnotationMirrorImpl(BaseProcessingEnvImpl env, AnnotationBinding binding) {
- this._env = env;
- this._binding = binding;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof AnnotationMirrorImpl) {
- if (this._binding == null) {
- return ((AnnotationMirrorImpl) obj)._binding == null;
- }
- return equals(this._binding, ((AnnotationMirrorImpl) obj)._binding);
- }
- return obj == null ? false : obj.equals(this); // obj could be wrapped by a proxy.
- }
-
- private static boolean equals(AnnotationBinding annotationBinding, AnnotationBinding annotationBinding2) {
- if (annotationBinding.getAnnotationType() != annotationBinding2.getAnnotationType()) return false; //$IDENTITY-COMPARISON$
- final ElementValuePair[] elementValuePairs = annotationBinding.getElementValuePairs();
- final ElementValuePair[] elementValuePairs2 = annotationBinding2.getElementValuePairs();
- final int length = elementValuePairs.length;
- if (length != elementValuePairs2.length) return false;
- loop: for (int i = 0; i < length; i++) {
- ElementValuePair pair = elementValuePairs[i];
- // loop on the given pair to make sure one will match
- for (int j = 0; j < length; j++) {
- ElementValuePair pair2 = elementValuePairs2[j];
- if (pair.binding == pair2.binding) {
- if (pair.value == null) {
- if (pair2.value == null) {
- continue loop;
- }
- return false;
- } else {
- if (pair2.value == null) return false;
- if (pair2.value instanceof Object[] && pair.value instanceof Object[]) {
- if (!Arrays.equals((Object[]) pair.value, (Object[]) pair2.value)) {
- return false;
- }
- } else if (!pair2.value.equals(pair.value)){
- return false;
- }
- }
- continue loop;
- }
- }
- return false;
- }
- return true;
- }
-
- @Override
- public DeclaredType getAnnotationType() {
- return (DeclaredType) this._env.getFactory().newTypeMirror(this._binding.getAnnotationType());
- }
-
- /**
- * @return all the members of this annotation mirror that have explicit values.
- * Default values are not included.
- */
- @Override
- public Map extends ExecutableElement, ? extends AnnotationValue> getElementValues() {
- if (this._binding == null) {
- return Collections.emptyMap();
- }
- ElementValuePair[] pairs = this._binding.getElementValuePairs();
- Map valueMap =
- new LinkedHashMap<>(pairs.length);
- for (ElementValuePair pair : pairs) {
- MethodBinding method = pair.getMethodBinding();
- if (method == null) {
- // ideally we should be able to create a fake ExecutableElementImpl
- continue;
- }
- ExecutableElement e = new ExecutableElementImpl(this._env, method);
- AnnotationValue v = new AnnotationMemberValue(this._env, pair.getValue(), method);
- valueMap.put(e, v);
- }
- return Collections.unmodifiableMap(valueMap);
- }
-
- /**
- * @see javax.lang.model.util.Elements#getElementValuesWithDefaults(AnnotationMirror)
- * @return all the members of this annotation mirror that have explicit or default
- * values.
- */
- public Map extends ExecutableElement, ? extends AnnotationValue> getElementValuesWithDefaults() {
- if (this._binding == null) {
- return Collections.emptyMap();
- }
- ElementValuePair[] pairs = this._binding.getElementValuePairs();
- ReferenceBinding annoType = this._binding.getAnnotationType();
- Map valueMap =
- new LinkedHashMap<>();
- for (MethodBinding method : annoType.methods()) {
- // if binding is in ElementValuePair list, then get value from there
- boolean foundExplicitValue = false;
- for (int i = 0; i < pairs.length; ++i) {
- MethodBinding explicitBinding = pairs[i].getMethodBinding();
- if (method == explicitBinding) {
- ExecutableElement e = new ExecutableElementImpl(this._env, explicitBinding);
- AnnotationValue v = new AnnotationMemberValue(this._env, pairs[i].getValue(), explicitBinding);
- valueMap.put(e, v);
- foundExplicitValue = true;
- break;
- }
- }
- // else get default value if one exists
- if (!foundExplicitValue) {
- Object defaultVal = method.getDefaultValue();
- if (null != defaultVal) {
- ExecutableElement e = new ExecutableElementImpl(this._env, method);
- AnnotationValue v = new AnnotationMemberValue(this._env, defaultVal, method);
- valueMap.put(e, v);
- }
- }
- }
- return Collections.unmodifiableMap(valueMap);
- }
-
- @Override
- public int hashCode() {
- if (this._binding == null) return this._env.hashCode();
- return this._binding.hashCode();
- }
-
- /*
- * Used by getAnnotation(), which returns a reflective proxy of the annotation class. When processors then
- * invoke methods such as value() on the annotation proxy, this method is called.
- *
- * A challenge here is that the processor was not necessarily compiled against the same annotation
- * definition that the compiler is looking at right now, not to mention that the annotation itself
- * may be defective in source. So the actual type of the value may be quite different than the
- * type expected by the caller, which will result in a ClassCastException, which is ugly for the
- * processor to try to catch. So we try to catch and correct this type mismatch where possible.
- *
- * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
- */
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
- {
- if (this._binding == null) return null;
- final String methodName = method.getName();
- if ( args == null || args.length == 0 ) {
- if( methodName.equals("hashCode") ) { //$NON-NLS-1$
- return Integer.valueOf(hashCode());
- }
- else if( methodName.equals("toString") ) { //$NON-NLS-1$
- return toString();
- }
- else if( methodName.equals("annotationType")) { //$NON-NLS-1$
- return proxy.getClass().getInterfaces()[0];
- }
- }
- else if ( args.length == 1 && methodName.equals("equals") ) { //$NON-NLS-1$
- return Boolean.valueOf(equals(args[0]));
- }
-
- // If it's not one of the above methods, it must be an annotation member, so it cannot take any arguments
- if ( args != null && args.length != 0 ) {
- throw new NoSuchMethodException("method " + method.getName() + formatArgs(args) + " does not exist on annotation " + toString()); //$NON-NLS-1$ //$NON-NLS-2$
- }
- final MethodBinding methodBinding = getMethodBinding(methodName);
- if ( methodBinding == null ) {
- throw new NoSuchMethodException("method " + method.getName() + "() does not exist on annotation" + toString()); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- Object actualValue = null;
- boolean foundMethod = false;
- ElementValuePair[] pairs = this._binding.getElementValuePairs();
- for (ElementValuePair pair : pairs) {
- if (methodName.equals(new String(pair.getName()))) {
- actualValue = pair.getValue();
- foundMethod = true;
- break;
- }
- }
- if (!foundMethod) {
- // couldn't find explicit value; see if there's a default
- actualValue = methodBinding.getDefaultValue();
- }
- Class> expectedType = method.getReturnType();
- TypeBinding actualType = methodBinding.returnType;
- return getReflectionValue(actualValue, actualType, expectedType);
- }
-
- @Override
- public String toString() {
- TypeMirror decl = getAnnotationType();
- StringBuilder sb = new StringBuilder();
- sb.append('@');
- sb.append(decl.toString());
- Map extends ExecutableElement, ? extends AnnotationValue> values = getElementValues();
- if (!values.isEmpty()) {
- sb.append('(');
- boolean first = true;
- for (Entry extends ExecutableElement, ? extends AnnotationValue> e : values.entrySet()) {
- if (!first) {
- sb.append(", "); //$NON-NLS-1$
- }
- first = false;
- sb.append(e.getKey().getSimpleName());
- sb.append(" = "); //$NON-NLS-1$
- sb.append(e.getValue().toString());
- }
- sb.append(')');
- }
- return sb.toString();
- }
-
- /**
- * Used for constructing exception message text.
- * @return a string like "(a, b, c)".
- */
- private String formatArgs(final Object[] args)
- {
- // estimate that each class name (plus the separators) is 10 characters long plus 2 for "()".
- final StringBuilder builder = new StringBuilder(args.length * 8 + 2 );
- builder.append('(');
- for( int i=0; i 0 )
- builder.append(", "); //$NON-NLS-1$
- builder.append(args[i].getClass().getName());
- }
- builder.append(')');
- return builder.toString();
- }
-
- /**
- * Find a particular annotation member by name.
- * @return a compiler method binding, or null if no member was found.
- */
- private MethodBinding getMethodBinding(String name) {
- ReferenceBinding annoType = this._binding.getAnnotationType();
- MethodBinding[] methods = annoType.getMethods(name.toCharArray());
- for (MethodBinding method : methods) {
- // annotation members have no parameters
- if (method.parameters.length == 0) {
- return method;
- }
- }
- return null;
- }
-
- /**
- * Convert an annotation member value from JDT into Reflection, and from whatever its actual type
- * is into whatever type the reflective invoker of a method is expecting.
- *
- * Only certain types are permitted as member values. Specifically, a member must be a constant,
- * and must be either a primitive type, String, Class, an enum constant, an annotation, or an
- * array of any of those. Multidimensional arrays are not permitted.
- *
- * @param actualValue the value as represented by {@link ElementValuePair#getValue()}
- * @param actualType the return type of the corresponding {@link MethodBinding}
- * @param expectedType the type that the reflective method invoker is expecting
- * @return an object of the expected type representing the annotation member value,
- * or an appropriate dummy value (such as null) if no value is available
- */
- private Object getReflectionValue(Object actualValue, TypeBinding actualType, Class> expectedType)
- {
- if (null == expectedType) {
- // With no expected type, we can't even guess at a conversion
- return null;
- }
- if (null == actualValue) {
- // Return a type-appropriate equivalent of null
- return Factory.getMatchingDummyValue(expectedType);
- }
- if (expectedType.isArray()) {
- if (Class.class.equals(expectedType.getComponentType())) {
- // package Class[]-valued return as a MirroredTypesException
- if (actualType.isArrayType() && ((ArrayBinding)actualType).leafComponentType.erasure().id == TypeIds.T_JavaLangClass) {
-
- Object[] bindings;
- if(actualValue instanceof Object[]) {
- bindings = (Object[]) actualValue;
- } else if(actualValue instanceof TypeBinding) {
- // when a single class element is passed to array: @AnnotationType(Something.class)
- bindings = new Object[] {actualValue};
- } else {
- bindings = null;
- }
-
- if(bindings != null) {
- List mirrors = new ArrayList<>(bindings.length);
- for (int i = 0; i < bindings.length; ++i) {
- if (bindings[i] instanceof TypeBinding) {
- mirrors.add(this._env.getFactory().newTypeMirror((TypeBinding)bindings[i]));
- }
- }
- throw new MirroredTypesException(mirrors);
- }
- }
- // TODO: actual value is not a TypeBinding[]. Should we return a TypeMirror[] around an ErrorType?
- return null;
- }
- // Handle arrays of types other than Class, e.g., int[], MyEnum[], ...
- return convertJDTArrayToReflectionArray(actualValue, actualType, expectedType);
- }
- else if (Class.class.equals(expectedType)) {
- // package the Class-valued return as a MirroredTypeException
- if (actualValue instanceof TypeBinding) {
- TypeMirror mirror = this._env.getFactory().newTypeMirror((TypeBinding)actualValue);
- throw new MirroredTypeException(mirror);
- }
- else {
- // TODO: actual value is not a TypeBinding. Should we return a TypeMirror around an ErrorType?
- return null;
- }
- }
- else {
- // Handle unitary values of type other than Class, e.g., int, MyEnum, ...
- return convertJDTValueToReflectionType(actualValue, actualType, expectedType);
- }
- }
-
- /**
- * Convert an array of JDT types as obtained from ElementValuePair.getValue()
- * (e.g., an Object[] containing IntConstant elements) to the type expected by
- * a reflective method invocation (e.g., int[]).
- *
- * This does not handle arrays of Class, but it does handle primitives, enum constants,
- * and types such as String.
- * @param jdtValue the actual value returned by ElementValuePair.getValue() or MethodBinding.getDefault()
- * @param jdtType the return type of the annotation method binding
- * @param expectedType the type that the invoker of the method is expecting; must be an array type
- * @return an Object which is, e.g., an int[]; or null, if an array cannot be created.
- */
- private Object convertJDTArrayToReflectionArray(Object jdtValue, TypeBinding jdtType, Class> expectedType)
- {
- assert null != expectedType && expectedType.isArray();
- if (!jdtType.isArrayType()) {
- // the compiler says that the type binding isn't an array type; this probably means
- // that there's some sort of syntax error.
- return null;
- }
- Object[] jdtArray;
- // See bug 261969: it's legal to pass a solo element for an array-typed value
- if (jdtValue != null && !(jdtValue instanceof Object[])) {
- // Create an array of the expected type
- jdtArray = (Object[]) Array.newInstance(jdtValue.getClass(), 1);
- jdtArray[0] = jdtValue;
- } else {
- jdtArray = (Object[])jdtValue;
- }
- TypeBinding jdtLeafType = jdtType.leafComponentType();
- Class> expectedLeafType = expectedType.getComponentType();
- final int length = jdtArray.length;
- final Object returnArray = Array.newInstance(expectedLeafType, length);
- for (int i = 0; i < length; ++i) {
- Object jdtElementValue = jdtArray[i];
- if (expectedLeafType.isPrimitive() || String.class.equals(expectedLeafType)) {
- if (jdtElementValue instanceof Constant) {
- if (boolean.class.equals(expectedLeafType)) {
- Array.setBoolean(returnArray, i, ((Constant)jdtElementValue).booleanValue());
- }
- else if (byte.class.equals(expectedLeafType)) {
- Array.setByte(returnArray, i, ((Constant)jdtElementValue).byteValue());
- }
- else if (char.class.equals(expectedLeafType)) {
- Array.setChar(returnArray, i, ((Constant)jdtElementValue).charValue());
- }
- else if (double.class.equals(expectedLeafType)) {
- Array.setDouble(returnArray, i, ((Constant)jdtElementValue).doubleValue());
- }
- else if (float.class.equals(expectedLeafType)) {
- Array.setFloat(returnArray, i, ((Constant)jdtElementValue).floatValue());
- }
- else if (int.class.equals(expectedLeafType)) {
- Array.setInt(returnArray, i, ((Constant)jdtElementValue).intValue());
- }
- else if (long.class.equals(expectedLeafType)) {
- Array.setLong(returnArray, i, ((Constant)jdtElementValue).longValue());
- }
- else if (short.class.equals(expectedLeafType)) {
- Array.setShort(returnArray, i, ((Constant)jdtElementValue).shortValue());
- }
- else if (String.class.equals(expectedLeafType)) {
- Array.set(returnArray, i, ((Constant)jdtElementValue).stringValue());
- }
- }
- else {
- // Primitive or string is expected, but our actual value cannot be coerced into one.
- // TODO: if the actual value is an array of primitives, should we unpack the first one?
- Factory.setArrayMatchingDummyValue(returnArray, i, expectedLeafType);
- }
- }
- else if (expectedLeafType.isEnum()) {
- Object returnVal = null;
- if (jdtLeafType != null && jdtLeafType.isEnum() && jdtElementValue instanceof FieldBinding) {
- FieldBinding binding = (FieldBinding)jdtElementValue;
- try {
- Field returnedField = null;
- returnedField = expectedLeafType.getField( new String(binding.name) );
- if (null != returnedField) {
- returnVal = returnedField.get(null);
- }
- }
- catch (NoSuchFieldException nsfe) {
- // return null
- }
- catch (IllegalAccessException iae) {
- // return null
- }
- }
- Array.set(returnArray, i, returnVal);
- }
- else if (expectedLeafType.isAnnotation()) {
- // member value is expected to be an annotation type. Wrap it in an Annotation proxy.
- Object returnVal = null;
- if (jdtLeafType.isAnnotationType() && jdtElementValue instanceof AnnotationBinding) {
- AnnotationMirrorImpl annoMirror =
- (AnnotationMirrorImpl)this._env.getFactory().newAnnotationMirror((AnnotationBinding)jdtElementValue);
- returnVal = Proxy.newProxyInstance(expectedLeafType.getClassLoader(),
- new Class[]{ expectedLeafType }, annoMirror );
- }
- Array.set(returnArray, i, returnVal);
- }
- else {
- Array.set(returnArray, i, null);
- }
- }
- return returnArray;
- }
-
- /**
- * Convert a JDT annotation value as obtained from ElementValuePair.getValue()
- * (e.g., IntConstant, FieldBinding, etc.) to the type expected by a reflective
- * method invocation (e.g., int, an enum constant, etc.).
- * @return a value of type {@code expectedType}, or a dummy value of that type if
- * the actual value cannot be converted.
- */
- private Object convertJDTValueToReflectionType(Object jdtValue, TypeBinding actualType, Class> expectedType) {
- if (expectedType.isPrimitive() || String.class.equals(expectedType)) {
- if (jdtValue instanceof Constant) {
- if (boolean.class.equals(expectedType)) {
- return ((Constant)jdtValue).booleanValue();
- }
- else if (byte.class.equals(expectedType)) {
- return ((Constant)jdtValue).byteValue();
- }
- else if (char.class.equals(expectedType)) {
- return ((Constant)jdtValue).charValue();
- }
- else if (double.class.equals(expectedType)) {
- return ((Constant)jdtValue).doubleValue();
- }
- else if (float.class.equals(expectedType)) {
- return ((Constant)jdtValue).floatValue();
- }
- else if (int.class.equals(expectedType)) {
- return ((Constant)jdtValue).intValue();
- }
- else if (long.class.equals(expectedType)) {
- return ((Constant)jdtValue).longValue();
- }
- else if (short.class.equals(expectedType)) {
- return ((Constant)jdtValue).shortValue();
- }
- else if (String.class.equals(expectedType)) {
- return ((Constant)jdtValue).stringValue();
- }
- }
- // Primitive or string is expected, but our actual value cannot be coerced into one.
- // TODO: if the actual value is an array of primitives, should we unpack the first one?
- return Factory.getMatchingDummyValue(expectedType);
- }
- else if (expectedType.isEnum()) {
- Object returnVal = null;
- if (actualType != null && actualType.isEnum() && jdtValue instanceof FieldBinding) {
-
- FieldBinding binding = (FieldBinding)jdtValue;
- try {
- Field returnedField = null;
- returnedField = expectedType.getField( new String(binding.name) );
- if (null != returnedField) {
- returnVal = returnedField.get(null);
- }
- }
- catch (NoSuchFieldException nsfe) {
- // return null
- }
- catch (IllegalAccessException iae) {
- // return null
- }
- }
- return null == returnVal ? Factory.getMatchingDummyValue(expectedType) : returnVal;
- }
- else if (expectedType.isAnnotation()) {
- // member value is expected to be an annotation type. Wrap it in an Annotation proxy.
- if (actualType.isAnnotationType() && jdtValue instanceof AnnotationBinding) {
- AnnotationMirrorImpl annoMirror =
- (AnnotationMirrorImpl)this._env.getFactory().newAnnotationMirror((AnnotationBinding)jdtValue);
- return Proxy.newProxyInstance(expectedType.getClassLoader(),
- new Class[]{ expectedType }, annoMirror );
- }
- else {
- // No way to cast a non-annotation value to an annotation type; return null to caller
- return null;
- }
- }
- else {
- return Factory.getMatchingDummyValue(expectedType);
- }
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/AnnotationValueImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/AnnotationValueImpl.java
deleted file mode 100644
index 60d382e..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/AnnotationValueImpl.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2023 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * het@google.com - Bug 441790
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.AnnotationValueVisitor;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.impl.Constant;
-import org.eclipse.jdt.internal.compiler.impl.DoubleConstant;
-import org.eclipse.jdt.internal.compiler.impl.FloatConstant;
-import org.eclipse.jdt.internal.compiler.impl.LongConstant;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
-import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
-import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement;
-import org.eclipse.jdt.internal.compiler.util.Util;
-
-public class AnnotationValueImpl implements AnnotationValue, TypeIds {
-
- /*
- * Additions to T_* constants in TypeIds.
- */
- private static final int T_AnnotationMirror = -1;
- private static final int T_EnumConstant = -2;
- private static final int T_ClassObject = -3;
- private static final int T_ArrayType = -4;
-
- private final BaseProcessingEnvImpl _env;
-
- /**
- * The annotation value, as it would be returned by
- * {@link #getValue()}. For instance, an Integer (for an int
- * constant), a VariableElement (for an enum constant), or
- * a List containing multiple such (for an array type).
- */
- private final Object _value;
-
- /**
- * The type stored in _value, represented as a T_* value from {@link TypeIds}
- * or one of the additional T_* values defined in this class.
- */
- private final int _kind;
-
- /**
- * @param value
- * The JDT representation of a compile-time constant. See
- * {@link org.eclipse.jdt.internal.compiler.lookup.ElementValuePair#getValue()} for possible object types:
- *
- * {@link org.eclipse.jdt.internal.compiler.impl.Constant} for member
- * of primitive type or String
- * {@link TypeBinding} for a member value of type
- * {@link java.lang.Class}
- * {@link FieldBinding} for an enum constant
- * {@link AnnotationBinding} for an annotation instance
- * Object[] for a member value of array type, where the
- * array entries are one of the above
- *
- * @param type
- * The JDT representation of the type of the constant, as determined
- * by the return type of the element. This is needed because the type
- * of the value may have been widened (e.g., byte to int) by the compiler
- * and we need to call the proper visitor. This is used only for base types.
- * If it is null or not a BaseTypeBinding, it is ignored and the type is
- * determined from the type of the value.
- */
- public AnnotationValueImpl(BaseProcessingEnvImpl env, Object value, TypeBinding type) {
- this._env = env;
- int kind[] = new int[1];
- if (type == null) {
- this._value = convertToMirrorType(value, type, kind);
- this._kind = kind[0];
- } else if (type.isArrayType()) {
- List convertedValues = null;
- TypeBinding valueType = ((ArrayBinding)type).elementsType();
- if (value instanceof Object[]) {
- Object[] values = (Object[])value;
- convertedValues = new ArrayList<>(values.length);
- for (Object oneValue : values) {
- convertedValues.add(new AnnotationValueImpl(this._env, oneValue, valueType));
- }
- } else {
- convertedValues = new ArrayList<>(1);
- convertedValues.add(new AnnotationValueImpl(this._env, value, valueType));
- }
- this._value = Collections.unmodifiableList(convertedValues);
- this._kind = T_ArrayType;
- } else {
- this._value = convertToMirrorType(value, type, kind);
- this._kind = kind[0];
- }
- }
-
- /**
- * Convert the JDT representation of a single constant into its javax.lang.model
- * representation. For instance, convert a StringConstant into a String, or
- * a FieldBinding into a VariableElement. This does not handle the case where
- * value is an Object[].
- * @param value the JDT object
- * @param type the return type of the annotation member. If null or not a
- * BaseTypeBinding, this is ignored and the value is inspected to determine type.
- * @param kind an int array whose first element will be set to the type of the
- * converted object, represented with T_* values from TypeIds or from this class.
- * @return converted mirror type
- */
- private Object convertToMirrorType(Object value, TypeBinding type, int kind[]) {
- if (type == null) {
- kind[0] = TypeIds.T_JavaLangString;
- return ""; //$NON-NLS-1$
- } else if (type instanceof BaseTypeBinding || type.id == TypeIds.T_JavaLangString) {
- if (value == null) {
- if (type instanceof BaseTypeBinding
- || type.id == TypeIds.T_JavaLangString) {
- // return a string with error in it to reflect a value that could not be resolved
- kind[0] = TypeIds.T_JavaLangString;
- return ""; //$NON-NLS-1$
- } else if (type.isAnnotationType()) {
- kind[0] = T_AnnotationMirror;
- return this._env.getFactory().newAnnotationMirror(null);
- }
- } else if (value instanceof Constant) {
- if (type instanceof BaseTypeBinding) {
- kind[0] = ((BaseTypeBinding)type).id;
- }
- else if (type.id == TypeIds.T_JavaLangString) {
- kind[0] = ((Constant)value).typeID();
- } else {
- // error case
- kind[0] = TypeIds.T_JavaLangString;
- return ""; //$NON-NLS-1$
- }
- switch (kind[0]) {
- case T_boolean:
- return ((Constant)value).booleanValue();
- case T_byte:
- return ((Constant)value).byteValue();
- case T_char:
- return ((Constant)value).charValue();
- case T_double:
- return ((Constant)value).doubleValue();
- case T_float:
- return ((Constant)value).floatValue();
- case T_int:
- try {
- if (value instanceof LongConstant
- || value instanceof DoubleConstant
- || value instanceof FloatConstant) {
- // error case
- kind[0] = TypeIds.T_JavaLangString;
- return ""; //$NON-NLS-1$
- }
- return ((Constant)value).intValue();
- } catch (ShouldNotImplement e) {
- kind[0] = TypeIds.T_JavaLangString;
- return ""; //$NON-NLS-1$
- }
- case T_JavaLangString:
- return ((Constant)value).stringValue();
- case T_long:
- return ((Constant)value).longValue();
- case T_short:
- return ((Constant)value).shortValue();
- }
- }
- } else if (type.isEnum()) {
- if (value instanceof FieldBinding) {
- kind[0] = T_EnumConstant;
- return this._env.getFactory().newElement((FieldBinding) value);
- } else {
- kind[0] = TypeIds.T_JavaLangString;
- return ""; //$NON-NLS-1$
- }
- } else if (type.isAnnotationType()) {
- if (value instanceof AnnotationBinding) {
- kind[0] = T_AnnotationMirror;
- return this._env.getFactory().newAnnotationMirror((AnnotationBinding) value);
- }
- } else if (value instanceof TypeBinding) {
- kind[0] = T_ClassObject;
- return this._env.getFactory().newTypeMirror((TypeBinding) value);
- }
- // error case
- kind[0] = TypeIds.T_JavaLangString;
- return ""; //$NON-NLS-1$
- }
-
- @SuppressWarnings("unchecked") // Need to cast Object _value to a List
- @Override
- public R accept(AnnotationValueVisitor v, P p) {
- switch (this._kind) {
- case TypeIds.T_boolean:
- return v.visitBoolean((Boolean)this._value, p);
- case TypeIds.T_byte:
- return v.visitByte((Byte)this._value, p);
- case TypeIds.T_char:
- return v.visitChar((Character)this._value, p);
- case TypeIds.T_double:
- return v.visitDouble((Double)this._value, p);
- case TypeIds.T_float:
- return v.visitFloat((Float)this._value, p);
- case TypeIds.T_int:
- return v.visitInt((Integer)this._value, p);
- case TypeIds.T_JavaLangString:
- return v.visitString((String)this._value, p);
- case TypeIds.T_long:
- return v.visitLong((Long)this._value, p);
- case TypeIds.T_short:
- return v.visitShort((Short)this._value, p);
- case T_EnumConstant:
- return v.visitEnumConstant((VariableElement)this._value, p);
- case T_ClassObject:
- return v.visitType((TypeMirror)this._value, p);
- case T_AnnotationMirror:
- return v.visitAnnotation((AnnotationMirror)this._value, p);
- case T_ArrayType:
- return v.visitArray((List)this._value, p);
- default:
- return null;
- }
- }
-
- @Override
- public Object getValue() {
- return this._value;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof AnnotationValueImpl) {
- return this._value.equals(((AnnotationValueImpl) obj)._value);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return this._value.hashCode() + this._kind;
- }
-
- @Override
- public String toString() {
- if (this._value == null) {
- return "null"; //$NON-NLS-1$
- } else if (this._value instanceof String) {
- String value = (String) this._value;
- StringBuilder sb = new StringBuilder();
- sb.append('"');
- for (int i = 0; i < value.length(); i++) {
- Util.appendEscapedChar(sb, value.charAt(i), true);
- }
- sb.append('"');
- return sb.toString();
- } else if (this._value instanceof Character) {
- StringBuilder sb = new StringBuilder();
- sb.append('\'');
- Util.appendEscapedChar(sb, ((Character) this._value).charValue(), false);
- sb.append('\'');
- return sb.toString();
- } else if (this._value instanceof VariableElement) {
- VariableElement enumDecl = (VariableElement) this._value;
- return enumDecl.asType().toString() + "." + enumDecl.getSimpleName(); //$NON-NLS-1$
- } else if (this._value instanceof Collection) {
- // It must be Collection
- @SuppressWarnings("unchecked")
- Collection values = (Collection) this._value;
- StringBuilder sb = new StringBuilder();
- sb.append('{');
- boolean first = true;
- for (AnnotationValue annoValue : values) {
- if (!first) {
- sb.append(", "); //$NON-NLS-1$
- }
- first = false;
- sb.append(annoValue.toString());
- }
- sb.append('}');
- return sb.toString();
- } else if (this._value instanceof TypeMirror) {
- return this._value.toString() + ".class"; //$NON-NLS-1$
- } else {
- return this._value.toString();
- }
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ArrayTypeImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ArrayTypeImpl.java
deleted file mode 100644
index 378c716..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ArrayTypeImpl.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2014 BEA Systems, Inc. and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- * IBM Corporation - fix for 342598
- * IBM Corporation - Java 8 support
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVisitor;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-
-/**
- * Implementation of ArrayType, which represents an array of some type.
- */
-public class ArrayTypeImpl extends TypeMirrorImpl implements ArrayType {
-
- ArrayTypeImpl(BaseProcessingEnvImpl env, ArrayBinding binding) {
- super(env, binding);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.ArrayType#getComponentType()
- */
- @Override
- public TypeMirror getComponentType() {
- return this._env.getFactory().newTypeMirror(((ArrayBinding)this._binding).elementsType());
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeMirror#accept(javax.lang.model.type.TypeVisitor, java.lang.Object)
- */
- @Override
- public R accept(TypeVisitor v, P p) {
- return v.visitArray(this, p);
- }
-
- @Override
- protected AnnotationBinding[] getAnnotationBindings() {
- AnnotationBinding[] oldies = ((ArrayBinding)this._binding).getTypeAnnotations();
- AnnotationBinding[] newbies = Binding.NO_ANNOTATIONS;
- // Strip out the annotations on sub arrays
- for (int i = 0, length = oldies == null ? 0 : oldies.length; i < length; i++) {
- if (oldies[i] == null) {
- System.arraycopy(oldies, 0, newbies = new AnnotationBinding[i], 0, i);
- return newbies;
- }
- }
- return newbies;
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeMirror#getKind()
- */
- @Override
- public TypeKind getKind() {
- return TypeKind.ARRAY;
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/DeclaredTypeImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/DeclaredTypeImpl.java
deleted file mode 100644
index f1ece38..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/DeclaredTypeImpl.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2023 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- * IBM Corporation - fix for 342598
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVisitor;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-
-/**
- * Implementation of DeclaredType, which refers to a particular usage or instance of a type.
- * Contrast with {@link javax.lang.model.element.TypeElement}, which is an element that potentially defines a family
- * of DeclaredTypes.
- */
-public class DeclaredTypeImpl extends TypeMirrorImpl implements DeclaredType {
-
- private final ElementKind _elementKindHint;
-
- /* package */ DeclaredTypeImpl(BaseProcessingEnvImpl env, ReferenceBinding binding) {
- super(env, binding);
- this._elementKindHint = null;
- }
-
- /**
- * Create a DeclaredType that knows in advance what kind of element to produce from asElement().
- * This is useful in the case where the type binding is to an unresolved type, but we know
- * from context what type it is - e.g., an annotation type.
- */
- /* package */ DeclaredTypeImpl(BaseProcessingEnvImpl env, ReferenceBinding binding, ElementKind elementKindHint) {
- super(env, binding);
- this._elementKindHint = elementKindHint;
- }
-
- @Override
- public Element asElement() {
- TypeBinding prototype = null;
- if (this._binding instanceof TypeBinding) {
- prototype = ((TypeBinding) this._binding).prototype();
- }
- if (prototype != null) {
- return this._env.getFactory().newElement(prototype, this._elementKindHint);
- }
- // The JDT compiler does not distinguish between type elements and declared types
- return this._env.getFactory().newElement(this._binding, this._elementKindHint);
- }
-
- @Override
- public TypeMirror getEnclosingType() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- ReferenceBinding enclosingType = binding.enclosingType();
- if (enclosingType != null) {
- return this._env.getFactory().newTypeMirror(enclosingType);
- }
- return this._env.getFactory().getNoType(TypeKind.NONE);
- }
-
- /*
- * (non-Javadoc)
- * @see javax.lang.model.type.DeclaredType#getTypeArguments()
- * @see javax.lang.model.element.TypeElement#getTypeParameters().
- */
- @Override
- public List extends TypeMirror> getTypeArguments() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- if (binding.isParameterizedType()) {
- ParameterizedTypeBinding ptb = (ParameterizedTypeBinding)this._binding;
- TypeBinding[] arguments = ptb.arguments;
- int length = arguments == null ? 0 : arguments.length;
- if (length == 0) return Collections.emptyList();
- List args = new ArrayList<>(length);
- for (TypeBinding arg : arguments) {
- args.add(this._env.getFactory().newTypeMirror(arg));
- }
- return Collections.unmodifiableList(args);
- }
- if (binding.isGenericType()) {
- TypeVariableBinding[] typeVariables = binding.typeVariables();
- List args = new ArrayList<>(typeVariables.length);
- for (TypeBinding arg : typeVariables) {
- args.add(this._env.getFactory().newTypeMirror(arg));
- }
- return Collections.unmodifiableList(args);
- }
- return Collections.emptyList();
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeMirror#accept(javax.lang.model.type.TypeVisitor, java.lang.Object)
- */
- @Override
- public R accept(TypeVisitor v, P p) {
- return v.visitDeclared(this, p);
- }
-
- @Override
- public TypeKind getKind() {
- return TypeKind.DECLARED;
- }
-
- @Override
- public String toString() {
- return new String(this._binding.readableName());
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java
deleted file mode 100644
index b258002..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2017 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.lang.annotation.Annotation;
-import java.lang.annotation.Inherited;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.type.TypeMirror;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-
-/**
- * Element represents any defined Java language element - a package,
- * a method, a class or interface. Contrast with DeclaredType.
- */
-public abstract class ElementImpl
- implements javax.lang.model.element.Element, IElementInfo
-{
- public final BaseProcessingEnvImpl _env;
- public final Binding _binding;
-
- protected ElementImpl(BaseProcessingEnvImpl env, Binding binding) {
- this._env = env;
- this._binding = binding;
- }
-
- @Override
- public TypeMirror asType() {
- return this._env.getFactory().newTypeMirror(this._binding);
- }
-
- /**
- * @return the set of compiler annotation bindings on this element
- */
- protected abstract AnnotationBinding[] getAnnotationBindings();
-
- /* Package any repeating annotations into containers, return others as is.
- In the compiler bindings repeating annotations are left in as is, hence
- this step. The return value would match what one would expect to see in
- a class file.
- */
- public final AnnotationBinding [] getPackedAnnotationBindings() {
- return Factory.getPackedAnnotationBindings(getAnnotationBindings());
- }
-
- @Override
- public A getAnnotation(Class annotationClass) {
- A annotation = this._env.getFactory().getAnnotation(getPackedAnnotationBindings(), annotationClass);
- if (annotation != null || this.getKind() != ElementKind.CLASS || annotationClass.getAnnotation(Inherited.class) == null)
- return annotation;
-
- ElementImpl superClass = (ElementImpl) this._env.getFactory().newElement(((ReferenceBinding) this._binding).superclass());
- return superClass == null ? null : superClass.getAnnotation(annotationClass);
- }
-
- @Override
- public List extends AnnotationMirror> getAnnotationMirrors() {
- return this._env.getFactory().getAnnotationMirrors(getPackedAnnotationBindings());
- }
-
- @Override
- public A[] getAnnotationsByType(Class annotationType) {
- A [] annotations = this._env.getFactory().getAnnotationsByType(Factory.getUnpackedAnnotationBindings(getPackedAnnotationBindings()), annotationType);
- if (annotations.length != 0 || this.getKind() != ElementKind.CLASS || annotationType.getAnnotation(Inherited.class) == null)
- return annotations;
-
- ElementImpl superClass = (ElementImpl) this._env.getFactory().newElement(((ReferenceBinding) this._binding).superclass());
- return superClass == null ? annotations : superClass.getAnnotationsByType(annotationType);
- }
-
- @Override
- public Set getModifiers() {
- // Most subclasses implement this; this default is appropriate for
- // PackageElement and TypeParameterElement.
- return Collections.emptySet();
- }
-
- @Override
- public Name getSimpleName() {
- return new NameImpl(this._binding.shortReadableName());
- }
-
- @Override
- public int hashCode() {
- return this._binding.hashCode();
- }
-
- // TODO: equals() implemented as == of JDT bindings. Valid within
- // a single Compiler instance; breaks in IDE if processors cache values.
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final ElementImpl other = (ElementImpl) obj;
- if (this._binding == null) {
- if (other._binding != null)
- return false;
- } else if (this._binding != other._binding)
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return this._binding.toString();
- }
-
- @Override
- public String getFileName() {
- // Subclasses should override and return something of value
- return null;
- }
-
- /**
- * @return the package containing this element. The package of a PackageElement is itself.
- */
- PackageElement getPackage() {
- return null;
- }
-
- /**
- * Subclassed by VariableElementImpl, TypeElementImpl, and ExecutableElementImpl.
- * This base implementation suffices for other types.
- * @see javax.lang.model.util.Elements#hides
- * @return true if this element hides {@code hidden}
- */
- public boolean hides(Element hidden)
- {
- return false;
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java
deleted file mode 100644
index 20b5173..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java
+++ /dev/null
@@ -1,741 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2023 BEA Systems, Inc. and others
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- * IBM Corporation - Fix for bug 341494
- * IBM Corporation - Fix for bug 328575
- * IBM Corporation - Java 8 support
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.ModuleElement;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.Elements;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Javadoc;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodVerifier;
-import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TagBits;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
-
-/**
- * Utilities for working with java8 and earlier language elements.
- * There is one of these for every ProcessingEnvironment.
- *
- * @see ElementsImpl9
- */
-public class ElementsImpl implements Elements {
-
- // Used for parsing Javadoc comments: matches initial delimiter, followed by whitespace
- private static final Pattern INITIAL_DELIMITER = Pattern.compile("^\\s*/\\*+"); //$NON-NLS-1$
-
- protected final BaseProcessingEnvImpl _env;
-
- /*
- * The processing env creates and caches an ElementsImpl. Other clients should
- * not create their own; they should ask the env for it.
- */
- protected ElementsImpl(BaseProcessingEnvImpl env) {
- this._env = env;
- }
-
- public static ElementsImpl create(BaseProcessingEnvImpl env) {
- return (SourceVersion.latest().compareTo(SourceVersion.RELEASE_8) <= 0)? new ElementsImpl(env): new ElementsImpl9(env);
- }
-
- /**
- * Return all the annotation mirrors on this element, including inherited annotations.
- * Annotations are inherited only if the annotation type is meta-annotated with @Inherited,
- * and the annotation is on a class: e.g., annotations are not inherited for interfaces, methods,
- * or fields.
- */
- @Override
- public List extends AnnotationMirror> getAllAnnotationMirrors(Element e) {
- // if e is a class, walk up its superclass hierarchy looking for @Inherited annotations not already in the list
- if (e.getKind() == ElementKind.CLASS && e instanceof TypeElementImpl) {
- List annotations = new ArrayList<>();
- // A class can only have one annotation of a particular annotation type.
- Set annotationTypes = new HashSet<>();
- ReferenceBinding binding = (ReferenceBinding)((TypeElementImpl)e)._binding;
- boolean checkIfInherited = false;
- while (null != binding) {
- if (binding instanceof ParameterizedTypeBinding) {
- binding = ((ParameterizedTypeBinding) binding).genericType();
- }
- for (AnnotationBinding annotation : Factory.getPackedAnnotationBindings(binding.getAnnotations())) {
- if (annotation == null) continue;
- ReferenceBinding annotationType = annotation.getAnnotationType();
- if (checkIfInherited && (annotationType.getAnnotationTagBits() & TagBits.AnnotationInherited) == 0)
- continue;
- if (!annotationTypes.contains(annotationType)) {
- annotationTypes.add(annotationType);
- annotations.add(annotation);
- }
- }
- binding = binding.superclass();
- checkIfInherited = true;
- }
- List list = new ArrayList<>(annotations.size());
- for (AnnotationBinding annotation : annotations) {
- list.add(this._env.getFactory().newAnnotationMirror(annotation));
- }
- return Collections.unmodifiableList(list);
- }
- else {
- return e.getAnnotationMirrors();
- }
- }
-
- /**
- * Compute a list of all the visible entities in this type. Specifically:
- *
- * All nested types declared in this type, including interfaces and enums
- * All protected or public nested types declared in this type's superclasses
- * and superinterfaces, that are not hidden by a name collision
- * All methods declared in this type, including constructors but not
- * including static or instance initializers, and including abstract
- * methods and unimplemented methods declared in interfaces
- * All protected or public methods declared in this type's superclasses,
- * that are not overridden by another method, but not including constructors
- * or initializers. Includes abstract methods and methods declared in
- * superinterfaces but not implemented
- * All fields declared in this type, including constants
- * All non-private fields declared in this type's superclasses and
- * superinterfaces, that are not hidden by a name collision.
- *
- */
- @Override
- public List extends Element> getAllMembers(TypeElement type) {
- if (null == type || !(type instanceof TypeElementImpl)) {
- return Collections.emptyList();
- }
- ReferenceBinding binding = (ReferenceBinding)((TypeElementImpl)type)._binding;
- // Map of element simple name to binding
- Map types = new HashMap<>();
- // Javac implementation does not take field name collisions into account
- List fields = new ArrayList<>();
- // For methods, need to compare parameters, not just names
- Map> methods = new HashMap<>();
- Set superinterfaces = new LinkedHashSet<>();
- boolean ignoreVisibility = true;
- while (null != binding) {
- addMembers(binding, ignoreVisibility, types, fields, methods);
- Set newfound = new LinkedHashSet<>();
- collectSuperInterfaces(binding, superinterfaces, newfound);
- for (ReferenceBinding superinterface : newfound) {
- addMembers(superinterface, false, types, fields, methods);
- }
- superinterfaces.addAll(newfound);
- binding = binding.superclass();
- ignoreVisibility = false;
- }
- List allMembers = new ArrayList<>();
- for (ReferenceBinding nestedType : types.values()) {
- allMembers.add(this._env.getFactory().newElement(nestedType));
- }
- for (FieldBinding field : fields) {
- allMembers.add(this._env.getFactory().newElement(field));
- }
- for (Set sameNamedMethods : methods.values()) {
- for (MethodBinding method : sameNamedMethods) {
- allMembers.add(this._env.getFactory().newElement(method));
- }
- }
- return allMembers;
- }
-
- /**
- * Recursively depth-first walk the tree of superinterfaces of a type, collecting
- * all the unique superinterface bindings. (Note that because of generics, a type may
- * have multiple unique superinterface bindings corresponding to the same interface
- * declaration.)
- * @param existing bindings already in this set will not be re-added or recursed into
- * @param newfound newly found bindings will be added to this set
- */
- private void collectSuperInterfaces(ReferenceBinding type,
- Set existing, Set newfound) {
- for (ReferenceBinding superinterface : type.superInterfaces()) {
- if (!existing.contains(superinterface) && !newfound.contains(superinterface)) {
- newfound.add(superinterface);
- collectSuperInterfaces(superinterface, existing, newfound);
- }
- }
- }
-
- /**
- * Add the members of a type to the maps of subtypes, fields, and methods. Add only those
- * which are non-private and which are not overridden by an already-discovered member.
- * For fields, add them all; javac implementation does not take field hiding into account.
- * @param binding the type whose members will be added to the lists
- * @param directMembers if true, all members will be added regardless of whether they
- * are private, overridden, static etc.
- * @param types a map of type simple name to type binding
- * @param fields a list of field bindings
- * @param methods a map of method simple name to set of method bindings with that name
- */
- private void addMembers(ReferenceBinding binding, boolean directMembers, Map types,
- List fields, Map> methods)
- {
- for (ReferenceBinding subtype : binding.memberTypes()) {
- if (directMembers || !subtype.isPrivate()) {
- String name = new String(subtype.sourceName());
- if (null == types.get(name)) {
- types.put(name, subtype);
- }
- }
- }
- for (FieldBinding field : binding.fields()) {
- if (directMembers || !field.isPrivate()) {
- fields.add(field);
- }
- }
- for (MethodBinding method : binding.methods()) {
- if (!directMembers && method.isStatic())
- continue;
- if (!method.isSynthetic() && (directMembers || (!method.isPrivate() && !method.isConstructor()))) {
- String methodName = new String(method.selector);
- Set sameNamedMethods = methods.get(methodName);
- if (null == sameNamedMethods) {
- // New method name. Create a set for it and add it to the list.
- // We don't expect many methods with same name, so only 4 slots:
- sameNamedMethods = new HashSet<>(4);
- methods.put(methodName, sameNamedMethods);
- sameNamedMethods.add(method);
- }
- else {
- // We already have a method with this name. Is this method overridden?
- boolean unique = true;
- if (!directMembers) {
- for (MethodBinding existing : sameNamedMethods) {
- MethodVerifier verifier = this._env.getLookupEnvironment().methodVerifier();
- if (verifier.doesMethodOverride(existing, method)) {
- unique = false;
- break;
- }
- }
- }
- if (unique) {
- sameNamedMethods.add(method);
- }
- }
- }
- }
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.util.Elements#getBinaryName(javax.lang.model.element.TypeElement)
- */
- @Override
- public Name getBinaryName(TypeElement type) {
- TypeElementImpl typeElementImpl = (TypeElementImpl) type;
- ReferenceBinding referenceBinding = (ReferenceBinding) typeElementImpl._binding;
- return new NameImpl(
- CharOperation.replaceOnCopy(referenceBinding.constantPoolName(), '/', '.'));
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.util.Elements#getConstantExpression(java.lang.Object)
- */
- @Override
- public String getConstantExpression(Object value) {
- if (!(value instanceof Integer)
- && !(value instanceof Byte)
- && !(value instanceof Float)
- && !(value instanceof Double)
- && !(value instanceof Long)
- && !(value instanceof Short)
- && !(value instanceof Character)
- && !(value instanceof String)
- && !(value instanceof Boolean)) {
- throw new IllegalArgumentException("Not a valid wrapper type : " + value.getClass()); //$NON-NLS-1$
- }
- if (value instanceof Character) {
- StringBuilder builder = new StringBuilder();
- builder.append('\'').append(value).append('\'');
- return String.valueOf(builder);
- } else if (value instanceof String) {
- StringBuilder builder = new StringBuilder();
- builder.append('\"').append(value).append('\"');
- return String.valueOf(builder);
- } else if (value instanceof Float) {
- StringBuilder builder = new StringBuilder();
- builder.append(value).append('f');
- return String.valueOf(builder);
- } else if (value instanceof Long) {
- StringBuilder builder = new StringBuilder();
- builder.append(value).append('L');
- return String.valueOf(builder);
- } else if (value instanceof Short) {
- StringBuilder builder = new StringBuilder();
- builder.append("(short)").append(value); //$NON-NLS-1$
- return String.valueOf(builder);
- } else if (value instanceof Byte) {
- StringBuilder builder = new StringBuilder();
- builder.append("(byte)0x"); //$NON-NLS-1$
- int intValue = ((Byte) value).byteValue();
- String hexString = Integer.toHexString(intValue & 0xFF);
- if (hexString.length() < 2) {
- builder.append('0');
- }
- builder.append(hexString);
- return String.valueOf(builder);
- }
- return String.valueOf(value);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.util.Elements#getDocComment(javax.lang.model.element.Element)
- */
- @Override
- public String getDocComment(Element e) {
- char[] unparsed = getUnparsedDocComment(e);
- return formatJavadoc(unparsed);
- }
-
- /**
- * Return the entire javadoc comment on e, including the comment characters and whitespace
- * @param e an Element of any sort, possibly with a javadoc comment.
- * @return a String, or null if the comment is not available
- */
- private char[] getUnparsedDocComment(Element e)
- {
- Javadoc javadoc = null;
- ReferenceContext referenceContext = null;
- switch(e.getKind()) {
- case ANNOTATION_TYPE :
- case CLASS :
- case ENUM :
- case INTERFACE :
- case RECORD :
- TypeElementImpl typeElementImpl = (TypeElementImpl) e;
- ReferenceBinding referenceBinding = (ReferenceBinding)typeElementImpl._binding;
- if (referenceBinding instanceof SourceTypeBinding) {
- SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) referenceBinding;
- referenceContext = sourceTypeBinding.scope.referenceContext;
- javadoc = ((TypeDeclaration) referenceContext).javadoc;
- }
- break;
- case PACKAGE :
- // might need to handle javadoc of package-info.java file
- PackageElementImpl packageElementImpl = (PackageElementImpl) e;
- PackageBinding packageBinding = (PackageBinding) packageElementImpl._binding;
- char[][] compoundName = CharOperation.arrayConcat(packageBinding.compoundName, TypeConstants.PACKAGE_INFO_NAME);
- ReferenceBinding type = this._env.getLookupEnvironment().getType(compoundName);
- if (type != null && type.isValidBinding() && (type instanceof SourceTypeBinding)) {
- SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) type;
- referenceContext = sourceTypeBinding.scope.referenceContext;
- javadoc = ((TypeDeclaration) referenceContext).javadoc;
- }
- break;
- case CONSTRUCTOR :
- case METHOD :
- ExecutableElementImpl executableElementImpl = (ExecutableElementImpl) e;
- MethodBinding methodBinding = (MethodBinding) executableElementImpl._binding;
- AbstractMethodDeclaration sourceMethod = methodBinding.sourceMethod();
- if (sourceMethod != null) {
- javadoc = sourceMethod.javadoc;
- referenceContext = sourceMethod;
- }
- break;
- case RECORD_COMPONENT :
- case ENUM_CONSTANT :
- case FIELD :
- VariableElementImpl variableElementImpl = (VariableElementImpl) e;
- FieldBinding fieldBinding = (FieldBinding) variableElementImpl._binding;
- FieldDeclaration sourceField = fieldBinding.sourceField();
- if (sourceField != null) {
- javadoc = sourceField.javadoc;
- if (fieldBinding.declaringClass instanceof SourceTypeBinding) {
- SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) fieldBinding.declaringClass;
- referenceContext = sourceTypeBinding.scope.referenceContext;
- }
- }
- break;
- default:
- return null;
- }
- if (javadoc != null && referenceContext != null) {
- char[] contents = referenceContext.compilationResult().getCompilationUnit().getContents();
- if (contents != null) {
- return CharOperation.subarray(contents, javadoc.sourceStart, javadoc.sourceEnd - 1);
- }
- }
- return null;
- }
-
- /**
- * Strip the comment characters from a javadoc comment. Assume the comment is already
- * missing its closing delimiter.
- *
- * Javac's behavior with regard to tab expansion and trimming of whitespace and
- * asterisks is bizarre and undocumented. We do our best here to emulate it.
- */
- private static String formatJavadoc(char[] unparsed)
- {
- if (unparsed == null || unparsed.length < 5) { // delimiters take 5 chars
- return null;
- }
-
- String[] lines = new String(unparsed).split("\n"); //$NON-NLS-1$
- Matcher delimiterMatcher = INITIAL_DELIMITER.matcher(lines[0]);
- if (!delimiterMatcher.find()) {
- return null;
- }
- int iOpener = delimiterMatcher.end();
- lines[0] = lines[0].substring(iOpener);
- if (lines.length == 1) {
- // single-line comment. Should trim(), but javac doesn't.
- // we should however remove the starting whitespaces
- StringBuilder sb = new StringBuilder();
- char[] chars = lines[0].toCharArray();
- boolean startingWhitespaces = true;
- for (char c : chars) {
- if (Character.isWhitespace(c))
- if (startingWhitespaces) {
- continue;
- } else {
- sb.append(c);
- } else {
- startingWhitespaces = false;
- sb.append(c);
- }
- }
- return sb.toString();
- }
-
- // if the first line ends with spaces after the /** then we want to insert a line separator
- int firstLine = lines[0].trim().length() > 0 ? 0 : 1;
-
- // If the last line is now empty, skip it
- int lastLine = lines[lines.length - 1].trim().length() > 0 ? lines.length - 1 : lines.length - 2;
-
- StringBuilder sb = new StringBuilder();
- if (lines[0].length() != 0 && firstLine == 1) {
- // insert a line separator only if the remaining chars on the line are whitespaces
- sb.append('\n');
- }
- boolean preserveLineSeparator = lines[0].length() == 0;
- for (int line = firstLine; line <= lastLine; ++line) {
- char[] chars = lines[line].toCharArray();
- int starsIndex = getStars(chars);
- int leadingWhitespaces = 0;
- boolean recordLeadingWhitespaces = true;
- for (int i = 0, max = chars.length; i < max; i++) {
- char c = chars[i];
- switch(c) {
- case ' ' :
- if (starsIndex == -1) {
- if (recordLeadingWhitespaces) {
- leadingWhitespaces++;
- } else {
- sb.append(c);
- }
- } else if (i >= starsIndex) {
- sb.append(c);
- }
- break;
- default :
- // convert leadingwhitespaces to spaces
- recordLeadingWhitespaces = false;
- if (leadingWhitespaces != 0) {
- int numberOfTabs = leadingWhitespaces / 8;
- if (numberOfTabs != 0) {
- for (int j = 0, max2 = numberOfTabs; j < max2; j++) {
- sb.append(" "); //$NON-NLS-1$
- }
- if ((leadingWhitespaces % 8) >= 1) {
- sb.append(' ');
- }
- } else if (line != 0) {
- // we don't want to preserve the leading spaces for the first line
- for (int j = 0, max2 = leadingWhitespaces; j < max2; j++) {
- sb.append(' ');
- }
- }
- leadingWhitespaces = 0;
- sb.append(c);
- } else if (c == '\t') {
- if (i >= starsIndex) {
- sb.append(c);
- }
- } else if (c != '*' || i > starsIndex) {
- sb.append(c);
- }
- }
- }
-
- // append a newline at the end of each line except the last, even if we skipped the last entirely
- int end = lines.length - 1;
- if (line < end) {
- sb.append('\n');
- } else if (preserveLineSeparator && line == end) {
- sb.append('\n');
- }
- }
- return sb.toString();
- }
-
- /**
- * Returns the index of the last leading stars on this line, -1 if none.
- *
- * @param line the given line
- * @return the computed index
- */
- private static int getStars(char[] line) {
- loop: for (int i = 0, max = line.length; i < max; i++) {
- char c = line[i];
- if (!Character.isWhitespace(c)) {
- if (c == '*') {
- // only whitespaces before the first star
- // consume all stars and return the last index
- for (int j = i + 1; j < max; j++) {
- if (line[j] != '*') {
- return j;
- }
- }
- return max - 1;
- }
- // no need to continue
- break loop;
- }
- }
- return -1;
- }
- /**
- * @return all the annotation instance's explicitly set values, plus default values
- * for all the annotation members that are not explicitly set but that have
- * defaults. By comparison, {@link AnnotationMirror#getElementValues()} only
- * returns the explicitly set values.
- * @see javax.lang.model.util.Elements#getElementValuesWithDefaults(javax.lang.model.element.AnnotationMirror)
- */
- @Override
- public Map extends ExecutableElement, ? extends AnnotationValue> getElementValuesWithDefaults(
- AnnotationMirror a) {
- return ((AnnotationMirrorImpl)a).getElementValuesWithDefaults();
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.util.Elements#getName(java.lang.CharSequence)
- */
- @Override
- public Name getName(CharSequence cs) {
- return new NameImpl(cs);
- }
-
- @Override
- public PackageElement getPackageElement(CharSequence name) {
- LookupEnvironment le = this._env.getLookupEnvironment(); // FIXME(SHMOD): does this lookup need to be module-aware?
- if (name.length() == 0) {
- return (PackageElement) this._env.getFactory().newElement(le.defaultPackage);
- }
- char[] packageName = name.toString().toCharArray();
- PackageBinding packageBinding = le.createPackage(CharOperation.splitOn('.', packageName));
- if (packageBinding == null) {
- return null;
- }
- return (PackageElement) this._env.getFactory().newElement(packageBinding);
- }
-
- @Override
- public PackageElement getPackageOf(Element type) {
- switch(type.getKind()) {
- case ANNOTATION_TYPE :
- case CLASS :
- case ENUM :
- case INTERFACE :
- case RECORD :
- TypeElementImpl typeElementImpl = (TypeElementImpl) type;
- ReferenceBinding referenceBinding = (ReferenceBinding)typeElementImpl._binding;
- return (PackageElement) this._env.getFactory().newElement(referenceBinding.fPackage);
- case PACKAGE :
- return (PackageElement) type;
- case CONSTRUCTOR :
- case METHOD :
- ExecutableElementImpl executableElementImpl = (ExecutableElementImpl) type;
- MethodBinding methodBinding = (MethodBinding) executableElementImpl._binding;
- return (PackageElement) this._env.getFactory().newElement(methodBinding.declaringClass.fPackage);
- case ENUM_CONSTANT :
- case FIELD :
- case RECORD_COMPONENT :
- VariableElementImpl variableElementImpl = (VariableElementImpl) type;
- FieldBinding fieldBinding = (FieldBinding) variableElementImpl._binding;
- return (PackageElement) this._env.getFactory().newElement(fieldBinding.declaringClass.fPackage);
- case PARAMETER :
- variableElementImpl = (VariableElementImpl) type;
- LocalVariableBinding localVariableBinding = (LocalVariableBinding) variableElementImpl._binding;
- return (PackageElement) this._env.getFactory().newElement(localVariableBinding.declaringScope.classScope().referenceContext.binding.fPackage);
- case EXCEPTION_PARAMETER :
- case INSTANCE_INIT :
- case OTHER :
- case STATIC_INIT :
- case TYPE_PARAMETER :
- case LOCAL_VARIABLE :
- return null;
- default:
- break;
- }
- // unreachable
- return null;
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.util.Elements#getTypeElement(java.lang.CharSequence)
- */
- @Override
- public TypeElement getTypeElement(CharSequence name) {
- LookupEnvironment le = this._env.getLookupEnvironment();
- final char[][] compoundName = CharOperation.splitOn('.', name.toString().toCharArray());
- ReferenceBinding binding = le.getType(compoundName);
- // If we didn't find the binding, maybe it's a nested type;
- // try finding the top-level type and then working downwards.
- if (null == binding) {
- ReferenceBinding topLevelBinding = null;
- int topLevelSegments = compoundName.length;
- while (--topLevelSegments > 0) {
- char[][] topLevelName = new char[topLevelSegments][];
- for (int i = 0; i < topLevelSegments; ++i) {
- topLevelName[i] = compoundName[i];
- }
- topLevelBinding = le.getType(topLevelName);
- if (null != topLevelBinding) {
- break;
- }
- }
- if (null == topLevelBinding) {
- return null;
- }
- binding = topLevelBinding;
- for (int i = topLevelSegments; null != binding && i < compoundName.length; ++i) {
- binding = binding.getMemberType(compoundName[i]);
- }
- }
- if (null == binding) {
- return null;
- }
- if((binding.tagBits & TagBits.HasMissingType) != 0) {
- return null;
- }
- return new TypeElementImpl(this._env, binding, null);
- }
-
- /* (non-Javadoc)
- * Element A hides element B if: A and B are both fields, both nested types, or both methods; and
- * the enclosing element of B is a superclass or superinterface of the enclosing element of A.
- * See JLS 8.3 (for hiding of fields), 8.4.8.2 (hiding of class methods), and 8.5 (for hiding of member types).
- * @see javax.lang.model.util.Elements#hides(javax.lang.model.element.Element, javax.lang.model.element.Element)
- */
- @Override
- public boolean hides(Element hider, Element hidden) {
- if (hidden == null) {
- // required by API spec
- throw new NullPointerException();
- }
- return ((ElementImpl)hider).hides(hidden);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.util.Elements#isDeprecated(javax.lang.model.element.Element)
- */
- @Override
- public boolean isDeprecated(Element e) {
- if (!(e instanceof ElementImpl)) {
- return false;
- }
- return (((ElementImpl)e)._binding.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0;
- }
-
- /* (non-Javadoc)
- * See JLS 8.4.8.1 for discussion of hiding of methods
- * @see javax.lang.model.util.Elements#overrides(javax.lang.model.element.ExecutableElement, javax.lang.model.element.ExecutableElement, javax.lang.model.element.TypeElement)
- */
- @Override
- public boolean overrides(ExecutableElement overrider, ExecutableElement overridden,
- TypeElement type) {
- if (overridden == null || type == null) {
- throw new NullPointerException();
- }
- return ((ExecutableElementImpl)overrider).overrides(overridden, type);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.util.Elements#printElements(java.io.Writer, javax.lang.model.element.Element[])
- */
- @Override
- public void printElements(Writer w, Element... elements) {
- String lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$
- for (Element element : elements) {
- try {
- w.write(element.toString());
- w.write(lineSeparator);
- } catch (IOException e) {
- // ignore
- }
- }
- try {
- w.flush();
- } catch (IOException e) {
- // ignore
- }
- }
-
- @Override
- public boolean isFunctionalInterface(TypeElement type) {
- if (type != null && type.getKind() == ElementKind.INTERFACE) {
- ReferenceBinding binding = (ReferenceBinding)((TypeElementImpl) type)._binding;
- if (binding instanceof SourceTypeBinding) {
- return binding.isFunctionalInterface(((SourceTypeBinding) binding).scope);
- }
- }
- return false;
- }
- @Override
- public boolean isAutomaticModule(ModuleElement module) {
- ModuleBinding binding = ((ModuleElementImpl) module).binding;
- return binding != null ? binding.isAutomatic() : false;
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl9.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl9.java
deleted file mode 100644
index ed97430..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl9.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2023 BEA Systems, Inc. and others
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Igor Fedorenko - extracted from ElementsImpl
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.io.File;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.lang.model.AnnotatedConstruct;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.ModuleElement;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.tools.JavaFileObject.Kind;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.CompilationResult;
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
-import org.eclipse.jdt.internal.compiler.lookup.BinaryModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TagBits;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
-import org.eclipse.jdt.internal.compiler.tool.EclipseFileManager;
-import org.eclipse.jdt.internal.compiler.tool.PathFileObject;
-import org.eclipse.jdt.internal.compiler.util.HashtableOfModule;
-
-/**
- * Utilities for working with java9 language elements.
- * There is one of these for every ProcessingEnvironment.
- */
-public class ElementsImpl9 extends ElementsImpl {
-
- public ElementsImpl9(BaseProcessingEnvImpl env) {
- super(env);
- }
-
- @Override
- public TypeElement getTypeElement(CharSequence name) {
- final char[][] compoundName = CharOperation.splitOn('.', name.toString().toCharArray());
- Set extends ModuleElement> allModuleElements = getAllModuleElements();
- for (ModuleElement moduleElement : allModuleElements) {
- TypeElement t = getTypeElement(compoundName, ((ModuleElementImpl) moduleElement).binding);
- if (t != null) {
- return t;
- }
- }
- return null;
- }
-
- @Override
- public TypeElement getTypeElement(ModuleElement module, CharSequence name) {
- ModuleBinding mBinding = ((ModuleElementImpl) module).binding;
- final char[][] compoundName = CharOperation.splitOn('.', name.toString().toCharArray());
- return getTypeElement(compoundName, mBinding);
- }
-
- private TypeElement getTypeElement(final char[][] compoundName, ModuleBinding mBinding) {
- LookupEnvironment le = mBinding == null ? this._env.getLookupEnvironment() : mBinding.environment;
- ReferenceBinding binding = mBinding == null ? le.getType(compoundName) : le.getType(compoundName, mBinding);
- // If we didn't find the binding, maybe it's a nested type;
- // try finding the top-level type and then working downwards.
- if (null == binding) {
- ReferenceBinding topLevelBinding = null;
- int topLevelSegments = compoundName.length;
- while (--topLevelSegments > 0) {
- char[][] topLevelName = new char[topLevelSegments][];
- for (int i = 0; i < topLevelSegments; ++i) {
- topLevelName[i] = compoundName[i];
- }
- topLevelBinding = le.getType(topLevelName);
- if (null != topLevelBinding) {
- break;
- }
- }
- if (null == topLevelBinding) {
- return null;
- }
- binding = topLevelBinding;
- for (int i = topLevelSegments; null != binding && i < compoundName.length; ++i) {
- binding = binding.getMemberType(compoundName[i]);
- }
- }
- if (null == binding) {
- return null;
- }
- if ((binding.tagBits & TagBits.HasMissingType) != 0) {
- return null;
- }
- return new TypeElementImpl(this._env, binding, null);
- }
-
-
- @Override
- public Origin getOrigin(Element e) {
- return Origin.EXPLICIT;
- }
-
- @Override
- public Origin getOrigin(AnnotatedConstruct c, AnnotationMirror a) {
- return Origin.EXPLICIT;
- }
-
- @Override
- public Origin getOrigin(ModuleElement m, ModuleElement.Directive directive) {
- return Origin.EXPLICIT;
- }
-
- @Override
- public boolean isBridge(ExecutableElement e) {
- MethodBinding methodBinding = (MethodBinding) ((ExecutableElementImpl) e)._binding;
- return methodBinding.isBridge();
- }
-
- @Override
- public ModuleElement getModuleOf(Element elem) {
- if (elem instanceof ModuleElement) {
- return (ModuleElement) elem;
- }
- Element parent = elem.getEnclosingElement();
- while (parent != null) {
- if (parent instanceof ModuleElement) {
- return (ModuleElement) parent;
- }
- parent = parent.getEnclosingElement();
- }
- return null;
- }
-
- @Override
- public ModuleElement getModuleElement(CharSequence name) {
- LookupEnvironment lookup = this._env.getLookupEnvironment();
- ModuleBinding binding = lookup.getModule(name.length() == 0 ? ModuleBinding.UNNAMED : name.toString().toCharArray());
- //TODO: Surely there has to be a better way than calling toString().toCharArray()?
- if (binding == null) {
- return null;
- }
- return new ModuleElementImpl(this._env, binding);
- }
-
- @Override
- public Set extends ModuleElement> getAllModuleElements() {
- LookupEnvironment lookup = this._env.getLookupEnvironment();
- HashtableOfModule knownModules = lookup.knownModules;
- ModuleBinding[] modules = knownModules.valueTable;
- if (modules == null || modules.length == 0) {
- return Collections.emptySet();
- }
- Set mods = new HashSet<>(modules.length);
- for (ModuleBinding moduleBinding : modules) {
- if (moduleBinding == null)
- continue;
- ModuleElement element = (ModuleElement) this._env.getFactory().newElement(moduleBinding);
- mods.add(element);
- }
- mods.add((ModuleElement) this._env.getFactory().newElement(lookup.UnNamedModule));
- return mods;
- }
-
- @Override
- public
- PackageElement getPackageElement(ModuleElement module, CharSequence name) {
- ModuleBinding mBinding = ((ModuleElementImpl) module).binding;
- final char[][] compoundName = CharOperation.splitOn('.', name.toString().toCharArray());
- PackageBinding p = null;
- if (mBinding != null) {
- p = mBinding.getVisiblePackage(compoundName);
- } else {
- p = this._env.getLookupEnvironment().createPackage(compoundName);
- }
- if (p == null || !p.isValidBinding())
- return null;
- return (PackageElement) this._env.getFactory().newElement(p);
- }
- @Override
- public boolean isAutomaticModule(ModuleElement module) {
- ModuleBinding mBinding = ((ModuleElementImpl) module).binding;
- return mBinding.isAutomatic();
- }
- @Override
- public javax.tools.JavaFileObject getFileObjectOf(Element element) {
- switch(element.getKind()) {
- case INTERFACE:
- case CLASS:
- case ENUM:
- case RECORD:
- case ANNOTATION_TYPE:
- TypeElementImpl elementImpl = (TypeElementImpl) element;
- ReferenceBinding refBinding = (ReferenceBinding) elementImpl._binding;
- if (!refBinding.isBinaryBinding()) {
- TypeElementImpl outer = (TypeElementImpl) getOutermostTypeElement(element);
- refBinding = (ReferenceBinding) outer._binding;
- }
- return getFileObjectForType(refBinding);
- case MODULE:
- ModuleElementImpl moduleEl = (ModuleElementImpl) element;
- ModuleBinding mBinding = (ModuleBinding) moduleEl._binding;
- if (mBinding instanceof SourceModuleBinding) {
- SourceModuleBinding sourceModule = (SourceModuleBinding) mBinding;
- return getSourceJavaFileObject(sourceModule.scope.referenceContext());
- } else if (mBinding instanceof BinaryModuleBinding) {
- BinaryModuleBinding binaryBinding = (BinaryModuleBinding) mBinding;
- if (binaryBinding.path != null) {
- return new PathFileObject(Path.of(binaryBinding.path), Kind.CLASS, Charset.defaultCharset());
- }
- }
- break;
- case PACKAGE:
- PackageElementImpl packEl = (PackageElementImpl) element;
- PackageBinding pBinding = (PackageBinding) packEl._binding;
- Binding typeOrPackage = pBinding.getTypeOrPackage(TypeConstants.PACKAGE_INFO_NAME, pBinding.enclosingModule, true);
- if (typeOrPackage != null) {
- return getFileObjectForType((TypeBinding) typeOrPackage);
- }
- break;
- case PARAMETER:
- case LOCAL_VARIABLE:
- case FIELD:
- case RECORD_COMPONENT:
- case ENUM_CONSTANT:
- case METHOD:
- case CONSTRUCTOR:
- if (element.getEnclosingElement() != null) {
- return getFileObjectOf(element.getEnclosingElement());
- }
- break;
- default:
- break;
- }
- return null;
- }
- private JavaFileObject getFileObjectForType(TypeBinding binding) {
- if (binding instanceof SourceTypeBinding) {
- SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) binding;
- ReferenceContext referenceContext = sourceTypeBinding.scope.referenceContext();
- return getSourceJavaFileObject(referenceContext);
- } else if(binding instanceof BinaryTypeBinding) {
- BinaryTypeBinding binaryBinding = (BinaryTypeBinding) binding;
- if (binaryBinding.path != null) {
- Path of = Path.of(binaryBinding.path);
- if (Files.exists(of)) {
- return new PathFileObject(of, Kind.CLASS, Charset.defaultCharset());
- }
- }
- }
- return null;
- }
-
- @SuppressWarnings("resource") // fileManager is not created, must not be closed
- private JavaFileObject getSourceJavaFileObject(ReferenceContext referenceContext) {
- JavaFileManager fileManager = this._env.getFileManager();
- if (fileManager instanceof EclipseFileManager) {
- EclipseFileManager eFileManager = (EclipseFileManager) fileManager;
- CompilationResult compilationResult = referenceContext.compilationResult();
- String fileName = new String(compilationResult.fileName);
- File f = new File(fileName);
- if (f.exists()) {
- Iterator extends JavaFileObject> objects = eFileManager.getJavaFileObjects(f).iterator();
- if (objects.hasNext()) {
- return objects.next();
- }
- }
- } else {
- throw new UnsupportedOperationException();
- }
- return null;
- }
- @Override
- public boolean isCanonicalConstructor(ExecutableElement e) {
- MethodBinding methodBinding = (MethodBinding) ((ExecutableElementImpl) e)._binding;
- return methodBinding.isCanonicalConstructor();
- }
- @Override
- public boolean isCompactConstructor(ExecutableElement e) {
- MethodBinding methodBinding = (MethodBinding) ((ExecutableElementImpl) e)._binding;
- return methodBinding.isCompactConstructor();
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ErrorTypeElement.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ErrorTypeElement.java
deleted file mode 100644
index a9667e1..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ErrorTypeElement.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2017 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.NestingKind;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-
-/**
- * Element corresponding to the Error type mirror
- */
-public class ErrorTypeElement extends TypeElementImpl {
-
- ErrorTypeElement(BaseProcessingEnvImpl env, ReferenceBinding binding) {
- super(env, binding, null);
- }
- /* (non-Javadoc)
- * @see javax.lang.model.element.TypeElement#getInterfaces()
- */
- @Override
- public List extends TypeMirror> getInterfaces() {
- return Collections.emptyList();
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.TypeElement#getNestingKind()
- */
- @Override
- public NestingKind getNestingKind() {
- return NestingKind.TOP_LEVEL;
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.TypeElement#getQualifiedName()
- */
- @Override
- public Name getQualifiedName() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- char[] qName;
- if (binding.isMemberType()) {
- qName = CharOperation.concatWith(binding.enclosingType().compoundName, binding.sourceName, '.');
- CharOperation.replace(qName, '$', '.');
- } else {
- qName = CharOperation.concatWith(binding.compoundName, '.');
- }
- return new NameImpl(qName);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.TypeElement#getSuperclass()
- */
- @Override
- public TypeMirror getSuperclass() {
- return this._env.getFactory().getNoType(TypeKind.NONE);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.TypeElement#getTypeParameters()
- */
- @Override
- public List extends TypeParameterElement> getTypeParameters() {
- return Collections.emptyList();
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.Element#asType()
- */
- @Override
- public TypeMirror asType() {
- return this._env.getFactory().getErrorType((ReferenceBinding) this._binding);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.Element#getAnnotation(java.lang.Class)
- */
- @Override
- public A getAnnotation(Class annotationType) {
- return null;
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.Element#getAnnotationMirrors()
- */
- @Override
- public List extends AnnotationMirror> getAnnotationMirrors() {
- return Collections.emptyList();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public A[] getAnnotationsByType(Class annotationType) {
- return (A[]) Array.newInstance(annotationType, 0);
- }
-
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.Element#getEnclosedElements()
- */
- @Override
- public List extends Element> getEnclosedElements() {
- return Collections.emptyList();
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.Element#getEnclosingElement()
- */
- @Override
- public Element getEnclosingElement() {
- return this._env.getFactory().newPackageElement(this._env.getLookupEnvironment().defaultPackage);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.Element#getKind()
- */
- @Override
- public ElementKind getKind() {
- return ElementKind.CLASS;
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.Element#getModifiers()
- */
- @Override
- public Set getModifiers() {
- return Collections.emptySet();
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.Element#getSimpleName()
- */
- @Override
- public Name getSimpleName() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- return new NameImpl(binding.sourceName());
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ErrorTypeImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ErrorTypeImpl.java
deleted file mode 100644
index cb4ab93..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ErrorTypeImpl.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2023 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.type.ErrorType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVisitor;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-
-/**
- * Implementation of the {@link ErrorType} interface.
- */
-public class ErrorTypeImpl extends DeclaredTypeImpl implements ErrorType {
-
- /* package */ ErrorTypeImpl(BaseProcessingEnvImpl env, ReferenceBinding binding) {
- super(env, binding);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.DeclaredType#asElement()
- */
- @Override
- public Element asElement() {
- return this._env.getFactory().newElement(this._binding);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.DeclaredType#getEnclosingType()
- */
- @Override
- public TypeMirror getEnclosingType() {
- return NoTypeImpl.NO_TYPE_NONE;
- }
-
- @Override
- public List extends TypeMirror> getTypeArguments() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- if (binding.isParameterizedType()) {
- ParameterizedTypeBinding ptb = (ParameterizedTypeBinding)this._binding;
- TypeBinding[] arguments = ptb.arguments;
- int length = arguments == null ? 0 : arguments.length;
- if (length == 0) return Collections.emptyList();
- List args = new ArrayList<>(length);
- for (TypeBinding arg : arguments) {
- args.add(this._env.getFactory().newTypeMirror(arg));
- }
- return Collections.unmodifiableList(args);
- }
- if (binding.isGenericType()) {
- TypeVariableBinding[] typeVariables = binding.typeVariables();
- List args = new ArrayList<>(typeVariables.length);
- for (TypeBinding arg : typeVariables) {
- args.add(this._env.getFactory().newTypeMirror(arg));
- }
- return Collections.unmodifiableList(args);
- }
- return Collections.emptyList();
- }
-
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeMirror#accept(javax.lang.model.type.TypeVisitor, java.lang.Object)
- */
- @Override
- public R accept(TypeVisitor v, P p) {
- return v.visitError(this, p);
- }
-
- @Override
- public List extends AnnotationMirror> getAnnotationMirrors() {
- return Factory.EMPTY_ANNOTATION_MIRRORS;
- }
-
- @Override
- public A getAnnotation(Class annotationType) {
- return null;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public A[] getAnnotationsByType(Class annotationType) {
- return (A[]) Array.newInstance(annotationType, 0);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeMirror#getKind()
- */
- @Override
- public TypeKind getKind() {
- return TypeKind.ERROR;
- }
-
- @Override
- public String toString() {
- return new String(this._binding.readableName());
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ExecutableElementImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ExecutableElementImpl.java
deleted file mode 100644
index b1d6c01..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ExecutableElementImpl.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2015 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- * Jesper Steen Moller - Bug 412150 [1.8] [compiler] Enable reflected parameter names during annotation processing
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationHolder;
-import org.eclipse.jdt.internal.compiler.lookup.AptBinaryLocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodVerifier;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-
-public class ExecutableElementImpl extends ElementImpl implements
- ExecutableElement {
-
- private Name _name = null;
-
- /* package */ ExecutableElementImpl(BaseProcessingEnvImpl env, MethodBinding binding) {
- super(env, binding);
- }
-
- @Override
- public R accept(ElementVisitor v, P p)
- {
- return v.visitExecutable(this, p);
- }
-
- @Override
- protected AnnotationBinding[] getAnnotationBindings()
- {
- return ((MethodBinding)this._binding).getAnnotations();
- }
-
- @Override
- public AnnotationValue getDefaultValue() {
- MethodBinding binding = (MethodBinding)this._binding;
- Object defaultValue = binding.getDefaultValue();
- if (defaultValue != null) return new AnnotationMemberValue(this._env, defaultValue, binding);
- return null;
- }
-
- @Override
- public List extends Element> getEnclosedElements() {
- return Collections.emptyList();
- }
-
- @Override
- public Element getEnclosingElement() {
- MethodBinding binding = (MethodBinding)this._binding;
- if (null == binding.declaringClass) {
- return null;
- }
- return this._env.getFactory().newElement(binding.declaringClass);
- }
-
- @Override
- public String getFileName() {
- ReferenceBinding dc = ((MethodBinding)this._binding).declaringClass;
- char[] name = dc.getFileName();
- if (name == null)
- return null;
- return new String(name);
- }
-
- @Override
- public ElementKind getKind() {
- MethodBinding binding = (MethodBinding)this._binding;
- if (binding.isConstructor()) {
- return ElementKind.CONSTRUCTOR;
- }
- else if (CharOperation.equals(binding.selector, TypeConstants.CLINIT)) {
- return ElementKind.STATIC_INIT;
- }
- else if (CharOperation.equals(binding.selector, TypeConstants.INIT)) {
- return ElementKind.INSTANCE_INIT;
- }
- else {
- return ElementKind.METHOD;
- }
- }
-
- @Override
- public Set getModifiers() {
- MethodBinding binding = (MethodBinding)this._binding;
- return Factory.getModifiers(binding.modifiers, getKind());
- }
-
- @Override
- PackageElement getPackage()
- {
- MethodBinding binding = (MethodBinding)this._binding;
- if (null == binding.declaringClass) {
- return null;
- }
- return this._env.getFactory().newPackageElement(binding.declaringClass.fPackage);
- }
-
- @Override
- public List extends VariableElement> getParameters() {
- MethodBinding binding = (MethodBinding)this._binding;
- int length = binding.parameters == null ? 0 : binding.parameters.length;
- if (0 != length) {
- AbstractMethodDeclaration methodDeclaration = binding.sourceMethod();
- List params = new ArrayList<>(length);
- if (methodDeclaration != null) {
- for (Argument argument : methodDeclaration.arguments) {
- VariableElement param = new VariableElementImpl(this._env, argument.binding);
- params.add(param);
- }
- } else {
- // binary method
- AnnotationBinding[][] parameterAnnotationBindings = null;
- AnnotationHolder annotationHolder = binding.declaringClass.retrieveAnnotationHolder(binding, false);
- if (annotationHolder != null) {
- parameterAnnotationBindings = annotationHolder.getParameterAnnotations();
- }
- // we need to filter the synthetic arguments
- int i = 0;
- for (TypeBinding typeBinding : binding.parameters) {
- char name[] = binding.parameterNames.length > i ? binding.parameterNames[i] : null;
- if (name == null) {
- StringBuilder builder = new StringBuilder("arg");//$NON-NLS-1$
- builder.append(i);
- name = String.valueOf(builder).toCharArray();
- }
- VariableElement param = new VariableElementImpl(this._env,
- new AptBinaryLocalVariableBinding(
- name,
- typeBinding,
- 0,
- parameterAnnotationBindings != null ? parameterAnnotationBindings[i] : null,
- binding));
- params.add(param);
- i++;
- }
- }
- return Collections.unmodifiableList(params);
- }
- return Collections.emptyList();
- }
-
- @Override
- public TypeMirror getReturnType() {
- MethodBinding binding = (MethodBinding)this._binding;
- if (binding.returnType == null) {
- return null;
- }
- else return this._env.getFactory().newTypeMirror(binding.returnType);
- }
-
- @Override
- public Name getSimpleName() {
- MethodBinding binding = (MethodBinding)this._binding;
- if (this._name == null) {
- this._name = new NameImpl(binding.selector);
- }
- return this._name;
- }
-
- @Override
- public List extends TypeMirror> getThrownTypes() {
- MethodBinding binding = (MethodBinding)this._binding;
- if (binding.thrownExceptions.length == 0) {
- return Collections.emptyList();
- }
- List list = new ArrayList<>(binding.thrownExceptions.length);
- for (ReferenceBinding exception : binding.thrownExceptions) {
- list.add(this._env.getFactory().newTypeMirror(exception));
- }
- return list;
- }
-
- @Override
- public List extends TypeParameterElement> getTypeParameters() {
- MethodBinding binding = (MethodBinding)this._binding;
- TypeVariableBinding[] variables = binding.typeVariables();
- if (variables.length == 0) {
- return Collections.emptyList();
- }
- List params = new ArrayList<>(variables.length);
- for (TypeVariableBinding variable : variables) {
- params.add(this._env.getFactory().newTypeParameterElement(variable, this));
- }
- return Collections.unmodifiableList(params);
- }
-
- @Override
- public boolean hides(Element hidden)
- {
- if (!(hidden instanceof ExecutableElementImpl)) {
- return false;
- }
- MethodBinding hiderBinding = (MethodBinding)this._binding;
- MethodBinding hiddenBinding = (MethodBinding)((ExecutableElementImpl)hidden)._binding;
- if (hiderBinding == hiddenBinding) {
- return false;
- }
- if (hiddenBinding.isPrivate()) {
- return false;
- }
- // See JLS 8.4.8: hiding only applies to static methods
- if (!hiderBinding.isStatic() || !hiddenBinding.isStatic()) {
- return false;
- }
- // check names
- if (!CharOperation.equals(hiddenBinding.selector, hiderBinding.selector)) {
- return false;
- }
- // check parameters
- if (!this._env.getLookupEnvironment().methodVerifier().isMethodSubsignature(hiderBinding, hiddenBinding)) {
- return false;
- }
- return null != hiderBinding.declaringClass.findSuperTypeOriginatingFrom(hiddenBinding.declaringClass);
- }
-
- @Override
- public boolean isVarArgs() {
- return ((MethodBinding) this._binding).isVarargs();
- }
-
- /**
- * Return true if this method overrides {@code overridden} in the context of {@code type}. For
- * instance, consider
- *
- * interface A { void f(); }
- * class B { void f() {} }
- * class C extends B implements I { }
- *
- * In the context of B, B.f() does not override A.f(); they are unrelated. But in the context of
- * C, B.f() does override A.f(). That is, the copy of B.f() that C inherits overrides A.f().
- * This is equivalent to considering two questions: first, does C inherit B.f(); if so, does
- * the inherited C.f() override A.f(). If B.f() were private, for instance, then in the context
- * of C it would still not override A.f().
- *
- * see jls3 8.4.8 Inheritance, Overriding, and Hiding
- *
see jls3 9.4.1 Inheritance and Overriding
- * @see javax.lang.model.util.Elements#overrides(ExecutableElement, ExecutableElement, TypeElement)
- */
- public boolean overrides(ExecutableElement overridden, TypeElement type)
- {
- MethodBinding overriddenBinding = (MethodBinding)((ExecutableElementImpl) overridden)._binding;
- ReferenceBinding overriderContext = (ReferenceBinding)((TypeElementImpl)type)._binding;
- if ((MethodBinding)this._binding == overriddenBinding
- || overriddenBinding.isStatic()
- || overriddenBinding.isPrivate()
- || ((MethodBinding)this._binding).isStatic()) {
- return false;
- }
- char[] selector = ((MethodBinding)this._binding).selector;
- if (!CharOperation.equals(selector, overriddenBinding.selector))
- return false;
-
- // Construct a binding to the equivalent of this (the overrider) as it would be inherited by 'type'.
- // Can only do this if 'type' is descended from the overrider.
- // Second clause of the AND is required to match a peculiar javac behavior.
- if (null == overriderContext.findSuperTypeOriginatingFrom(((MethodBinding)this._binding).declaringClass) &&
- null == ((MethodBinding)this._binding).declaringClass.findSuperTypeOriginatingFrom(overriderContext)) {
- return false;
- }
- MethodBinding overriderBinding = new MethodBinding((MethodBinding)this._binding, overriderContext);
- if (overriderBinding.isPrivate()) {
- // a private method can never override another method. The other method would either be
- // private itself, in which case it would not be visible; or this would be a restriction
- // of access, which is a compile-time error.
- return false;
- }
-
- TypeBinding match = overriderBinding.declaringClass.findSuperTypeOriginatingFrom(overriddenBinding.declaringClass);
- if (!(match instanceof ReferenceBinding)) return false;
-
- org.eclipse.jdt.internal.compiler.lookup.MethodBinding[] superMethods = ((ReferenceBinding)match).getMethods(selector);
- LookupEnvironment lookupEnvironment = this._env.getLookupEnvironment();
- if (lookupEnvironment == null) return false;
- MethodVerifier methodVerifier = lookupEnvironment.methodVerifier();
- for (int i = 0, length = superMethods.length; i < length; i++) {
- if (superMethods[i].original() == overriddenBinding) {
- return methodVerifier.doesMethodOverride(overriderBinding, superMethods[i]);
- }
- }
- return false;
- }
-
- @Override
- public TypeMirror getReceiverType() {
- return this._env.getFactory().getReceiverType((MethodBinding) this._binding);
- }
-
- @Override
- public boolean isDefault() {
- if (this._binding != null) {
- return ((MethodBinding)this._binding).isDefaultMethod();
- }
- return false;
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ExecutableTypeImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ExecutableTypeImpl.java
deleted file mode 100644
index 4beec43..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ExecutableTypeImpl.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2016 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.lang.model.type.TypeVisitor;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-
-/**
- * Implementation of the ExecutableType
- */
-public class ExecutableTypeImpl extends TypeMirrorImpl implements ExecutableType {
-
- ExecutableTypeImpl(BaseProcessingEnvImpl env, MethodBinding binding) {
- super(env, binding);
- }
- /* (non-Javadoc)
- * @see javax.lang.model.type.ExecutableType#getParameterTypes()
- */
- @Override
- public List extends TypeMirror> getParameterTypes() {
- MethodBinding binding = (MethodBinding) this._binding;
- TypeBinding[] parameters = binding.parameters;
- int length = parameters.length;
- boolean isEnumConstructor = binding.isConstructor()
- && binding.declaringClass.isEnum()
- && binding.declaringClass.isBinaryBinding()
- && ((binding.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0);
- if (isEnumConstructor) {
- ArrayList list = new ArrayList<>();
- for (int i = 0; i < length; i++) {
- list.add(this._env.getFactory().newTypeMirror(parameters[i]));
- }
- return Collections.unmodifiableList(list);
- }
- if (length != 0) {
- ArrayList list = new ArrayList<>();
- for (TypeBinding typeBinding : parameters) {
- list.add(this._env.getFactory().newTypeMirror(typeBinding));
- }
- return Collections.unmodifiableList(list);
- }
- return Collections.emptyList();
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.ExecutableType#getReturnType()
- */
- @Override
- public TypeMirror getReturnType() {
- return this._env.getFactory().newTypeMirror(((MethodBinding) this._binding).returnType);
- }
-
- @Override
- protected AnnotationBinding[] getAnnotationBindings() {
- return ((MethodBinding) this._binding).returnType.getTypeAnnotations();
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.ExecutableType#getThrownTypes()
- */
- @Override
- public List extends TypeMirror> getThrownTypes() {
- ArrayList list = new ArrayList<>();
- ReferenceBinding[] thrownExceptions = ((MethodBinding) this._binding).thrownExceptions;
- if (thrownExceptions.length != 0) {
- for (ReferenceBinding referenceBinding : thrownExceptions) {
- list.add(this._env.getFactory().newTypeMirror(referenceBinding));
- }
- }
- return Collections.unmodifiableList(list);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.ExecutableType#getTypeVariables()
- */
- @Override
- public List extends TypeVariable> getTypeVariables() {
- ArrayList list = new ArrayList<>();
- TypeVariableBinding[] typeVariables = ((MethodBinding) this._binding).typeVariables();
- if (typeVariables.length != 0) {
- for (TypeVariableBinding typeVariableBinding : typeVariables) {
- list.add((TypeVariable) this._env.getFactory().newTypeMirror(typeVariableBinding));
- }
- }
- return Collections.unmodifiableList(list);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeMirror#accept(javax.lang.model.type.TypeVisitor, java.lang.Object)
- */
- @Override
- public R accept(TypeVisitor v, P p) {
- return v.visitExecutable(this, p);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeMirror#getKind()
- */
- @Override
- public TypeKind getKind() {
- return TypeKind.EXECUTABLE;
- }
-
- @Override
- public TypeMirror getReceiverType() {
- return this._env.getFactory().getReceiverType((MethodBinding) this._binding);
- }
- @Override
- public String toString() {
- return new String(((MethodBinding) this._binding).returnType.readableName());
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/Factory.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/Factory.java
deleted file mode 100644
index b42b2d9..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/Factory.java
+++ /dev/null
@@ -1,921 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2023 BEA Systems, Inc. and others
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- * IBM Corporation - fix for 342598
- * IBM Corporation - Java 8 support
- * het@google.com - Bug 427943 - The method org.eclipse.jdt.internal.compiler.apt.model.Factory.getPrimitiveType does not throw IllegalArgumentException
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.type.ErrorType;
-import javax.lang.model.type.NoType;
-import javax.lang.model.type.NullType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
-import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
-import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TagBits;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
-import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
-
-/**
- * Creates javax.lang.model wrappers around JDT internal compiler bindings.
- */
-public class Factory {
-
- // using auto-boxing to take advantage of caching, if any.
- // the dummy value picked here falls within the caching range.
- public static final Byte DUMMY_BYTE = 0;
- public static final Character DUMMY_CHAR = '0';
- public static final Double DUMMY_DOUBLE = 0d;
- public static final Float DUMMY_FLOAT = 0f;
- public static final Integer DUMMY_INTEGER = 0;
- public static final Long DUMMY_LONG = 0l;
- public static final Short DUMMY_SHORT = 0;
-
- private final BaseProcessingEnvImpl _env;
- public static List extends AnnotationMirror> EMPTY_ANNOTATION_MIRRORS = Collections.emptyList();
-
- /**
- * This object should only be constructed by the BaseProcessingEnvImpl.
- */
- public Factory(BaseProcessingEnvImpl env) {
- this._env = env;
- }
-
- /**
- * Convert an array of compiler annotation bindings into a list of AnnotationMirror
- * @return a non-null, possibly empty, unmodifiable list.
- */
- public List extends AnnotationMirror> getAnnotationMirrors(AnnotationBinding[] annotations) {
- if (null == annotations || 0 == annotations.length) {
- return Collections.emptyList();
- }
- List list = new ArrayList<>(annotations.length);
- for (AnnotationBinding annotation : annotations) {
- if (annotation == null) continue;
- list.add(newAnnotationMirror(annotation));
- }
- return Collections.unmodifiableList(list);
- }
-
- @SuppressWarnings("unchecked") // for the cast to A
- public A[] getAnnotationsByType(AnnotationBinding[] annoInstances, Class annotationClass) {
- A[] result = getAnnotations(annoInstances, annotationClass, false);
- return result == null ? (A[]) Array.newInstance(annotationClass, 0) : result;
- }
-
-
- public A getAnnotation(AnnotationBinding[] annoInstances, Class annotationClass) {
- A[] result = getAnnotations(annoInstances, annotationClass, true);
- return result == null ? null : result[0];
- }
-
- @SuppressWarnings("unchecked") // for cast of newProxyInstance() to A
- private A[] getAnnotations(AnnotationBinding[] annoInstances, Class annotationClass, boolean justTheFirst) {
- if(annoInstances == null || annoInstances.length == 0 || annotationClass == null )
- return null;
-
- String annoTypeName = annotationClass.getName();
- if(annoTypeName == null ) return null;
-
- List list = new ArrayList<>(annoInstances.length);
- for(AnnotationBinding annoInstance : annoInstances) {
- if (annoInstance == null)
- continue;
-
- AnnotationMirrorImpl annoMirror = createAnnotationMirror(annoTypeName, annoInstance);
- if (annoMirror != null) {
- list.add((A)Proxy.newProxyInstance(annotationClass.getClassLoader(), new Class[]{ annotationClass }, annoMirror));
- if (justTheFirst) break;
- }
- }
- A [] result = (A[]) Array.newInstance(annotationClass, list.size());
- return list.size() > 0 ? (A[]) list.toArray(result) : null;
- }
-
- private AnnotationMirrorImpl createAnnotationMirror(String annoTypeName, AnnotationBinding annoInstance) {
- ReferenceBinding binding = annoInstance.getAnnotationType();
- if (binding != null && binding.isAnnotationType() ) {
- char[] qName;
- if (binding.isMemberType()) {
- annoTypeName = annoTypeName.replace('$', '.');
- qName = CharOperation.concatWith(binding.enclosingType().compoundName, binding.sourceName, '.');
- CharOperation.replace(qName, '$', '.');
- } else {
- qName = CharOperation.concatWith(binding.compoundName, '.');
- }
- if(annoTypeName.equals(new String(qName)) ){
- return (AnnotationMirrorImpl)this._env.getFactory().newAnnotationMirror(annoInstance);
- }
- }
- return null;
- }
-
- private static void appendModifier(Set result, int modifiers, int modifierConstant, Modifier modifier) {
- if ((modifiers & modifierConstant) != 0) {
- result.add(modifier);
- }
- }
-
- private static void decodeModifiers(Set result, int modifiers, int[] checkBits) {
- if (checkBits == null) return;
- for (int i = 0, max = checkBits.length; i < max; i++) {
- switch(checkBits[i]) {
- case ClassFileConstants.AccPublic :
- appendModifier(result, modifiers, checkBits[i], Modifier.PUBLIC);
- break;
- case ClassFileConstants.AccProtected:
- appendModifier(result, modifiers, checkBits[i], Modifier.PROTECTED);
- break;
- case ClassFileConstants.AccPrivate :
- appendModifier(result, modifiers, checkBits[i], Modifier.PRIVATE);
- break;
- case ClassFileConstants.AccAbstract :
- appendModifier(result, modifiers, checkBits[i], Modifier.ABSTRACT);
- break;
- case ExtraCompilerModifiers.AccDefaultMethod :
- try {
- appendModifier(result, modifiers, checkBits[i], Modifier.valueOf("DEFAULT")); //$NON-NLS-1$
- } catch(IllegalArgumentException iae) {
- // Don't have JDK 1.8, just ignore and proceed.
- }
- break;
- case ClassFileConstants.AccStatic :
- appendModifier(result, modifiers, checkBits[i], Modifier.STATIC);
- break;
- case ClassFileConstants.AccFinal :
- appendModifier(result, modifiers, checkBits[i], Modifier.FINAL);
- break;
- case ClassFileConstants.AccSynchronized :
- appendModifier(result, modifiers, checkBits[i], Modifier.SYNCHRONIZED);
- break;
- case ClassFileConstants.AccNative :
- appendModifier(result, modifiers, checkBits[i], Modifier.NATIVE);
- break;
- case ClassFileConstants.AccStrictfp :
- appendModifier(result, modifiers, checkBits[i], Modifier.STRICTFP);
- break;
- case ClassFileConstants.AccTransient :
- appendModifier(result, modifiers, checkBits[i], Modifier.TRANSIENT);
- break;
- case ClassFileConstants.AccVolatile :
- appendModifier(result, modifiers, checkBits[i], Modifier.VOLATILE);
- break;
- case ExtraCompilerModifiers.AccNonSealed :
- try {
- appendModifier(result, modifiers, checkBits[i], Modifier.valueOf("NON_SEALED")); //$NON-NLS-1$
- } catch(IllegalArgumentException iae) {
- // Don't have JDK 15, just ignore and proceed.
- }
- break;
- case ExtraCompilerModifiers.AccSealed :
- try {
- appendModifier(result, modifiers, checkBits[i], Modifier.valueOf("SEALED")); //$NON-NLS-1$
- } catch(IllegalArgumentException iae) {
- // Don't have JDK 15, just ignore and proceed.
- }
- break;
- }
- }
- }
-
- public static Object getMatchingDummyValue(final Class> expectedType){
- if( expectedType.isPrimitive() ){
- if(expectedType == boolean.class)
- return Boolean.FALSE;
- else if( expectedType == byte.class )
- return DUMMY_BYTE;
- else if( expectedType == char.class )
- return DUMMY_CHAR;
- else if( expectedType == double.class)
- return DUMMY_DOUBLE;
- else if( expectedType == float.class )
- return DUMMY_FLOAT;
- else if( expectedType == int.class )
- return DUMMY_INTEGER;
- else if( expectedType == long.class )
- return DUMMY_LONG;
- else if(expectedType == short.class)
- return DUMMY_SHORT;
- else // expectedType == void.class. can this happen?
- return DUMMY_INTEGER; // anything would work
- }
- else
- return null;
- }
-
- public TypeMirror getReceiverType(MethodBinding binding) {
- if (binding != null) {
- if (binding.receiver != null) {
- return this._env.getFactory().newTypeMirror(binding.receiver);
- }
- if (binding.declaringClass != null) {
- if (!binding.isStatic() && (!binding.isConstructor() || binding.declaringClass.isMemberType())) {
- return this._env.getFactory().newTypeMirror(binding.declaringClass);
- }
- }
- }
- return NoTypeImpl.NO_TYPE_NONE;
- }
-
- public static Set getModifiers(int modifiers, ElementKind kind) {
- return getModifiers(modifiers, kind, false);
- }
- /**
- * Convert from the JDT's ClassFileConstants flags to the Modifier enum.
- */
- public static Set getModifiers(int modifiers, ElementKind kind, boolean isFromBinary)
- {
- EnumSet result = EnumSet.noneOf(Modifier.class);
- switch(kind) {
- case CONSTRUCTOR :
- case METHOD :
- // modifiers for methods
- decodeModifiers(result, modifiers, new int[] {
- ClassFileConstants.AccPublic,
- ClassFileConstants.AccProtected,
- ClassFileConstants.AccPrivate,
- ClassFileConstants.AccAbstract,
- ClassFileConstants.AccStatic,
- ClassFileConstants.AccFinal,
- ClassFileConstants.AccSynchronized,
- ClassFileConstants.AccNative,
- ClassFileConstants.AccStrictfp,
- ExtraCompilerModifiers.AccDefaultMethod
- });
- break;
- case FIELD :
- case ENUM_CONSTANT :
- // for fields
- decodeModifiers(result, modifiers, new int[] {
- ClassFileConstants.AccPublic,
- ClassFileConstants.AccProtected,
- ClassFileConstants.AccPrivate,
- ClassFileConstants.AccStatic,
- ClassFileConstants.AccFinal,
- ClassFileConstants.AccTransient,
- ClassFileConstants.AccVolatile
- });
- break;
- case ENUM :
- if (isFromBinary) {
- decodeModifiers(result, modifiers, new int[] {
- ClassFileConstants.AccPublic,
- ClassFileConstants.AccProtected,
- ClassFileConstants.AccFinal,
- ClassFileConstants.AccPrivate,
- ClassFileConstants.AccAbstract,
- ClassFileConstants.AccStatic,
- ClassFileConstants.AccStrictfp,
- ExtraCompilerModifiers.AccSealed,
- });
- } else {
- // enum from source cannot be explicitly abstract
- decodeModifiers(result, modifiers, new int[] {
- ClassFileConstants.AccPublic,
- ClassFileConstants.AccProtected,
- ClassFileConstants.AccFinal,
- ClassFileConstants.AccPrivate,
- ClassFileConstants.AccStatic,
- ClassFileConstants.AccStrictfp,
- ExtraCompilerModifiers.AccSealed,
- });
- }
- break;
- case ANNOTATION_TYPE :
- case INTERFACE :
- case CLASS :
- case RECORD :
- // for type
- decodeModifiers(result, modifiers, new int[] {
- ClassFileConstants.AccPublic,
- ClassFileConstants.AccProtected,
- ClassFileConstants.AccAbstract,
- ClassFileConstants.AccFinal,
- ClassFileConstants.AccPrivate,
- ClassFileConstants.AccStatic,
- ClassFileConstants.AccStrictfp,
- ExtraCompilerModifiers.AccSealed,
- ExtraCompilerModifiers.AccNonSealed
- });
- break;
- case MODULE :
- decodeModifiers(result, modifiers, new int[] {
- ClassFileConstants.ACC_OPEN,
- ClassFileConstants.ACC_TRANSITIVE
- });
- break;
- default:
- break;
- }
- return Collections.unmodifiableSet(result);
- }
-
- public AnnotationMirror newAnnotationMirror(AnnotationBinding binding)
- {
- return new AnnotationMirrorImpl(this._env, binding);
- }
-
- /**
- * Create a new element that knows what kind it is even if the binding is unresolved.
- */
- public Element newElement(Binding binding, ElementKind kindHint) {
- if (binding == null)
- return null;
- switch (binding.kind()) {
- case Binding.FIELD:
- case Binding.LOCAL:
- case Binding.RECORD_COMPONENT:
- case Binding.VARIABLE:
- return new VariableElementImpl(this._env, (VariableBinding) binding);
- case Binding.TYPE:
- case Binding.GENERIC_TYPE:
- ReferenceBinding referenceBinding = (ReferenceBinding)binding;
- if ((referenceBinding.tagBits & TagBits.HasMissingType) != 0) {
- return new ErrorTypeElement(this._env, referenceBinding);
- }
- if (CharOperation.equals(referenceBinding.sourceName, TypeConstants.PACKAGE_INFO_NAME)) {
- return newPackageElement(referenceBinding.fPackage);
- }
- return new TypeElementImpl(this._env, referenceBinding, kindHint);
- case Binding.METHOD:
- return new ExecutableElementImpl(this._env, (MethodBinding)binding);
- case Binding.RAW_TYPE:
- case Binding.PARAMETERIZED_TYPE:
- return new TypeElementImpl(this._env, ((ParameterizedTypeBinding)binding).genericType(), kindHint);
- case Binding.PACKAGE:
- return newPackageElement((PackageBinding)binding);
- case Binding.TYPE_PARAMETER:
- return new TypeParameterElementImpl(this._env, (TypeVariableBinding)binding);
- // TODO: fill in the rest of these
- case Binding.MODULE:
- return new ModuleElementImpl(this._env, (ModuleBinding) binding);
- case Binding.IMPORT:
- case Binding.ARRAY_TYPE:
- case Binding.BASE_TYPE:
- case Binding.WILDCARD_TYPE:
- case Binding.INTERSECTION_TYPE:
- throw new UnsupportedOperationException("NYI: binding type " + binding.kind()); //$NON-NLS-1$
- }
- return null;
- }
-
- public Element newElement(Binding binding) {
- return newElement(binding, null);
- }
-
- /**
- * Convenience method - equivalent to {@code (PackageElement)Factory.newElement(binding)}
- */
- public PackageElement newPackageElement(PackageBinding binding)
- {
- if (binding != null && binding.enclosingModule != null) {
- binding = binding.getIncarnation(binding.enclosingModule);
- }
- if (binding == null) {
- return null;
- }
- return new PackageElementImpl(this._env, binding);
- }
-
- public NullType getNullType() {
- return NoTypeImpl.NULL_TYPE;
- }
-
- public NoType getNoType(TypeKind kind)
- {
- switch (kind) {
- case NONE:
- return NoTypeImpl.NO_TYPE_NONE;
- case VOID:
- return NoTypeImpl.NO_TYPE_VOID;
- case PACKAGE:
- return NoTypeImpl.NO_TYPE_PACKAGE;
- case MODULE:
- return new NoTypeImpl(kind);
- default:
- throw new IllegalArgumentException();
- }
- }
-
- /**
- * Get a type mirror object representing the specified primitive type kind.
- * @throws IllegalArgumentException if a non-primitive TypeKind is requested
- */
- public PrimitiveTypeImpl getPrimitiveType(TypeKind kind)
- {
- switch (kind) {
- case BOOLEAN:
- return PrimitiveTypeImpl.BOOLEAN;
- case BYTE:
- return PrimitiveTypeImpl.BYTE;
- case CHAR:
- return PrimitiveTypeImpl.CHAR;
- case DOUBLE:
- return PrimitiveTypeImpl.DOUBLE;
- case FLOAT:
- return PrimitiveTypeImpl.FLOAT;
- case INT:
- return PrimitiveTypeImpl.INT;
- case LONG:
- return PrimitiveTypeImpl.LONG;
- case SHORT:
- return PrimitiveTypeImpl.SHORT;
- default:
- throw new IllegalArgumentException();
- }
- }
-
- public PrimitiveTypeImpl getPrimitiveType(BaseTypeBinding binding) {
- AnnotationBinding[] annotations = binding.getTypeAnnotations();
- if (annotations == null || annotations.length == 0) {
- return getPrimitiveType(PrimitiveTypeImpl.getKind(binding));
- }
- return new PrimitiveTypeImpl(this._env, binding);
- }
-
- /**
- * Given a binding of uncertain type, try to create the right sort of TypeMirror for it.
- */
- public TypeMirror newTypeMirror(Binding binding) {
- switch (binding.kind()) {
- case Binding.FIELD:
- case Binding.LOCAL:
- case Binding.RECORD_COMPONENT:
- case Binding.VARIABLE:
- // For variables, return the type of the variable
- return newTypeMirror(((VariableBinding)binding).type);
-
- case Binding.PACKAGE:
- return getNoType(TypeKind.PACKAGE);
-
- case Binding.IMPORT:
- throw new UnsupportedOperationException("NYI: import type " + binding.kind()); //$NON-NLS-1$
-
- case Binding.METHOD:
- return new ExecutableTypeImpl(this._env, (MethodBinding) binding);
-
- case Binding.TYPE:
- case Binding.RAW_TYPE:
- case Binding.GENERIC_TYPE:
- case Binding.PARAMETERIZED_TYPE:
- ReferenceBinding referenceBinding = (ReferenceBinding) binding;
- if ((referenceBinding.tagBits & TagBits.HasMissingType) != 0) {
- return getErrorType(referenceBinding);
- }
- return new DeclaredTypeImpl(this._env, (ReferenceBinding)binding);
-
- case Binding.ARRAY_TYPE:
- return new ArrayTypeImpl(this._env, (ArrayBinding)binding);
-
- case Binding.BASE_TYPE:
- BaseTypeBinding btb = (BaseTypeBinding)binding;
- switch (btb.id) {
- case TypeIds.T_void:
- return getNoType(TypeKind.VOID);
- case TypeIds.T_null:
- return getNullType();
- default:
- return getPrimitiveType(btb);
- }
-
- case Binding.WILDCARD_TYPE:
- case Binding.INTERSECTION_TYPE: // TODO compatible, but shouldn't it really be an intersection type?
- return new WildcardTypeImpl(this._env, (WildcardBinding) binding);
-
- case Binding.TYPE_PARAMETER:
- return new TypeVariableImpl(this._env, (TypeVariableBinding) binding);
- case Binding.MODULE:
- return getNoType(TypeKind.MODULE);
- }
- return null;
- }
-
- /**
- * @param declaringElement the class, method, etc. that is parameterized by this parameter.
- */
- public TypeParameterElement newTypeParameterElement(TypeVariableBinding variable, Element declaringElement)
- {
- return new TypeParameterElementImpl(this._env, variable, declaringElement);
- }
-
- public ErrorType getErrorType(ReferenceBinding binding) {
- return new ErrorTypeImpl(this._env, binding);
- }
-
- /**
- * This method is derived from code in org.eclipse.jdt.apt.core.
- *
- * This method is designed to be invoked by the invocation handler and anywhere that requires
- * a AnnotationValue (AnnotationMirror member values and default values from annotation member).
- *
- * Regardless of the path, there are common primitive type conversion that needs to take place.
- * The type conversions respect the type widening and narrowing rules from JLS 5.1.2 and 5.1.2.
- *
- * The only question remains is what is the type of the return value when the type conversion fails?
- * When avoidReflectException is set to true
- * Return false if the expected type is boolean
- * Return numeric 0 for all numeric primitive types and '0' for char
- *
- * Otherwise:
- * Return the value unchanged.
- *
- * In the invocation handler case:
- * The value returned by {@link java.lang.reflect.InvocationHandler#invoke}
- * will be converted into the expected type by the {@link java.lang.reflect.Proxy}.
- * If the value and the expected type does not agree, and the value is not null,
- * a ClassCastException will be thrown. A NullPointerException will result if the
- * expected type is a primitive type and the value is null.
- * This behavior causes annotation processors a lot of pain and the decision is
- * to not throw such unchecked exception. In the case where a ClassCastException or
- * NullPointerException will be thrown return some dummy value. Otherwise, return
- * the original value.
- * Chosen dummy values:
- * Return false if the expected type is boolean
- * Return numeric 0 for all numeric primitive types and '0' for char
- *
- * This behavior is triggered by setting avoidReflectException to true
- *
- * Note: the new behavior deviates from what's documented in
- * {@link java.lang.reflect.InvocationHandler#invoke} and also deviates from
- * Sun's implementation.
- *
- * @param value the current value from the annotation instance.
- * @param expectedType the expected type of the value.
- */
- public static Object performNecessaryPrimitiveTypeConversion(
- final Class> expectedType,
- final Object value,
- final boolean avoidReflectException)
- {
- assert expectedType.isPrimitive() : "expectedType is not a primitive type: " + expectedType.getName(); //$NON-NLS-1$
- if( value == null)
- return avoidReflectException ? getMatchingDummyValue(expectedType) : null;
- // apply widening conversion based on JLS 5.1.2 and 5.1.3
- final String typeName = expectedType.getName();
- final char expectedTypeChar = typeName.charAt(0);
- final int nameLen = typeName.length();
- // widening byte -> short, int, long, float or double
- // narrowing byte -> char
- if( value instanceof Byte )
- {
- final byte b = ((Byte)value).byteValue();
- switch( expectedTypeChar )
- {
- case 'b':
- if(nameLen == 4) // byte
- return value; // exact match.
- else
- return avoidReflectException ? Boolean.FALSE : value;
- case 'c':
- return Character.valueOf((char) b); // narrowing.
- case 'd':
- return Double.valueOf(b); // widening.
- case 'f':
- return Float.valueOf(b); // widening.
- case 'i':
- return Integer.valueOf(b); // widening.
- case 'l':
- return Long.valueOf(b); // widening.
- case 's':
- return Short.valueOf(b); // widening.
- default:
- throw new IllegalStateException("unknown type " + expectedTypeChar); //$NON-NLS-1$
- }
- }
- // widening short -> int, long, float, or double
- // narrowing short -> byte or char
- else if( value instanceof Short )
- {
- final short s = ((Short)value).shortValue();
- switch( expectedTypeChar )
- {
- case 'b':
- if(nameLen == 4) // byte
- return Byte.valueOf((byte) s); // narrowing.
- else
- return avoidReflectException ? Boolean.FALSE : value; // completely wrong.
- case 'c':
- return Character.valueOf((char) s); // narrowing.
- case 'd':
- return Double.valueOf(s); // widening.
- case 'f':
- return Float.valueOf(s); // widening.
- case 'i':
- return Integer.valueOf(s); // widening.
- case 'l':
- return Long.valueOf(s); // widening.
- case 's':
- return value; // exact match
- default:
- throw new IllegalStateException("unknown type " + expectedTypeChar); //$NON-NLS-1$
- }
- }
- // widening char -> int, long, float, or double
- // narrowing char -> byte or short
- else if( value instanceof Character )
- {
- final char c = ((Character)value).charValue();
- switch( expectedTypeChar )
- {
- case 'b':
- if(nameLen == 4) // byte
- return Byte.valueOf((byte) c); // narrowing.
- else
- return avoidReflectException ? Boolean.FALSE : value; // completely wrong.
- case 'c':
- return value; // exact match
- case 'd':
- return Double.valueOf(c); // widening.
- case 'f':
- return Float.valueOf(c); // widening.
- case 'i':
- return Integer.valueOf(c); // widening.
- case 'l':
- return Long.valueOf(c); // widening.
- case 's':
- return Short.valueOf((short) c); // narrowing.
- default:
- throw new IllegalStateException("unknown type " + expectedTypeChar); //$NON-NLS-1$
- }
- }
-
- // widening int -> long, float, or double
- // narrowing int -> byte, short, or char
- else if( value instanceof Integer )
- {
- final int i = ((Integer)value).intValue();
- switch( expectedTypeChar )
- {
- case 'b':
- if(nameLen == 4) // byte
- return Byte.valueOf((byte) i); // narrowing.
- else
- return avoidReflectException ? Boolean.FALSE : value; // completely wrong.
- case 'c':
- return Character.valueOf((char) i); // narrowing
- case 'd':
- return Double.valueOf(i); // widening.
- case 'f':
- return Float.valueOf(i); // widening.
- case 'i':
- return value; // exact match
- case 'l':
- return Long.valueOf(i); // widening.
- case 's':
- return Short.valueOf((short) i); // narrowing.
- default:
- throw new IllegalStateException("unknown type " + expectedTypeChar); //$NON-NLS-1$
- }
- }
- // widening long -> float or double
- else if( value instanceof Long )
- {
- final long l = ((Long)value).longValue();
- switch( expectedTypeChar )
- {
- case 'b': // both byte and boolean
- case 'c':
- case 'i':
- case 's':
- // completely wrong.
- return avoidReflectException ? getMatchingDummyValue(expectedType) : value;
- case 'd':
- return Double.valueOf(l); // widening.
- case 'f':
- return Float.valueOf(l); // widening.
- case 'l':
- return value; // exact match.
-
- default:
- throw new IllegalStateException("unknown type " + expectedTypeChar); //$NON-NLS-1$
- }
- }
-
- // widening float -> double
- else if( value instanceof Float )
- {
- final float f = ((Float)value).floatValue();
- switch( expectedTypeChar )
- {
- case 'b': // both byte and boolean
- case 'c':
- case 'i':
- case 's':
- case 'l':
- // completely wrong.
- return avoidReflectException ? getMatchingDummyValue(expectedType) : value;
- case 'd':
- return Double.valueOf(f); // widening.
- case 'f':
- return value; // exact match.
- default:
- throw new IllegalStateException("unknown type " + expectedTypeChar); //$NON-NLS-1$
- }
- }
- else if( value instanceof Double ){
- if(expectedTypeChar == 'd' )
- return value; // exact match
- else{
- return avoidReflectException ? getMatchingDummyValue(expectedType) : value; // completely wrong.
- }
- }
- else if( value instanceof Boolean ){
- if( expectedTypeChar == 'b' && nameLen == 7) // "boolean".length() == 7
- return value;
- else
- return avoidReflectException ? getMatchingDummyValue(expectedType) : value; // completely wrong.
- }
- else // can't convert
- return avoidReflectException ? getMatchingDummyValue(expectedType) : value;
- }
-
- /**
- * Set an element of an array to the appropriate dummy value type
- */
- public static void setArrayMatchingDummyValue(Object array, int i, Class> expectedLeafType)
- {
- if (boolean.class.equals(expectedLeafType)) {
- Array.setBoolean(array, i, false);
- }
- else if (byte.class.equals(expectedLeafType)) {
- Array.setByte(array, i, DUMMY_BYTE);
- }
- else if (char.class.equals(expectedLeafType)) {
- Array.setChar(array, i, DUMMY_CHAR);
- }
- else if (double.class.equals(expectedLeafType)) {
- Array.setDouble(array, i, DUMMY_DOUBLE);
- }
- else if (float.class.equals(expectedLeafType)) {
- Array.setFloat(array, i, DUMMY_FLOAT);
- }
- else if (int.class.equals(expectedLeafType)) {
- Array.setInt(array, i, DUMMY_INTEGER);
- }
- else if (long.class.equals(expectedLeafType)) {
- Array.setLong(array, i, DUMMY_LONG);
- }
- else if (short.class.equals(expectedLeafType)) {
- Array.setShort(array, i, DUMMY_SHORT);
- }
- else {
- Array.set(array, i, null);
- }
- }
-
- /* Wrap repeating annotations into their container, return an array of bindings.
- Incoming array is not modified. The resulting array may be null but will not contain null
- entries.
- */
- public static AnnotationBinding [] getPackedAnnotationBindings(AnnotationBinding [] annotations) {
-
- int length = annotations == null ? 0 : annotations.length;
- if (length == 0)
- return annotations;
-
- AnnotationBinding[] repackagedBindings = annotations; // only replicate if repackaging.
- for (int i = 0; i < length; i++) {
- AnnotationBinding annotation = repackagedBindings[i];
- if (annotation == null) continue;
- ReferenceBinding annotationType = annotation.getAnnotationType();
- if (!annotationType.isRepeatableAnnotationType())
- continue;
- ReferenceBinding containerType = annotationType.containerAnnotationType();
- if (containerType == null)
- continue; // FUBAR.
- MethodBinding [] values = containerType.getMethods(TypeConstants.VALUE);
- if (values == null || values.length != 1)
- continue; // FUBAR.
- MethodBinding value = values[0];
- if (value.returnType == null || value.returnType.dimensions() != 1 || TypeBinding.notEquals(value.returnType.leafComponentType(), annotationType))
- continue; // FUBAR
-
- // We have a kosher repeatable annotation with a kosher containing type. See if actually repeats.
- List containees = null;
- for (int j = i + 1; j < length; j++) {
- AnnotationBinding otherAnnotation = repackagedBindings[j];
- if (otherAnnotation == null) continue;
- if (otherAnnotation.getAnnotationType() == annotationType) { //$IDENTITY-COMPARISON$
- if (repackagedBindings == annotations)
- System.arraycopy(repackagedBindings, 0, repackagedBindings = new AnnotationBinding[length], 0, length);
- repackagedBindings[j] = null; // so it is not double packed.
- if (containees == null) {
- containees = new ArrayList<>();
- containees.add(annotation);
- }
- containees.add(otherAnnotation);
- }
- }
- if (containees != null) {
- ElementValuePair [] elementValuePairs = new ElementValuePair [] { new ElementValuePair(TypeConstants.VALUE, containees.toArray(), value) };
- repackagedBindings[i] = new AnnotationBinding(containerType, elementValuePairs);
- }
- }
-
- int finalTally = 0;
- for (int i = 0; i < length; i++) {
- if (repackagedBindings[i] != null)
- finalTally++;
- }
-
- if (repackagedBindings == annotations && finalTally == length) {
- return annotations;
- }
-
- annotations = new AnnotationBinding [finalTally];
- for (int i = 0, j = 0; i < length; i++) {
- if (repackagedBindings[i] != null)
- annotations[j++] = repackagedBindings[i];
- }
- return annotations;
- }
-
- /* Unwrap container annotations into the repeated annotations, return an array of bindings that includes the container and the containees.
- */
- public static AnnotationBinding [] getUnpackedAnnotationBindings(AnnotationBinding [] annotations) {
-
- int length = annotations == null ? 0 : annotations.length;
- if (length == 0)
- return annotations;
-
- List unpackedAnnotations = new ArrayList<>();
- for (int i = 0; i < length; i++) {
- AnnotationBinding annotation = annotations[i];
- if (annotation == null) continue;
- unpackedAnnotations.add(annotation);
- ReferenceBinding annotationType = annotation.getAnnotationType();
-
- MethodBinding [] values = annotationType.getMethods(TypeConstants.VALUE);
- if (values == null || values.length != 1)
- continue;
- MethodBinding value = values[0];
-
- if (value.returnType.dimensions() != 1)
- continue;
-
- TypeBinding containeeType = value.returnType.leafComponentType();
- if (containeeType == null || !containeeType.isAnnotationType() || !containeeType.isRepeatableAnnotationType())
- continue;
-
- if (containeeType.containerAnnotationType() != annotationType) //$IDENTITY-COMPARISON$
- continue;
-
- // We have a kosher container: unwrap the contained annotations.
- ElementValuePair [] elementValuePairs = annotation.getElementValuePairs();
- for (ElementValuePair elementValuePair : elementValuePairs) {
- if (CharOperation.equals(elementValuePair.getName(), TypeConstants.VALUE)) {
- Object [] containees = (Object []) elementValuePair.getValue();
- for (Object object : containees) {
- unpackedAnnotations.add((AnnotationBinding) object);
- }
- break;
- }
- }
- }
- return unpackedAnnotations.toArray(new AnnotationBinding [unpackedAnnotations.size()]);
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/IElementInfo.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/IElementInfo.java
deleted file mode 100644
index dc0327a..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/IElementInfo.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2011 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- *
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-/**
- * Additional information available for Elements that are implemented
- * within the Eclipse APT framework.
- * @see javax.lang.model.element.Element
- * @since 3.3
- */
-public interface IElementInfo {
- /**
- * Get the project-relative path to the source file that contains this element.
- * If the element is a PackageElement, the "source file" is package-info.java.
- * If the element is not recognized or does not exist in the project for some
- * reason, returns null.
- * @return the project-relative path, or null.
- */
- public String getFileName();
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java
deleted file mode 100644
index da73d91..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java
+++ /dev/null
@@ -1,369 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2018, 2020 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.ModuleElement;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.PlainPackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-
-public class ModuleElementImpl extends ElementImpl implements ModuleElement {
-
- ModuleBinding binding;
- private List directives;
- private static List EMPTY_DIRECTIVES = Collections.emptyList();
-
- /**
- * In general, clients should call
- * {@link Factory#newElement(org.eclipse.jdt.internal.compiler.lookup.Binding)}
- * to create new instances.
- */
- ModuleElementImpl(BaseProcessingEnvImpl env, ModuleBinding binding) {
- super(env, binding);
- this.binding = binding;
- }
-
- @Override
- public ElementKind getKind() {
- return ElementKind.MODULE;
- }
-
- @Override
- public Set getModifiers() {
- int modifiers = this.binding.modifiers;
- return Factory.getModifiers(modifiers, getKind(), false);
- }
-
- @Override
- public Name getQualifiedName() {
- return new NameImpl(this.binding.moduleName);
- }
-
- @Override
- public Name getSimpleName() {
- char[] simpleName = this.binding.moduleName;
- for(int i = simpleName.length-1;i>=0;i--) {
- if(simpleName[i] == '.') {
- simpleName = Arrays.copyOfRange(simpleName, i+1, simpleName.length);
- break;
- }
- }
- return new NameImpl(simpleName);
- }
-
- @Override
- public List extends Element> getEnclosedElements() {
- ModuleBinding module = this.binding;
- Set unique = new HashSet<>();
- for (PlainPackageBinding p : module.declaredPackages.values()) {
- if (!p.hasCompilationUnit(true))
- continue;
- unique.add(p);
- }
- if (module.isUnnamed()) {
- PlainPackageBinding def = module.environment.defaultPackage;
- // FIXME: Does it have any impact for unnamed modules - default package combo?
- if (def != null && def.hasCompilationUnit(true)) {
- unique.add(def);
- }
- } else {
- for (PlainPackageBinding pBinding : this.binding.getExports()) {
- unique.add(pBinding);
- }
- for (PlainPackageBinding pBinding : this.binding.getOpens()) {
- unique.add(pBinding);
- }
- }
- List enclosed = new ArrayList<>(unique.size());
- for (PlainPackageBinding p : unique) {
- PackageElement pElement = (PackageElement) this._env.getFactory().newElement(p);
- enclosed.add(pElement);
- }
- return Collections.unmodifiableList(enclosed);
- }
-
- @Override
- public boolean isOpen() {
- return (this.binding.modifiers & ClassFileConstants.ACC_OPEN) != 0;
- }
-
- @Override
- public boolean isUnnamed() {
- return this.binding.moduleName.length == 0;
- }
-
- @Override
- public Element getEnclosingElement() {
- // As of today, modules have no enclosing element
- return null;
- }
-
- @Override
- public List extends Directive> getDirectives() {
- if (isUnnamed()) {
- return EMPTY_DIRECTIVES;
- }
- if (this.directives == null)
- this.directives = new ArrayList<>();
-
- PlainPackageBinding[] packs = this.binding.getExports();
- for (PlainPackageBinding exp : packs) {
- this.directives.add(new ExportsDirectiveImpl(exp));
- }
- Set transitive = new HashSet<>();
- for (ModuleBinding mBinding : this.binding.getRequiresTransitive()) {
- transitive.add(mBinding);
- }
- ModuleBinding[] required = this.binding.getRequires();
- for (ModuleBinding mBinding : required) {
- if (transitive.contains(mBinding)) {
- this.directives.add(new RequiresDirectiveImpl(mBinding, true));
- } else {
- this.directives.add(new RequiresDirectiveImpl(mBinding, false));
- }
- }
-
- TypeBinding[] tBindings = this.binding.getUses();
- for (TypeBinding tBinding : tBindings) {
- this.directives.add(new UsesDirectiveImpl(tBinding));
- }
- tBindings = this.binding.getServices();
- for (TypeBinding tBinding : tBindings) {
- this.directives.add(new ProvidesDirectiveImpl(tBinding));
- }
- packs = this.binding.getOpens();
- for (PlainPackageBinding exp : packs) {
- this.directives.add(new OpensDirectiveImpl(exp));
- }
- return this.directives;
- }
-
- @Override
- public R accept(ElementVisitor visitor, P param) {
- return visitor.visitModule(this, param);
- }
- @Override
- protected AnnotationBinding[] getAnnotationBindings() {
- return ((ModuleBinding) this._binding).getAnnotations();
- }
-
- abstract class PackageDirectiveImpl {
- final PackageBinding binding1;
- List targets;
-
- PackageDirectiveImpl(PackageBinding pBinding) {
- this.binding1 = pBinding;
- }
-
- public PackageElement getPackage() {
- return ModuleElementImpl.this._env.getFactory().newPackageElement(this.binding1);
- }
-
- public List extends ModuleElement> getTargetModules(String[] restrictions) {
- if(this.targets != null) {
- return this.targets;
- }
- if (restrictions.length == 0) {
- return (this.targets = null);
- }
- List targets1 = new ArrayList<>(restrictions.length);
- for (String string : restrictions) {
- ModuleBinding target = ModuleElementImpl.this.binding.environment.getModule(string.toCharArray());
- if (target != null) {
- ModuleElement element = ((ModuleElement) ModuleElementImpl.this._env.getFactory().newElement(target));
- targets1.add(element);
- }
- }
- return (this.targets = Collections.unmodifiableList(targets1));
- }
- }
-
- class ExportsDirectiveImpl extends PackageDirectiveImpl implements ModuleElement.ExportsDirective {
-
- ExportsDirectiveImpl(PackageBinding pBinding) {
- super(pBinding);
- }
-
- @Override
- public R accept(DirectiveVisitor visitor, P param) {
- return visitor.visitExports(this, param);
- }
-
- @Override
- public javax.lang.model.element.ModuleElement.DirectiveKind getKind() {
- return DirectiveKind.EXPORTS;
- }
-
- @Override
- public PackageElement getPackage() {
- return ModuleElementImpl.this._env.getFactory().newPackageElement(this.binding1);
- }
- @Override
- public List extends ModuleElement> getTargetModules() {
- if(this.targets != null) {
- return this.targets;
- }
- return getTargetModules(ModuleElementImpl.this.binding.getExportRestrictions(this.binding1));
- }
-
- }
-
- class RequiresDirectiveImpl implements ModuleElement.RequiresDirective {
- ModuleBinding dependency;
- boolean transitive;
-
- RequiresDirectiveImpl(ModuleBinding dependency, boolean transitive) {
- this.dependency = dependency;
- this.transitive = transitive;
- }
-
- @Override
- public R accept(DirectiveVisitor visitor, P param) {
- return visitor.visitRequires(this, param);
- }
-
- @Override
- public javax.lang.model.element.ModuleElement.DirectiveKind getKind() {
- return DirectiveKind.REQUIRES;
- }
-
- @Override
- public ModuleElement getDependency() {
- return (ModuleElement) ModuleElementImpl.this._env.getFactory().newElement(this.dependency, ElementKind.MODULE);
- }
-
- @Override
- public boolean isStatic() {
- // TODO: Yet to see this in ModuleBinding. Check again.
- return false;
- }
-
- @Override
- public boolean isTransitive() {
- return this.transitive;
- }
- }
-
- class OpensDirectiveImpl extends PackageDirectiveImpl implements ModuleElement.OpensDirective {
-
- OpensDirectiveImpl(PackageBinding pBinding) {
- super(pBinding);
- }
-
- @Override
- public R accept(DirectiveVisitor visitor, P param) {
- return visitor.visitOpens(this, param);
- }
-
- @Override
- public javax.lang.model.element.ModuleElement.DirectiveKind getKind() {
- return DirectiveKind.OPENS;
- }
- @Override
- public List extends ModuleElement> getTargetModules() {
- if(this.targets != null) {
- return this.targets;
- }
- return getTargetModules(ModuleElementImpl.this.binding.getOpenRestrictions(this.binding1));
- }
- }
-
- class UsesDirectiveImpl implements ModuleElement.UsesDirective {
- final TypeBinding binding1;
-
- UsesDirectiveImpl(TypeBinding binding) {
- this.binding1 = binding;
- }
-
- @Override
- public R accept(DirectiveVisitor visitor, P param) {
- return visitor.visitUses(this, param);
- }
-
- @Override
- public DirectiveKind getKind() {
- return DirectiveKind.USES;
- }
-
- @Override
- public TypeElement getService() {
- return (TypeElement) ModuleElementImpl.this._env.getFactory().newElement(this.binding1);
- }
-
- }
-
- class ProvidesDirectiveImpl implements ModuleElement.ProvidesDirective {
-
- TypeBinding service;
- public List extends TypeElement> implementations;
-
- ProvidesDirectiveImpl(TypeBinding service) {
- this.service = service;
- }
-
- @Override
- public R accept(DirectiveVisitor visitor, P param) {
- return visitor.visitProvides(this, param);
- }
-
- @Override
- public DirectiveKind getKind() {
- return DirectiveKind.PROVIDES;
- }
-
- @Override
- public List extends TypeElement> getImplementations() {
- if (this.implementations != null)
- return this.implementations;
-
- TypeBinding[] implementations2 = ModuleElementImpl.this.binding.getImplementations(this.service);
- if (implementations2.length == 0) {
- return (this.implementations = Collections.emptyList());
- }
-
- List list = new ArrayList<>(implementations2.length);
- Factory factory = ModuleElementImpl.this._env.getFactory();
- for (TypeBinding type: implementations2) {
- TypeElement element = (TypeElement) factory.newElement(type);
- list.add(element);
- }
- return Collections.unmodifiableList(list);
- }
-
- @Override
- public TypeElement getService() {
- return (TypeElement) ModuleElementImpl.this._env.getFactory().newElement(this.service);
- }
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/NameImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/NameImpl.java
deleted file mode 100644
index 0839a4c..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/NameImpl.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- *
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import javax.lang.model.element.Name;
-
-/**
- * A String-based implementation of the type used to return strings in javax.lang.model.
- */
-public class NameImpl implements Name {
-
- private final String _name;
-
- /** nullary constructor is prohibited */
- @SuppressWarnings("unused")
- private NameImpl()
- {
- this._name = null;
- }
-
- public NameImpl(CharSequence cs)
- {
- this._name = cs.toString();
- }
-
- public NameImpl(char[] chars)
- {
- this._name = String.valueOf(chars);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.element.Name#contentEquals(java.lang.CharSequence)
- */
- @Override
- public boolean contentEquals(CharSequence cs) {
- return this._name.equals(cs.toString());
- }
-
- /* (non-Javadoc)
- * @see java.lang.CharSequence#charAt(int)
- */
- @Override
- public char charAt(int index) {
- return this._name.charAt(index);
- }
-
- /* (non-Javadoc)
- * @see java.lang.CharSequence#length()
- */
- @Override
- public int length() {
- return this._name.length();
- }
-
- /* (non-Javadoc)
- * @see java.lang.CharSequence#subSequence(int, int)
- */
- @Override
- public CharSequence subSequence(int start, int end) {
- return this._name.subSequence(start, end);
- }
-
- @Override
- public String toString() {
- return this._name;
- }
-
- @Override
- public int hashCode() {
- return this._name.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final NameImpl other = (NameImpl) obj;
- return this._name.equals(other._name);
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java
deleted file mode 100644
index 22294ba..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2015 BEA Systems, Inc. and others
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- * IBM Corporation - Java 8 support
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.util.List;
-
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.type.NoType;
-import javax.lang.model.type.NullType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeVisitor;
-
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-
-/**
- * An implementation of NoType, which is used to represent certain pseudo-types.
- * @see NoType
- */
-public class NoTypeImpl extends TypeMirrorImpl implements NoType, NullType
-{
- private final TypeKind _kind;
-
- public static final NoType NO_TYPE_NONE = new NoTypeImpl(TypeKind.NONE);
- public static final NoType NO_TYPE_VOID = new NoTypeImpl(TypeKind.VOID, TypeBinding.VOID);
- public static final NoType NO_TYPE_PACKAGE = new NoTypeImpl(TypeKind.PACKAGE);
- public static final NullType NULL_TYPE = new NoTypeImpl(TypeKind.NULL, TypeBinding.NULL);
- public static final Binding NO_TYPE_BINDING = new Binding() {
- @Override
- public int kind() {
- throw new IllegalStateException();
- }
-
- @Override
- public char[] readableName() {
- throw new IllegalStateException();
- }
- };
-
- public NoTypeImpl(TypeKind kind) {
- super(null, NO_TYPE_BINDING);
- this._kind = kind;
- }
- public NoTypeImpl(TypeKind kind, Binding binding) {
- super(null, binding);
- this._kind = kind;
- }
-
- @Override
- public R accept(TypeVisitor v, P p)
- {
- switch(this.getKind())
- {
- case NULL :
- return v.visitNull(this, p);
- default:
- return v.visitNoType(this, p);
- }
- }
-
- @Override
- public TypeKind getKind()
- {
- return this._kind;
- }
-
- @Override
- public String toString()
- {
- switch (this._kind) {
- default:
- case NONE:
- return "none"; //$NON-NLS-1$
- case NULL:
- return "null"; //$NON-NLS-1$
- case VOID:
- return "void"; //$NON-NLS-1$
- case PACKAGE:
- return "package"; //$NON-NLS-1$
- case MODULE:
- return "module"; //$NON-NLS-1$
- }
- }
-
- @Override
- public List extends AnnotationMirror> getAnnotationMirrors() {
- return Factory.EMPTY_ANNOTATION_MIRRORS;
- }
-
- @Override
- public A getAnnotation(Class annotationType) {
- return null;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public A[] getAnnotationsByType(Class annotationType) {
- return (A[]) Array.newInstance(annotationType, 0);
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/PackageElementImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/PackageElementImpl.java
deleted file mode 100644
index 47f5985..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/PackageElementImpl.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2017 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- *
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.PackageElement;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.batch.FileSystem;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
-import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
-
-/**
- * Implementation of PackageElement, which represents a package
- */
-public class PackageElementImpl extends ElementImpl implements PackageElement {
-
- PackageElementImpl(BaseProcessingEnvImpl env, PackageBinding binding) {
- super(env, binding);
- }
-
- @Override
- public R accept(ElementVisitor v, P p)
- {
- return v.visitPackage(this, p);
- }
-
- @Override
- protected AnnotationBinding[] getAnnotationBindings()
- {
- PackageBinding packageBinding = (PackageBinding) this._binding;
- char[][] compoundName = CharOperation.arrayConcat(packageBinding.compoundName, TypeConstants.PACKAGE_INFO_NAME);
- ReferenceBinding type = packageBinding.environment.getType(compoundName);
- AnnotationBinding[] annotations = null;
- if (type != null && type.isValidBinding()) {
- annotations = type.getAnnotations();
- }
- return annotations;
- }
-
- @Override
- public List extends Element> getEnclosedElements() {
- PackageBinding binding = (PackageBinding)this._binding;
- LookupEnvironment environment = binding.environment;
- char[][][] typeNames = null;
- INameEnvironment nameEnvironment = binding.environment.nameEnvironment;
- if (nameEnvironment instanceof FileSystem) {
- typeNames = ((FileSystem) nameEnvironment).findTypeNames(binding.compoundName);
- }
- HashSet set = new HashSet<>();
- Set types = new HashSet<>();
- if (typeNames != null) {
- for (char[][] typeName : typeNames) {
- if (typeName == null) continue;
- ReferenceBinding type = environment.getType(typeName);
- if (type == null || type.isMemberType()) continue;
- if (type.isValidBinding()) {
- Element newElement = this._env.getFactory().newElement(type);
- if (newElement.getKind() != ElementKind.PACKAGE) {
- set.add(newElement);
- types.add(type);
- }
- }
- }
- }
- if (binding.knownTypes != null) {
- ReferenceBinding[] knownTypes = binding.knownTypes.valueTable;
- for (ReferenceBinding referenceBinding : knownTypes) {
- if (referenceBinding != null && referenceBinding.isValidBinding() && referenceBinding.enclosingType() == null) {
- if (!types.contains(referenceBinding)) {
- Element newElement = this._env.getFactory().newElement(referenceBinding);
- if (newElement.getKind() != ElementKind.PACKAGE)
- set.add(newElement);
- }
- }
- }
- }
- ArrayList list = new ArrayList<>(set.size());
- list.addAll(set);
- return Collections.unmodifiableList(list);
- }
-
- @Override
- public Element getEnclosingElement() {
- if (super._env.getCompiler().options.sourceLevel < ClassFileConstants.JDK9) {
- return null;
- }
- PackageBinding pBinding = (PackageBinding) this._binding;
- ModuleBinding module = pBinding.enclosingModule;
- if (module == null)
- return null;
- return new ModuleElementImpl(this._env, module);
- }
-
- @Override
- public ElementKind getKind() {
- return ElementKind.PACKAGE;
- }
-
- @Override
- PackageElement getPackage()
- {
- return this;
- }
-
- @Override
- public Name getSimpleName() {
- char[][] compoundName = ((PackageBinding)this._binding).compoundName;
- int length = compoundName.length;
- if (length == 0) {
- return new NameImpl(CharOperation.NO_CHAR);
- }
- return new NameImpl(compoundName[length - 1]);
- }
-
- @Override
- public Name getQualifiedName() {
- return new NameImpl(CharOperation.concatWith(((PackageBinding)this._binding).compoundName, '.'));
- }
-
- @Override
- public boolean isUnnamed() {
- PackageBinding binding = (PackageBinding)this._binding;
- return binding.compoundName == CharOperation.NO_CHAR_CHAR;
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/PrimitiveTypeImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/PrimitiveTypeImpl.java
deleted file mode 100644
index 4de9896..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/PrimitiveTypeImpl.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2014 BEA Systems, Inc. and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- * IBM Corporation - Java 8 support
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeVisitor;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
-
-/**
- *
- * @since 3.3
- */
-public class PrimitiveTypeImpl extends TypeMirrorImpl implements PrimitiveType {
-
- public final static PrimitiveTypeImpl BOOLEAN = new PrimitiveTypeImpl(TypeBinding.BOOLEAN);
- public final static PrimitiveTypeImpl BYTE = new PrimitiveTypeImpl(TypeBinding.BYTE);
- public final static PrimitiveTypeImpl CHAR = new PrimitiveTypeImpl(TypeBinding.CHAR);
- public final static PrimitiveTypeImpl DOUBLE = new PrimitiveTypeImpl(TypeBinding.DOUBLE);
- public final static PrimitiveTypeImpl FLOAT = new PrimitiveTypeImpl(TypeBinding.FLOAT);
- public final static PrimitiveTypeImpl INT = new PrimitiveTypeImpl(TypeBinding.INT);
- public final static PrimitiveTypeImpl LONG = new PrimitiveTypeImpl(TypeBinding.LONG);
- public final static PrimitiveTypeImpl SHORT = new PrimitiveTypeImpl(TypeBinding.SHORT);
-
- /**
- * Clients should call {@link Factory#getPrimitiveType(TypeKind)},
- * rather than creating new objects.
- */
- private PrimitiveTypeImpl(BaseTypeBinding binding) {
- // Primitive types do not need an environment!
- super(null, binding);
- }
-
- PrimitiveTypeImpl(BaseProcessingEnvImpl env, BaseTypeBinding binding) {
- // From Java 8, base type bindings can hold annotations and hence need the environment.
- super(env, binding);
- }
-
- @Override
- public R accept(TypeVisitor v, P p)
- {
- return v.visitPrimitive(this, p);
- }
-
- @Override
- public TypeKind getKind() {
- return getKind((BaseTypeBinding)this._binding);
- }
-
- public static TypeKind getKind(BaseTypeBinding binding) {
- switch (binding.id) {
- case TypeIds.T_boolean:
- return TypeKind.BOOLEAN;
- case TypeIds.T_byte:
- return TypeKind.BYTE;
- case TypeIds.T_char:
- return TypeKind.CHAR;
- case TypeIds.T_double:
- return TypeKind.DOUBLE;
- case TypeIds.T_float:
- return TypeKind.FLOAT;
- case TypeIds.T_int:
- return TypeKind.INT;
- case TypeIds.T_long:
- return TypeKind.LONG;
- case TypeIds.T_short:
- return TypeKind.SHORT;
- default:
- throw new IllegalArgumentException("BaseTypeBinding of unexpected id " + binding.id); //$NON-NLS-1$
- }
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/RecordComponentElementImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/RecordComponentElementImpl.java
deleted file mode 100644
index a86c4df..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/RecordComponentElementImpl.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2020, 2021 IBM Corporation.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.RecordComponentElement;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.RecordComponentBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-
-public class RecordComponentElementImpl extends VariableElementImpl implements RecordComponentElement {
-
- protected RecordComponentElementImpl(BaseProcessingEnvImpl env, RecordComponentBinding binding) {
- super(env, binding);
- }
-
- @Override
- public ElementKind getKind() {
- return ElementKind.RECORD_COMPONENT;
- }
-
- @Override
- public ExecutableElement getAccessor() {
- RecordComponentBinding comp = (RecordComponentBinding) this._binding;
- ReferenceBinding binding = comp.declaringRecord;
- MethodBinding accessor = binding.getRecordComponentAccessor(comp.name);
- if (accessor != null) {
- return new ExecutableElementImpl(this._env, accessor);
- }
- return null;
- }
-
- @Override
- public R accept(ElementVisitor visitor, P param) {
- return visitor.visitRecordComponent(this, param);
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java
deleted file mode 100644
index 4212db5..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java
+++ /dev/null
@@ -1,395 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2023 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Set;
-
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.NestingKind;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.RecordComponentElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.RecordComponentBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-
-public class TypeElementImpl extends ElementImpl implements TypeElement {
-
- /**
- * Compares Element instances possibly returned by
- * {@link TypeElement#getEnclosedElements()} based on their source location, if available.
- */
- private static final class SourceLocationComparator implements Comparator {
- private final IdentityHashMap sourceStartCache = new IdentityHashMap<>();
-
- @Override
- public int compare(Element o1, Element o2) {
- ElementImpl e1 = (ElementImpl) o1;
- ElementImpl e2 = (ElementImpl) o2;
-
- return getSourceStart(e1) - getSourceStart(e2);
- }
-
- private int getSourceStart(ElementImpl e) {
- Integer value = this.sourceStartCache.get(e);
-
- if (value == null) {
- value = determineSourceStart(e);
- this.sourceStartCache.put(e, value);
- }
-
- return value;
- }
-
- private int determineSourceStart(ElementImpl e) {
- switch(e.getKind()) {
- case ANNOTATION_TYPE :
- case INTERFACE :
- case CLASS :
- case ENUM :
- case RECORD :
- TypeElementImpl typeElementImpl = (TypeElementImpl) e;
- Binding typeBinding = typeElementImpl._binding;
- if (typeBinding instanceof SourceTypeBinding) {
- SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) typeBinding;
- TypeDeclaration typeDeclaration = (TypeDeclaration) sourceTypeBinding.scope.referenceContext();
- return typeDeclaration.sourceStart;
- }
- break;
- case CONSTRUCTOR :
- case METHOD :
- ExecutableElementImpl executableElementImpl = (ExecutableElementImpl) e;
- Binding binding = executableElementImpl._binding;
- if (binding instanceof MethodBinding) {
- MethodBinding methodBinding = (MethodBinding) binding;
- return methodBinding.sourceStart();
- }
- break;
- case ENUM_CONSTANT :
- case FIELD :
- case RECORD_COMPONENT :
- VariableElementImpl variableElementImpl = (VariableElementImpl) e;
- binding = variableElementImpl._binding;
- if (binding instanceof FieldBinding) {
- FieldBinding fieldBinding = (FieldBinding) binding;
- FieldDeclaration fieldDeclaration = fieldBinding.sourceField();
- if (fieldDeclaration != null) {
- return fieldDeclaration.sourceStart;
- }
- }
- break;
- default:
- break;
- }
-
- return -1;
- }
- }
-
- private final ElementKind _kindHint;
-
- /**
- * In general, clients should call {@link Factory#newElement(org.eclipse.jdt.internal.compiler.lookup.Binding)}
- * to create new instances.
- */
- TypeElementImpl(BaseProcessingEnvImpl env, ReferenceBinding binding, ElementKind kindHint) {
- super(env, binding);
- this._kindHint = kindHint;
- }
-
- @Override
- public R accept(ElementVisitor v, P p)
- {
- return v.visitType(this, p);
- }
-
- @Override
- protected AnnotationBinding[] getAnnotationBindings()
- {
- return ((ReferenceBinding)this._binding).getAnnotations();
- }
-
- @Override
- public List extends Element> getEnclosedElements() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- List enclosed = new ArrayList<>(binding.fieldCount() + binding.methods().length + binding.memberTypes().length);
- for (MethodBinding method : binding.methods()) {
- ExecutableElement executable = new ExecutableElementImpl(this._env, method);
- enclosed.add(executable);
- }
- for (FieldBinding field : binding.fields()) {
- // TODO no field should be excluded according to the JLS
- if (!field.isSynthetic()) {
- VariableElement variable = new VariableElementImpl(this._env, field);
- enclosed.add(variable);
- }
- }
- if (binding.isRecord()) {
- RecordComponentBinding[] components = binding.components();
- for (RecordComponentBinding comp : components) {
- RecordComponentElement rec = new RecordComponentElementImpl(this._env, comp);
- enclosed.add(rec);
- }
- }
- for (ReferenceBinding memberType : binding.memberTypes()) {
- TypeElement type = new TypeElementImpl(this._env, memberType, null);
- enclosed.add(type);
- }
- Collections.sort(enclosed, new SourceLocationComparator());
- return Collections.unmodifiableList(enclosed);
- }
-
- @Override
- public List extends RecordComponentElement> getRecordComponents() {
- if (this._binding instanceof ReferenceBinding) {
- ReferenceBinding binding = (ReferenceBinding) this._binding;
- List enclosed = new ArrayList<>();
- for (RecordComponentBinding comp : binding.components()) {
- RecordComponentElement variable = new RecordComponentElementImpl(this._env, comp);
- enclosed.add(variable);
- }
- Collections.sort(enclosed, new SourceLocationComparator());
- return Collections.unmodifiableList(enclosed);
- }
- return Collections.emptyList();
- }
-
- @Override
- public List extends TypeMirror> getPermittedSubclasses() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- if (binding.isSealed()) {
- List permitted = new ArrayList<>();
- for (ReferenceBinding type : binding.permittedTypes()) {
- TypeMirror typeMirror = this._env.getFactory().newTypeMirror(type);
- permitted.add(typeMirror);
- }
- return Collections.unmodifiableList(permitted);
- }
- return Collections.emptyList();
- }
- @Override
- public Element getEnclosingElement() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- ReferenceBinding enclosingType = binding.enclosingType();
- if (null == enclosingType) {
- // this is a top level type; get its package
- return this._env.getFactory().newPackageElement(binding.fPackage);
- }
- else {
- return this._env.getFactory().newElement(binding.enclosingType());
- }
- }
-
- @Override
- public String getFileName() {
- char[] name = ((ReferenceBinding)this._binding).getFileName();
- if (name == null)
- return null;
- return new String(name);
- }
-
- @Override
- public List extends TypeMirror> getInterfaces() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- if (null == binding.superInterfaces() || binding.superInterfaces().length == 0) {
- return Collections.emptyList();
- }
- List interfaces = new ArrayList<>(binding.superInterfaces().length);
- for (ReferenceBinding interfaceBinding : binding.superInterfaces()) {
- TypeMirror interfaceType = this._env.getFactory().newTypeMirror(interfaceBinding);
- if (interfaceType.getKind() == TypeKind.ERROR) {
- if (this._env.getSourceVersion().compareTo(SourceVersion.RELEASE_6) > 0) {
- // for jdk 7 and above, add error types
- interfaces.add(interfaceType);
- }
- } else {
- interfaces.add(interfaceType);
- }
- }
- return Collections.unmodifiableList(interfaces);
- }
-
- @Override
- public ElementKind getKind() {
- if (null != this._kindHint) {
- return this._kindHint;
- }
- ReferenceBinding refBinding = (ReferenceBinding)this._binding;
- // The order of these comparisons is important: e.g., enum is subset of class
- if (refBinding.isEnum()) {
- return ElementKind.ENUM;
- }
- else if (refBinding.isRecord()) {
- return ElementKind.RECORD;
- }
- else if (refBinding.isAnnotationType()) {
- return ElementKind.ANNOTATION_TYPE;
- }
- else if (refBinding.isInterface()) {
- return ElementKind.INTERFACE;
- }
- else if (refBinding.isClass()) {
- return ElementKind.CLASS;
- }
- else {
- throw new IllegalArgumentException("TypeElement " + new String(refBinding.shortReadableName()) + //$NON-NLS-1$
- " has unexpected attributes " + refBinding.modifiers); //$NON-NLS-1$
- }
- }
-
- @Override
- public Set getModifiers()
- {
- ReferenceBinding refBinding = (ReferenceBinding)this._binding;
- int modifiers = refBinding.modifiers;
- if (refBinding.isInterface() && refBinding.isNestedType()) {
- modifiers |= ClassFileConstants.AccStatic;
- }
-
- return Factory.getModifiers(modifiers, getKind(), refBinding.isBinaryBinding());
- }
-
- @Override
- public NestingKind getNestingKind() {
- ReferenceBinding refBinding = (ReferenceBinding)this._binding;
- if (refBinding.isAnonymousType()) {
- return NestingKind.ANONYMOUS;
- } else if (refBinding.isLocalType()) {
- return NestingKind.LOCAL;
- } else if (refBinding.isMemberType()) {
- return NestingKind.MEMBER;
- }
- return NestingKind.TOP_LEVEL;
- }
-
- @Override
- PackageElement getPackage()
- {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- return this._env.getFactory().newPackageElement(binding.fPackage);
- }
-
- @Override
- public Name getQualifiedName() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- char[] qName;
- if (binding.isMemberType()) {
- qName = CharOperation.concatWith(binding.enclosingType().compoundName, binding.sourceName, '.');
- CharOperation.replace(qName, '$', '.');
- } else {
- qName = CharOperation.concatWith(binding.compoundName, '.');
- }
- return new NameImpl(qName);
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.apt.model.ElementImpl#getSimpleName()
- * @return last segment of name, e.g. for pa.pb.X.Y return Y.
- */
- @Override
- public Name getSimpleName()
- {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- return new NameImpl(binding.sourceName());
- }
-
- @Override
- public TypeMirror getSuperclass() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- ReferenceBinding superBinding = binding.superclass();
- if (null == superBinding || binding.isInterface()) {
- return this._env.getFactory().getNoType(TypeKind.NONE);
- }
- // superclass of a type must be a DeclaredType
- return this._env.getFactory().newTypeMirror(superBinding);
- }
-
- @Override
- public List extends TypeParameterElement> getTypeParameters() {
- ReferenceBinding binding = (ReferenceBinding)this._binding;
- TypeVariableBinding[] variables = binding.typeVariables();
- if (variables.length == 0) {
- return Collections.emptyList();
- }
- List params = new ArrayList<>(variables.length);
- for (TypeVariableBinding variable : variables) {
- params.add(this._env.getFactory().newTypeParameterElement(variable, this));
- }
- return Collections.unmodifiableList(params);
- }
-
- @Override
- public boolean hides(Element hidden)
- {
- if (!(hidden instanceof TypeElementImpl)) {
- return false;
- }
- ReferenceBinding hiddenBinding = (ReferenceBinding)((TypeElementImpl)hidden)._binding;
- if (hiddenBinding.isPrivate()) {
- return false;
- }
- ReferenceBinding hiderBinding = (ReferenceBinding)this._binding;
- if (TypeBinding.equalsEquals(hiddenBinding, hiderBinding)) {
- return false;
- }
- if (!hiddenBinding.isMemberType() || !hiderBinding.isMemberType()) {
- return false;
- }
- if (!CharOperation.equals(hiddenBinding.sourceName, hiderBinding.sourceName)) {
- return false;
- }
- return null != hiderBinding.enclosingType().findSuperTypeOriginatingFrom(hiddenBinding.enclosingType());
- }
-
- @Override
- public String toString() {
- ReferenceBinding binding = (ReferenceBinding) this._binding;
- char[] concatWith = CharOperation.concatWith(binding.compoundName, '.');
- if (binding.isNestedType()) {
- CharOperation.replace(concatWith, '$', '.');
- return new String(concatWith);
- }
- return new String(concatWith);
-
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeMirrorImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeMirrorImpl.java
deleted file mode 100644
index 9dffc2d..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeMirrorImpl.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2014 BEA Systems, Inc. and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- * IBM Corporation - Java 8 support
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.util.List;
-
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVisitor;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-
-/**
- * Implementation of a TypeMirror. TypeMirror represents a type, including
- * types that have no declaration, such as primitives (int, boolean) and
- * types that are specializations of declarations {@code (List)}.
- */
-public class TypeMirrorImpl implements TypeMirror {
-
- // Caution: _env will be NULL for unannotated primitive types (PrimitiveTypeImpl).
- protected final BaseProcessingEnvImpl _env;
- protected final Binding _binding;
-
- /* package */ TypeMirrorImpl(BaseProcessingEnvImpl env, Binding binding) {
- this._env = env;
- this._binding = binding;
- }
-
- /* package */ Binding binding() {
- return this._binding;
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeMirror#accept(javax.lang.model.type.TypeVisitor, java.lang.Object)
- */
- @Override
- public R accept(TypeVisitor v, P p) {
- return v.visit(this, p);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeMirror#getKind()
- */
- @Override
- public TypeKind getKind() {
- switch (this._binding.kind()) {
- // case Binding.TYPE:
- // case Binding.RAW_TYPE:
- // case Binding.GENERIC_TYPE:
- // case Binding.PARAMETERIZED_TYPE:
- // handled by DeclaredTypeImpl, etc.
- // case Binding.BASE_TYPE: handled by PrimitiveTypeImpl
- // case Binding.METHOD: handled by ExecutableTypeImpl
- // case Binding.PACKAGE: handled by NoTypeImpl
- // case Binding.WILDCARD_TYPE: handled by WildcardTypeImpl
- // case Binding.ARRAY_TYPE: handled by ArrayTypeImpl
- // case Binding.TYPE_PARAMETER: handled by TypeVariableImpl
- // TODO: fill in the rest of these
- case Binding.FIELD:
- case Binding.LOCAL:
- case Binding.RECORD_COMPONENT:
- case Binding.VARIABLE:
- case Binding.IMPORT:
- throw new IllegalArgumentException("Invalid binding kind: " + this._binding.kind()); //$NON-NLS-1$
- }
- return null;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return new String(this._binding.readableName());
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((this._binding == null) ? 0 : this._binding.hashCode());
- return result;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!(obj instanceof TypeMirrorImpl))
- return false;
- final TypeMirrorImpl other = (TypeMirrorImpl) obj;
- return this._binding == other._binding;
- }
-
- /* Package any repeating annotations into containers, return others as is.
- In the compiler bindings repeating annotations are left in as is, hence
- this step. The return value would match what one would expect to see in
- a class file.
- */
- public final AnnotationBinding [] getPackedAnnotationBindings() {
- return Factory.getPackedAnnotationBindings(getAnnotationBindings());
- }
-
- protected AnnotationBinding[] getAnnotationBindings() {
- return ((TypeBinding)this._binding).getTypeAnnotations();
- }
-
- @Override
- public List extends AnnotationMirror> getAnnotationMirrors() {
- return this._env == null ? Factory.EMPTY_ANNOTATION_MIRRORS :
- this._env.getFactory().getAnnotationMirrors(getPackedAnnotationBindings());
- }
-
- @Override
- public A getAnnotation(Class annotationType) {
- return this._env == null ? null : this._env.getFactory().getAnnotation(getPackedAnnotationBindings(), annotationType);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public A[] getAnnotationsByType(Class annotationType) {
- if (this._env == null)
- return (A[]) Array.newInstance(annotationType, 0);
- return this._env.getFactory().getAnnotationsByType(Factory.getUnpackedAnnotationBindings(getPackedAnnotationBindings()), annotationType);
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeParameterElementImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeParameterElementImpl.java
deleted file mode 100644
index a6502f3..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeParameterElementImpl.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2023 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- * IBM Corporation - fix for 342470
- * IBM Corporation - fix for 342598
- * IBM Corporation - Java 8 support
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.type.TypeMirror;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-
-public class TypeParameterElementImpl extends ElementImpl implements TypeParameterElement
-{
- private final Element _declaringElement;
-
- // Cache the bounds, because they're expensive to compute
- private List extends TypeMirror> _bounds = null;
-
- /* package */ TypeParameterElementImpl(BaseProcessingEnvImpl env, TypeVariableBinding binding, Element declaringElement) {
- super(env, binding);
- this._declaringElement = declaringElement;
- }
-
- /* package */ TypeParameterElementImpl(BaseProcessingEnvImpl env, TypeVariableBinding binding) {
- super(env, binding);
- this._declaringElement = this._env.getFactory().newElement(binding.declaringElement);
- }
-
- @Override
- public List extends TypeMirror> getBounds()
- {
- if (null == this._bounds) {
- this._bounds = calculateBounds();
- }
- return this._bounds;
- }
-
- // This code is drawn from org.eclipse.jdt.core.dom.TypeBinding.getTypeBounds()
- private List extends TypeMirror> calculateBounds() {
- TypeVariableBinding typeVariableBinding = (TypeVariableBinding)this._binding;
- ReferenceBinding varSuperclass = typeVariableBinding.superclass();
- TypeBinding firstClassOrArrayBound = typeVariableBinding.firstBound;
- int boundsLength = 0;
- boolean isFirstBoundATypeVariable = false;
- if (firstClassOrArrayBound != null) {
- if (firstClassOrArrayBound.isTypeVariable()) {
- isFirstBoundATypeVariable = true;
- }
- if (TypeBinding.equalsEquals(firstClassOrArrayBound, varSuperclass)) {
- boundsLength++;
- if (firstClassOrArrayBound.isTypeVariable()) {
- isFirstBoundATypeVariable = true;
- }
- } else if (firstClassOrArrayBound.isArrayType()) { // capture of ? extends/super arrayType
- boundsLength++;
- } else {
- firstClassOrArrayBound = null;
- }
- }
- ReferenceBinding[] superinterfaces = typeVariableBinding.superInterfaces();
- int superinterfacesLength = 0;
- if (superinterfaces != null) {
- superinterfacesLength = superinterfaces.length;
- boundsLength += superinterfacesLength;
- }
- List typeBounds = new ArrayList<>(boundsLength);
- if (boundsLength != 0) {
- if (firstClassOrArrayBound != null) {
- TypeMirror typeBinding = this._env.getFactory().newTypeMirror(firstClassOrArrayBound);
- if (typeBinding == null) {
- return Collections.emptyList();
- }
- typeBounds.add(typeBinding);
- }
- // we need to filter out remaining bounds if the first bound is a type variable
- if (superinterfaces != null && !isFirstBoundATypeVariable) {
- for (int i = 0; i < superinterfacesLength; i++) {
- TypeMirror typeBinding = this._env.getFactory().newTypeMirror(superinterfaces[i]);
- if (typeBinding == null) {
- return Collections.emptyList();
- }
- typeBounds.add(typeBinding);
- }
- }
- } else {
- // at least we must add java.lang.Object
- typeBounds.add(this._env.getFactory().newTypeMirror(this._env.getLookupEnvironment().getType(TypeConstants.JAVA_LANG_OBJECT)));
- }
- return Collections.unmodifiableList(typeBounds);
- }
-
- @Override
- public Element getGenericElement()
- {
- return this._declaringElement;
- }
-
- @Override
- public R accept(ElementVisitor v, P p)
- {
- return v.visitTypeParameter(this, p);
- }
-
- /*
- * (non-Javadoc)
- * Java supports annotations on type parameters from JLS8
- * @see javax.lang.model.element.Element#getAnnotationMirrors()
- */
- @Override
- protected AnnotationBinding[] getAnnotationBindings()
- {
- return ((TypeVariableBinding)this._binding).getTypeAnnotations();
- }
-
- private boolean shouldEmulateJavacBug() {
- if (this._env.getLookupEnvironment().globalOptions.emulateJavacBug8031744) {
- AnnotationBinding [] annotations = getAnnotationBindings();
- for (int i = 0, length = annotations.length; i < length; i++) {
- ReferenceBinding firstAnnotationType = annotations[i].getAnnotationType();
- for (int j = i+1; j < length; j++) {
- ReferenceBinding secondAnnotationType = annotations[j].getAnnotationType();
- if (firstAnnotationType == secondAnnotationType) //$IDENTITY-COMPARISON$
- return true;
- }
- }
- }
- return false;
- }
-
- @Override
- public List extends AnnotationMirror> getAnnotationMirrors() {
- if (shouldEmulateJavacBug())
- return Collections.emptyList();
- return super.getAnnotationMirrors();
- }
-
- @Override
- @SuppressWarnings("unchecked") // for the cast to A
- public A[] getAnnotationsByType(Class annotationType) {
- if (shouldEmulateJavacBug())
- return (A[]) Array.newInstance(annotationType, 0);
- return super.getAnnotationsByType(annotationType);
- }
-
- @Override
- public A getAnnotation(Class annotationType) {
- if (shouldEmulateJavacBug())
- return null;
- return super.getAnnotation(annotationType);
- }
-
- /*
- * (non-Javadoc)
- * Always return an empty list; type parameters do not enclose other elements.
- * @see javax.lang.model.element.Element#getEnclosedElements()
- */
- @Override
- public List extends Element> getEnclosedElements()
- {
- return Collections.emptyList();
- }
-
- /*
- * (non-Javadoc)
- * Always return null.
- * @see javax.lang.model.element.Element#getEnclosingElement()
- */
- @Override
- public Element getEnclosingElement()
- {
- return getGenericElement();
- }
-
- @Override
- public ElementKind getKind()
- {
- return ElementKind.TYPE_PARAMETER;
- }
-
- @Override
- PackageElement getPackage()
- {
- // TODO what is the package of a type parameter?
- return null;
- }
-
- @Override
- public String toString() {
- return new String(this._binding.readableName());
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeVariableImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeVariableImpl.java
deleted file mode 100644
index 46a6d7e..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypeVariableImpl.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2023 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import javax.lang.model.element.Element;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.lang.model.type.TypeVisitor;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-
-/**
- * Implementation of TypeVariable
- */
-public class TypeVariableImpl extends TypeMirrorImpl implements TypeVariable {
-
- TypeVariableImpl(BaseProcessingEnvImpl env, TypeVariableBinding binding) {
- super(env, binding);
- }
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeVariable#asElement()
- */
- @Override
- public Element asElement() {
- return this._env.getFactory().newElement(this._binding);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeVariable#getLowerBound()
- */
- @Override
- public TypeMirror getLowerBound() {
- // TODO might be more complex than this
- return this._env.getFactory().getNullType();
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeVariable#getUpperBound()
- */
- @Override
- public TypeMirror getUpperBound() {
- TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this._binding;
- TypeBinding firstBound = typeVariableBinding.firstBound;
- ReferenceBinding[] superInterfaces = typeVariableBinding.superInterfaces;
- if (firstBound == null || superInterfaces.length == 0) {
- // no explicit bound
- return this._env.getFactory().newTypeMirror(typeVariableBinding.upperBound());
- }
- if (superInterfaces.length == 1 && TypeBinding.equalsEquals(superInterfaces[0], firstBound)) {
- // only one bound that is an interface
- return this._env.getFactory().newTypeMirror(typeVariableBinding.upperBound());
- }
- return this._env.getFactory().newTypeMirror(this._binding);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeMirror#accept(javax.lang.model.type.TypeVisitor, java.lang.Object)
- */
- @Override
- public R accept(TypeVisitor v, P p) {
- return v.visitTypeVariable(this, p);
- }
-
- @Override
- public TypeKind getKind() {
- return TypeKind.TYPEVAR;
- }
-
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java
deleted file mode 100644
index 40c26f8..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/TypesImpl.java
+++ /dev/null
@@ -1,584 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007 - 2023 BEA Systems, Inc. and others
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Walter Harley - initial API and implementation
- * IBM Corporation - fix for 342598, 382590
- * Jean-Marie Henaff (Google) - Bug 481555
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.NoType;
-import javax.lang.model.type.NullType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.WildcardType;
-import javax.lang.model.util.Types;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.ast.Wildcard;
-import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
-import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
-
-/**
- * Utilities for working with types (as opposed to elements).
- * There is one of these for every ProcessingEnvironment.
- */
-public class TypesImpl implements Types {
-
- private final BaseProcessingEnvImpl _env;
-
- /*
- * The processing env creates and caches a TypesImpl. Other clients should
- * not create their own; they should ask the env for it.
- */
- public TypesImpl(BaseProcessingEnvImpl env) {
- this._env = env;
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.util.Types#asElement(javax.lang.model.type.TypeMirror)
- */
- @Override
- public Element asElement(TypeMirror t) {
- switch(t.getKind()) {
- case DECLARED :
- case TYPEVAR :
- return this._env.getFactory().newElement(((TypeMirrorImpl)t).binding());
- default:
- break;
- }
- return null;
- }
-
- @Override
- public TypeMirror asMemberOf(DeclaredType containing, Element element) {
- // throw new UnsupportedOperationException("NYI: TypesImpl.asMemberOf("
- // + containing + ", " + element + ")"); //$NON-NLS-1$ //$NON-NLS-2$
- // //$NON-NLS-3$
- ElementImpl elementImpl = (ElementImpl) element;
- DeclaredTypeImpl declaredTypeImpl = (DeclaredTypeImpl) containing;
- ReferenceBinding referenceBinding = (ReferenceBinding) declaredTypeImpl._binding;
- TypeMirror typeMirror;
-
- switch (element.getKind()) {
- case CONSTRUCTOR:
- case METHOD:
- typeMirror = findMemberInHierarchy(referenceBinding, elementImpl._binding, new MemberInTypeFinder() {
- @Override
- public TypeMirror find(ReferenceBinding typeBinding, Binding memberBinding) {
- MethodBinding methodBinding = ((MethodBinding) memberBinding);
- for (MethodBinding method : typeBinding.methods()) {
- if (CharOperation.equals(method.selector, methodBinding.selector)
- && (method.original() == methodBinding
- || method.areParameterErasuresEqual(methodBinding))) {
- return TypesImpl.this._env.getFactory().newTypeMirror(method);
- }
- }
- return null;
- }
- });
-
- if (typeMirror != null) {
- return typeMirror;
- }
- break;
- case TYPE_PARAMETER:
- typeMirror = findMemberInHierarchy(referenceBinding, elementImpl._binding, new MemberInTypeFinder() {
- @Override
- public TypeMirror find(ReferenceBinding typeBinding, Binding memberBinding) {
- if (typeBinding instanceof ParameterizedTypeBinding) {
- TypeVariableBinding variableBinding = ((TypeVariableBinding) memberBinding);
- ReferenceBinding binding = ((ParameterizedTypeBinding) typeBinding).genericType();
- if (variableBinding.declaringElement == binding) { // check in advance avoid looking into type parameters unnecessarily.
- TypeVariableBinding[] typeVariables = binding.typeVariables();
- TypeBinding[] typeArguments = ((ParameterizedTypeBinding) typeBinding).typeArguments();
- if (typeVariables.length == typeArguments.length) {
- for(int i = 0; i < typeVariables.length; i++) {
- if (typeVariables[i] == memberBinding) {
- return TypesImpl.this._env.getFactory().newTypeMirror(typeArguments[i]);
- }
- }
- }
- }
- }
- return null;
- }
- });
-
- if (typeMirror != null) {
- return typeMirror;
- }
- break;
- case FIELD:
- case ENUM_CONSTANT:
- case RECORD_COMPONENT:
- typeMirror = findMemberInHierarchy(referenceBinding, elementImpl._binding, new MemberInTypeFinder() {
- @Override
- public TypeMirror find(ReferenceBinding typeBinding, Binding memberBinding) {
- VariableBinding variableBinding = (VariableBinding) memberBinding;
- for (FieldBinding field : typeBinding.fields()) {
- if (CharOperation.equals(field.name, variableBinding.name)) {
- return TypesImpl.this._env.getFactory().newTypeMirror(field);
- }
- }
- return null;
- }
- });
-
- if (typeMirror != null) {
- return typeMirror;
- }
- break;
- case ENUM:
- case ANNOTATION_TYPE:
- case INTERFACE:
- case CLASS:
- case RECORD:
- typeMirror = findMemberInHierarchy(referenceBinding, elementImpl._binding, new MemberInTypeFinder() {
- @Override
- public TypeMirror find(ReferenceBinding typeBinding, Binding memberBinding) {
- ReferenceBinding elementBinding = (ReferenceBinding) memberBinding;
- // If referenceBinding is a ParameterizedTypeBinding, this
- // will return only ParameterizedTypeBindings
- // for member types, even if the member happens to be a
- // static nested class. That's probably a bug;
- // static nested classes are not parameterized by their
- // outer class.
- for (ReferenceBinding memberReferenceBinding : typeBinding.memberTypes()) {
- if (CharOperation.equals(elementBinding.compoundName, memberReferenceBinding.compoundName)) {
- return TypesImpl.this._env.getFactory().newTypeMirror(memberReferenceBinding);
- }
- }
- return null;
- }
- });
-
- if (typeMirror != null) {
- return typeMirror;
- }
- break;
- default:
- throw new IllegalArgumentException("element " + element + //$NON-NLS-1$
- " has unrecognized element kind " + element.getKind()); //$NON-NLS-1$
- }
- throw new IllegalArgumentException("element " + element + //$NON-NLS-1$
- " is not a member of the containing type " + containing + //$NON-NLS-1$
- " nor any of its superclasses"); //$NON-NLS-1$
- }
-
- private static interface MemberInTypeFinder {
- TypeMirror find(ReferenceBinding typeBinding, Binding memberBinding);
- }
-
- private TypeMirror findMemberInHierarchy(ReferenceBinding typeBinding, Binding memberBinding,
- MemberInTypeFinder finder) {
- TypeMirror result = null;
-
- if (typeBinding == null) {
- return null;
- }
-
- result = finder.find(typeBinding, memberBinding);
- if (result != null) {
- return result;
- }
-
- result = findMemberInHierarchy(typeBinding.superclass(), memberBinding, finder);
- if (result != null) {
- return result;
- }
-
- for (ReferenceBinding superInterface : typeBinding.superInterfaces()) {
- result = findMemberInHierarchy(superInterface, memberBinding, finder);
- if (result != null) {
- return result;
- }
- }
-
- return null;
- }
- private void validateRealType(TypeMirror t) {
- switch (t.getKind()) {
- case EXECUTABLE:
- case PACKAGE:
- case MODULE:
- throw new IllegalArgumentException(
- "Executable, package and module are illegal argument for Types.contains(..)"); //$NON-NLS-1$
- default:
- break;
- }
- }
- private void validateRealTypes(TypeMirror t1, TypeMirror t2) {
- validateRealType(t1);
- validateRealType(t2);
- }
-
- @Override
- public TypeElement boxedClass(PrimitiveType p) {
- PrimitiveTypeImpl primitiveTypeImpl = (PrimitiveTypeImpl) p;
- BaseTypeBinding baseTypeBinding = (BaseTypeBinding)primitiveTypeImpl._binding;
- TypeBinding boxed = this._env.getLookupEnvironment().computeBoxingType(baseTypeBinding);
- return (TypeElement) this._env.getFactory().newElement(boxed);
- }
-
- @Override
- public TypeMirror capture(TypeMirror t) {
- validateRealType(t);
- TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) t;
- if (typeMirrorImpl._binding instanceof ParameterizedTypeBinding) {
- throw new UnsupportedOperationException("NYI: TypesImpl.capture(...)"); //$NON-NLS-1$
- }
- return t;
- }
-
- @Override
- public boolean contains(TypeMirror t1, TypeMirror t2) {
- validateRealTypes(t1, t2);
- throw new UnsupportedOperationException("NYI: TypesImpl.contains(" + t1 + ", " + t2 + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- @Override
- public List extends TypeMirror> directSupertypes(TypeMirror t) {
- validateRealType(t);
- TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) t;
- Binding binding = typeMirrorImpl._binding;
- if (binding instanceof ReferenceBinding) {
- ReferenceBinding referenceBinding = (ReferenceBinding) binding;
- ArrayList list = new ArrayList<>();
- ReferenceBinding superclass = referenceBinding.superclass();
- if (superclass != null) {
- list.add(this._env.getFactory().newTypeMirror(superclass));
- }
- for (ReferenceBinding interfaceBinding : referenceBinding.superInterfaces()) {
- list.add(this._env.getFactory().newTypeMirror(interfaceBinding));
- }
- return Collections.unmodifiableList(list);
- }
- return Collections.emptyList();
- }
-
- @Override
- public TypeMirror erasure(TypeMirror t) {
- validateRealType(t);
- TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) t;
- Binding binding = typeMirrorImpl._binding;
- if (binding instanceof ReferenceBinding) {
- TypeBinding type = ((ReferenceBinding) binding).erasure();
- if (type.isGenericType()) {
- type = this._env.getLookupEnvironment().convertToRawType(type, false);
- }
- return this._env.getFactory().newTypeMirror(type);
- }
- if (binding instanceof ArrayBinding) {
- TypeBinding typeBinding = (TypeBinding) binding;
- TypeBinding leafType = typeBinding.leafComponentType().erasure();
- if (leafType.isGenericType()) {
- leafType = this._env.getLookupEnvironment().convertToRawType(leafType, false);
- }
- return this._env.getFactory().newTypeMirror(
- this._env.getLookupEnvironment().createArrayType(leafType,
- typeBinding.dimensions()));
- }
- return t;
- }
-
- @Override
- public ArrayType getArrayType(TypeMirror componentType) {
- TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) componentType;
- TypeBinding typeBinding = (TypeBinding) typeMirrorImpl._binding;
- return (ArrayType) this._env.getFactory().newTypeMirror(
- this._env.getLookupEnvironment().createArrayType(
- typeBinding.leafComponentType(),
- typeBinding.dimensions() + 1));
- }
-
- /*
- * (non-Javadoc)
- * Create a type instance by parameterizing a type element. If the element is a member type,
- * its container won't be parameterized (if it needs to be, you would need to use the form of
- * getDeclaredType that takes a container TypeMirror). If typeArgs is empty, and typeElem
- * is not generic, then you should use TypeElem.asType(). If typeArgs is empty and typeElem
- * is generic, this method will create the raw type.
- */
- @Override
- public DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) {
- int typeArgsLength = typeArgs.length;
- TypeElementImpl typeElementImpl = (TypeElementImpl) typeElem;
- ReferenceBinding elementBinding = (ReferenceBinding) typeElementImpl._binding;
- TypeVariableBinding[] typeVariables = elementBinding.typeVariables();
- int typeVariablesLength = typeVariables.length;
- if (typeArgsLength == 0) {
- if (elementBinding.isGenericType()) {
- // per javadoc,
- return (DeclaredType) this._env.getFactory().newTypeMirror(this._env.getLookupEnvironment().createRawType(elementBinding, null));
- }
- return (DeclaredType)typeElem.asType();
- } else if (typeArgsLength != typeVariablesLength) {
- throw new IllegalArgumentException("Number of typeArguments doesn't match the number of formal parameters of typeElem"); //$NON-NLS-1$
- }
- TypeBinding[] typeArguments = new TypeBinding[typeArgsLength];
- for (int i = 0; i < typeArgsLength; i++) {
- TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) typeArgs[i];
- Binding binding = typeMirrorImpl._binding;
- if (!(binding instanceof TypeBinding)) {
- throw new IllegalArgumentException("Invalid type argument: " + typeMirrorImpl); //$NON-NLS-1$
- }
- typeArguments[i] = (TypeBinding) binding;
- }
-
- ReferenceBinding enclosing = elementBinding.enclosingType();
- if (enclosing != null) {
- enclosing = this._env.getLookupEnvironment().createRawType(enclosing, null);
- }
-
- return (DeclaredType) this._env.getFactory().newTypeMirror(
- this._env.getLookupEnvironment().createParameterizedType(elementBinding, typeArguments, enclosing));
- }
-
- /* (non-Javadoc)
- * Create a specific type from a member element. The containing type can be parameterized,
- * e.g. Outer.Inner, but it cannot be generic, i.e., Outer.Inner. It only makes
- * sense to use this method when the member element is parameterized by its container; so,
- * for example, it makes sense for an inner class but not for a static member class.
- * Otherwise you should just use getDeclaredType(TypeElement, TypeMirror ...), if you need
- * to specify type arguments, or TypeElement.asType() directly, if not.
- */
- @Override
- public DeclaredType getDeclaredType(DeclaredType containing, TypeElement typeElem,
- TypeMirror... typeArgs) {
- int typeArgsLength = typeArgs.length;
- TypeElementImpl typeElementImpl = (TypeElementImpl) typeElem;
- ReferenceBinding elementBinding = (ReferenceBinding) typeElementImpl._binding;
- TypeVariableBinding[] typeVariables = elementBinding.typeVariables();
- int typeVariablesLength = typeVariables.length;
- DeclaredTypeImpl declaredTypeImpl = (DeclaredTypeImpl) containing;
- ReferenceBinding enclosingType = (ReferenceBinding) declaredTypeImpl._binding;
- if (typeArgsLength == 0) {
- if (elementBinding.isGenericType()) {
- // e.g., Outer.Inner but T is not specified
- // Per javadoc on interface, must return the raw type Outer.Inner
- return (DeclaredType) this._env.getFactory().newTypeMirror(
- this._env.getLookupEnvironment().createRawType(elementBinding, enclosingType));
- } else {
- // e.g., Outer.Inner
- ParameterizedTypeBinding ptb = this._env.getLookupEnvironment().createParameterizedType(elementBinding, null, enclosingType);
- return (DeclaredType) this._env.getFactory().newTypeMirror(ptb);
- }
- } else if (typeArgsLength != typeVariablesLength) {
- throw new IllegalArgumentException("Number of typeArguments doesn't match the number of formal parameters of typeElem"); //$NON-NLS-1$
- }
- TypeBinding[] typeArguments = new TypeBinding[typeArgsLength];
- for (int i = 0; i < typeArgsLength; i++) {
- TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) typeArgs[i];
- Binding binding = typeMirrorImpl._binding;
- if (!(binding instanceof TypeBinding)) {
- throw new IllegalArgumentException("Invalid type for a type arguments : " + typeMirrorImpl); //$NON-NLS-1$
- }
- typeArguments[i] = (TypeBinding) binding;
- }
- return (DeclaredType) this._env.getFactory().newTypeMirror(
- this._env.getLookupEnvironment().createParameterizedType(elementBinding, typeArguments, enclosingType));
- }
-
- @Override
- public NoType getNoType(TypeKind kind) {
- return this._env.getFactory().getNoType(kind);
- }
-
- @Override
- public NullType getNullType() {
- return this._env.getFactory().getNullType();
- }
-
- @Override
- public PrimitiveType getPrimitiveType(TypeKind kind) {
- return this._env.getFactory().getPrimitiveType(kind);
- }
-
- @Override
- public WildcardType getWildcardType(TypeMirror extendsBound, TypeMirror superBound) {
- if (extendsBound != null && superBound != null) {
- throw new IllegalArgumentException("Extends and super bounds cannot be set at the same time"); //$NON-NLS-1$
- }
- if (extendsBound != null) {
- TypeMirrorImpl extendsBoundMirrorType = (TypeMirrorImpl) extendsBound;
- TypeBinding typeBinding = (TypeBinding) extendsBoundMirrorType._binding;
- return (WildcardType) this._env.getFactory().newTypeMirror(
- this._env.getLookupEnvironment().createWildcard(
- null,
- 0,
- typeBinding,
- null,
- Wildcard.EXTENDS));
- }
- if (superBound != null) {
- TypeMirrorImpl superBoundMirrorType = (TypeMirrorImpl) superBound;
- TypeBinding typeBinding = (TypeBinding) superBoundMirrorType._binding;
- return new WildcardTypeImpl(this._env, this._env.getLookupEnvironment().createWildcard(
- null,
- 0,
- typeBinding,
- null,
- Wildcard.SUPER));
- }
- return new WildcardTypeImpl(this._env, this._env.getLookupEnvironment().createWildcard(
- null,
- 0,
- null,
- null,
- Wildcard.UNBOUND));
- }
-
- /* (non-Javadoc)
- * @return true if a value of type t1 can be assigned to a variable of type t2, i.e., t2 = t1.
- */
- @Override
- public boolean isAssignable(TypeMirror t1, TypeMirror t2) {
- validateRealTypes(t1, t2);
- if (!(t1 instanceof TypeMirrorImpl) || !(t2 instanceof TypeMirrorImpl)) {
- return false;
- }
- Binding b1 = ((TypeMirrorImpl)t1).binding();
- Binding b2 = ((TypeMirrorImpl)t2).binding();
- if (!(b1 instanceof TypeBinding) || !(b2 instanceof TypeBinding)) {
- // package, method, import, etc.
- throw new IllegalArgumentException();
- }
- if (((TypeBinding)b1).isCompatibleWith((TypeBinding)b2)) {
- return true;
- }
-
- TypeBinding convertedType = this._env.getLookupEnvironment().computeBoxingType((TypeBinding)b1);
- return null != convertedType && convertedType.isCompatibleWith((TypeBinding)b2);
- }
-
- @Override
- public boolean isSameType(TypeMirror t1, TypeMirror t2) {
- if (t1 instanceof NoTypeImpl) {
- if (t2 instanceof NoTypeImpl) {
- return ((NoTypeImpl) t1).getKind() == ((NoTypeImpl) t2).getKind();
- }
- return false;
- } else if (t2 instanceof NoTypeImpl) {
- return false;
- }
- if (t1.getKind() == TypeKind.WILDCARD || t2.getKind() == TypeKind.WILDCARD) {
- // Wildcard types are never equal, according to the spec of this method
- return false;
- }
- if (t1 == t2) {
- return true;
- }
- if (!(t1 instanceof TypeMirrorImpl) || !(t2 instanceof TypeMirrorImpl)) {
- return false;
- }
- Binding b1 = ((TypeMirrorImpl)t1).binding();
- Binding b2 = ((TypeMirrorImpl)t2).binding();
-
- if (b1 == b2) {
- return true;
- }
- if (!(b1 instanceof TypeBinding) || !(b2 instanceof TypeBinding)) {
- return false;
- }
- TypeBinding type1 = ((TypeBinding) b1);
- TypeBinding type2 = ((TypeBinding) b2);
- if (TypeBinding.equalsEquals(type1, type2))
- return true;
- return CharOperation.equals(type1.computeUniqueKey(), type2.computeUniqueKey());
- }
-
- @Override
- public boolean isSubsignature(ExecutableType m1, ExecutableType m2) {
- MethodBinding methodBinding1 = (MethodBinding) ((ExecutableTypeImpl) m1)._binding;
- MethodBinding methodBinding2 = (MethodBinding) ((ExecutableTypeImpl) m2)._binding;
- if (!CharOperation.equals(methodBinding1.selector, methodBinding2.selector))
- return false;
- return methodBinding1.areParameterErasuresEqual(methodBinding2) && methodBinding1.areTypeVariableErasuresEqual(methodBinding2);
- }
-
- /* (non-Javadoc)
- * @return true if t1 is a subtype of t2, or if t1 == t2.
- */
- @Override
- public boolean isSubtype(TypeMirror t1, TypeMirror t2) {
- validateRealTypes(t1, t2);
- if (t1 instanceof NoTypeImpl) {
- if (t2 instanceof NoTypeImpl) {
- return ((NoTypeImpl) t1).getKind() == ((NoTypeImpl) t2).getKind();
- }
- return false;
- } else if (t2 instanceof NoTypeImpl) {
- return false;
- }
- if (!(t1 instanceof TypeMirrorImpl) || !(t2 instanceof TypeMirrorImpl)) {
- throw new IllegalArgumentException();
- }
- if (t1 == t2) {
- return true;
- }
- Binding b1 = ((TypeMirrorImpl)t1).binding();
- Binding b2 = ((TypeMirrorImpl)t2).binding();
- if (b1 == b2) {
- return true;
- }
- if (!(b1 instanceof TypeBinding) || !(b2 instanceof TypeBinding)) {
- // package, method, import, etc.
- throw new IllegalArgumentException();
- }
- if (b1.kind() == Binding.BASE_TYPE || b2.kind() == Binding.BASE_TYPE) {
- if (b1.kind() != b2.kind()) {
- return false;
- }
- else {
- // for primitives, compatibility implies subtype
- return ((TypeBinding)b1).isCompatibleWith((TypeBinding)b2);
- }
- }
- return ((TypeBinding)b1).isCompatibleWith((TypeBinding)b2);
- }
-
- @Override
- public PrimitiveType unboxedType(TypeMirror t) {
- if (!(((TypeMirrorImpl)t)._binding instanceof ReferenceBinding)) {
- // Not an unboxable type - could be primitive, array, not a type at all, etc.
- throw new IllegalArgumentException("Given type mirror cannot be unboxed"); //$NON-NLS-1$
- }
- ReferenceBinding boxed = (ReferenceBinding)((TypeMirrorImpl)t)._binding;
- TypeBinding unboxed = this._env.getLookupEnvironment().computeBoxingType(boxed);
- if (unboxed.kind() != Binding.BASE_TYPE) {
- // No boxing conversion was found
- throw new IllegalArgumentException();
- }
- return (PrimitiveType) this._env.getFactory().newTypeMirror(unboxed);
- }
-
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/VariableElementImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/VariableElementImpl.java
deleted file mode 100644
index 826b204..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/VariableElementImpl.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2015 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- *
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.VariableElement;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.impl.Constant;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
-import org.eclipse.jdt.internal.compiler.lookup.AptBinaryLocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.AptSourceLocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.RecordComponentBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
-import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
-
-/**
- * Implementation of VariableElement, which represents a a field, enum constant,
- * method or constructor parameter, local variable, or exception parameter.
- */
-public class VariableElementImpl extends ElementImpl implements VariableElement {
-
- /**
- * @param binding might be a FieldBinding (for a field) or a LocalVariableBinding (for a method param)
- */
- VariableElementImpl(BaseProcessingEnvImpl env, VariableBinding binding) {
- super(env, binding);
- }
-
- @Override
- public R accept(ElementVisitor v, P p)
- {
- return v.visitVariable(this, p);
- }
-
- @Override
- protected AnnotationBinding[] getAnnotationBindings()
- {
- return ((VariableBinding)this._binding).getAnnotations();
- }
-
- @Override
- public Object getConstantValue() {
- VariableBinding variableBinding = (VariableBinding) this._binding;
- Constant constant = variableBinding.constant();
- if (constant == null || constant == Constant.NotAConstant) return null;
- TypeBinding type = variableBinding.type;
- switch (type.id) {
- case TypeIds.T_boolean:
- return constant.booleanValue();
- case TypeIds.T_byte:
- return constant.byteValue();
- case TypeIds.T_char:
- return constant.charValue();
- case TypeIds.T_double:
- return constant.doubleValue();
- case TypeIds.T_float:
- return constant.floatValue();
- case TypeIds.T_int:
- return constant.intValue();
- case TypeIds.T_JavaLangString:
- return constant.stringValue();
- case TypeIds.T_long:
- return constant.longValue();
- case TypeIds.T_short:
- return constant.shortValue();
- }
- return null;
- }
-
- @Override
- public List extends Element> getEnclosedElements() {
- return Collections.emptyList();
- }
-
- @Override
- public Element getEnclosingElement() {
- if (this._binding instanceof FieldBinding) {
- return this._env.getFactory().newElement(((FieldBinding)this._binding).declaringClass);
- }
- else if (this._binding instanceof AptSourceLocalVariableBinding){
- return this._env.getFactory().newElement(((AptSourceLocalVariableBinding) this._binding).methodBinding);
- } else if (this._binding instanceof AptBinaryLocalVariableBinding) {
- return this._env.getFactory().newElement(((AptBinaryLocalVariableBinding) this._binding).methodBinding);
- } else if (this._binding instanceof RecordComponentBinding) {
- return this._env.getFactory().newElement(((RecordComponentBinding)this._binding).declaringRecord);
- }
- return null;
- }
-
- @Override
- public ElementKind getKind() {
- if (this._binding instanceof FieldBinding) {
- if ((((FieldBinding) this._binding).modifiers & ClassFileConstants.AccEnum) != 0) {
- return ElementKind.ENUM_CONSTANT;
- }
- else {
- return ElementKind.FIELD;
- }
- }
- else {
- return ElementKind.PARAMETER;
- }
- }
-
- @Override
- public Set getModifiers()
- {
- if (this._binding instanceof VariableBinding) {
- return Factory.getModifiers(((VariableBinding)this._binding).modifiers, getKind());
- }
- return Collections.emptySet();
- }
-
- @Override
- PackageElement getPackage()
- {
- if (this._binding instanceof FieldBinding) {
- PackageBinding pkgBinding = ((FieldBinding)this._binding).declaringClass.fPackage;
- return this._env.getFactory().newPackageElement(pkgBinding);
- }
- else {
- // TODO: what is the package of a method parameter?
- throw new UnsupportedOperationException("NYI: VariableElmentImpl.getPackage() for method parameter"); //$NON-NLS-1$
- }
- }
-
- @Override
- public Name getSimpleName() {
- return new NameImpl(((VariableBinding)this._binding).name);
- }
-
- @Override
- public boolean hides(Element hiddenElement)
- {
- if (this._binding instanceof FieldBinding) {
- if (!(((ElementImpl)hiddenElement)._binding instanceof FieldBinding)) {
- return false;
- }
- FieldBinding hidden = (FieldBinding)((ElementImpl)hiddenElement)._binding;
- if (hidden.isPrivate()) {
- return false;
- }
- FieldBinding hider = (FieldBinding)this._binding;
- if (hidden == hider) {
- return false;
- }
- if (!CharOperation.equals(hider.name, hidden.name)) {
- return false;
- }
- return null != hider.declaringClass.findSuperTypeOriginatingFrom(hidden.declaringClass);
- }
- // TODO: should we implement hides() for method parameters?
- return false;
- }
-
- @Override
- public String toString() {
- return new String(((VariableBinding) this._binding).name);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final VariableElementImpl other = (VariableElementImpl) obj;
- return Objects.equals(this._binding, other._binding);
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/WildcardTypeImpl.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/WildcardTypeImpl.java
deleted file mode 100644
index 31a7459..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/model/WildcardTypeImpl.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2011 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.jdt.internal.compiler.apt.model;
-
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVisitor;
-import javax.lang.model.type.WildcardType;
-
-import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
-import org.eclipse.jdt.internal.compiler.ast.Wildcard;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
-
-/**
- * Implementation of the WildcardType
- */
-public class WildcardTypeImpl extends TypeMirrorImpl implements WildcardType {
-
- WildcardTypeImpl(BaseProcessingEnvImpl env, WildcardBinding binding) {
- super(env, binding);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.WildcardType#getExtendsBound()
- */
- @Override
- public TypeMirror getExtendsBound() {
- WildcardBinding wildcardBinding = (WildcardBinding) this._binding;
- if (wildcardBinding.boundKind != Wildcard.EXTENDS) return null;
- TypeBinding bound = wildcardBinding.bound;
- if (bound == null) return null;
- return this._env.getFactory().newTypeMirror(bound);
- }
-
- /* (non-Javadoc)
- * @see javax.lang.model.type.TypeMirror#getKind()
- */
- @Override
- public TypeKind getKind() {
- return TypeKind.WILDCARD;
- }
- /* (non-Javadoc)
- * @see javax.lang.model.type.WildcardType#getSuperBound()
- */
- @Override
- public TypeMirror getSuperBound() {
- WildcardBinding wildcardBinding = (WildcardBinding) this._binding;
- if (wildcardBinding.boundKind != Wildcard.SUPER) return null;
- TypeBinding bound = wildcardBinding.bound;
- if (bound == null) return null;
- return this._env.getFactory().newTypeMirror(bound);
- }
-
- @Override
- public R accept(TypeVisitor v, P p) {
- return v.visitWildcard(this, p);
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java
deleted file mode 100644
index 4dcae6c..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2022 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.nio.file.Path;
-import java.util.Collection;
-import java.util.Locale;
-
-/**
- * Implementation of the Standard Java File Manager
- */
-public class EclipseFileManager extends org.eclipse.jdt.internal.compiler.tool.EclipseFileManager {
-
-
- public EclipseFileManager(Locale locale, Charset charset) {
- super(locale, charset);
- }
-
- @Override
- public Iterable extends File> getLocation(Location location) {
- /* XXX there are strange differences regarding module name handling with super class
- if (location instanceof LocationWrapper) {
- return getFiles(((LocationWrapper) location).getPaths());
- }
- LocationWrapper loc = this.locationHandler.getLocation(location, ""); //$NON-NLS-1$
- if (loc == null) {
- return null;
- }
- return getFiles(loc.getPaths());
- */
- return super.getLocation(location);
- }
-
- @Override
- public boolean hasLocation(Location location) {
- /* XXX there are strange differences regarding module name handling with super class
- try {
- return getLocationForModule(location, "") != null; //$NON-NLS-1$
- } catch (IOException e) {
- // nothing to do
- }
- return false;
- */
- return super.hasLocation(location);
- }
-
- @Override
- public void setLocation(Location location, Iterable extends File> files) throws IOException {
- /* XXX there are strange differences regarding module name handling with super class
- if (location.isOutputLocation() && files != null) {
- // output location
- int count = 0;
- for (Iterator extends File> iterator = files.iterator(); iterator.hasNext(); ) {
- iterator.next();
- count++;
- }
- if (count != 1) {
- throw new IllegalArgumentException("output location can only have one path");//$NON-NLS-1$
- }
- }
- this.locationHandler.setLocation(location, "", getPaths(files)); //$NON-NLS-1$
- */
- super.setLocation(location, files);
- }
-
- @Override
- public void setLocationForModule(Location location, String moduleName, Collection extends Path> paths) throws IOException {
- /* XXX there are strange differences regarding module name handling with super class
- validateModuleLocation(location, moduleName);
- this.locationHandler.setLocation(location, moduleName, paths);
- if (location == StandardLocation.MODULE_SOURCE_PATH) {
- LocationWrapper wrapper = this.locationHandler.getLocation(StandardLocation.CLASS_OUTPUT, moduleName);
- if (wrapper == null) {
- wrapper = this.locationHandler.getLocation(StandardLocation.CLASS_OUTPUT, ""); //$NON-NLS-1$
- if (wrapper != null) {
- Iterator extends Path> iterator = wrapper.getPaths().iterator();
- if (iterator.hasNext()) {
- // Per module output location is always a singleton list
- Path path = iterator.next().resolve(moduleName);
- this.locationHandler.setLocation(StandardLocation.CLASS_OUTPUT, moduleName, Collections.singletonList(path));
- }
- }
- }
- }
- */
- super.setLocationForModule(location, moduleName, paths);
- }
-}
diff --git a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/util/ManyToMany.java b/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/util/ManyToMany.java
deleted file mode 100644
index 623f3cf..0000000
--- a/compiler/src/main/ecj/org/eclipse/jdt/internal/compiler/apt/util/ManyToMany.java
+++ /dev/null
@@ -1,369 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2017 BEA Systems, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * wharley@bea.com - initial API and implementation
- * (originally in org.eclipse.jdt.apt.core)
- * IBM Corporation - Bug 513790
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.apt.util;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Manage a {@code Map>}, with reverse links so that it is possible to
- * efficiently find all T1s that have a particular T2 associated with them.
- * Access to the map is synchronized, so that it is possible to read and
- * write simultaneously from multiple threads.
- *
- * The map permits the null value for keys nor for value elements.
- *
- * Design invariants preserved by all operations on this map are as follows:
- *
- * If a key exists, it has at least one value associated with it; that is,
- * for all k such that null != containsKey(k), getValues(k) returns a non-empty
- * set.
- * If a value exists, it has at least one key associated with it; that is,
- * for all v such that null != containsValue(v), getKeys(v) returns a non-empty
- * set.
- *
- */
-public class ManyToMany {
-
- private final Map> _forward = new HashMap<>();
- private final Map