]> granicus.if.org Git - icu/commitdiff
ICU-20150 API status of equals()/hashCode() should match the ICU class's status ...
authorYoshito Umaoka <yumaoka@users.noreply.github.com>
Wed, 19 Sep 2018 23:02:49 +0000 (19:02 -0400)
committerShane Carr <shane@unicode.org>
Thu, 27 Sep 2018 21:27:41 +0000 (14:27 -0700)
- Updated API status of java.lang.Object method overrides (equals/hashCode/toString/clone) to match status of declaring class. There are some API comments that is insufficient, or incorrect, or not appropriate after the change. Most of these issues were fixed.

- APIStatusConsistencyChecker and ant tasks invoking the check, designed for checking this requirement. For now, Normalizer#clone() does not satisfy the requirement, but unchanged on purpose. The tool can accept exception.

- DeprecatedAPIChecker had a problem for handling non-static inner class's constructor. CodePointMap$StringIterator is the very first instance of such class in ICU4J. The problem was fixed by removing the implicit param scanned by reflection.

- This commit includes a lot of changes made by Eclipse project configuration - removing spaces in blank lines/end of statement, and removeal of redundant generics type declaration.

27 files changed:
icu4j/build.xml
icu4j/main/classes/collate/src/com/ibm/icu/text/CollationElementIterator.java
icu4j/main/classes/collate/src/com/ibm/icu/text/Collator.java
icu4j/main/classes/core/src/com/ibm/icu/lang/CharacterProperties.java
icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatter.java
icu4j/main/classes/core/src/com/ibm/icu/number/Precision.java
icu4j/main/classes/core/src/com/ibm/icu/number/ScientificNotation.java
icu4j/main/classes/core/src/com/ibm/icu/text/CurrencyPluralInfo.java
icu4j/main/classes/core/src/com/ibm/icu/text/DateIntervalInfo.java
icu4j/main/classes/core/src/com/ibm/icu/text/Edits.java
icu4j/main/classes/core/src/com/ibm/icu/text/MeasureFormat.java
icu4j/main/classes/core/src/com/ibm/icu/text/PluralRules.java
icu4j/main/classes/core/src/com/ibm/icu/text/RuleBasedNumberFormat.java
icu4j/main/classes/core/src/com/ibm/icu/text/SpoofChecker.java
icu4j/main/classes/core/src/com/ibm/icu/text/StringPrepParseException.java
icu4j/main/classes/core/src/com/ibm/icu/text/TimeUnitFormat.java
icu4j/main/classes/core/src/com/ibm/icu/util/ByteArrayWrapper.java
icu4j/main/classes/core/src/com/ibm/icu/util/CaseInsensitiveString.java
icu4j/main/classes/core/src/com/ibm/icu/util/CodePointMap.java
icu4j/main/classes/core/src/com/ibm/icu/util/MeasureUnit.java
icu4j/main/classes/core/src/com/ibm/icu/util/SimpleTimeZone.java
icu4j/main/classes/core/src/com/ibm/icu/util/TimeZone.java
icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java
icu4j/main/classes/core/src/com/ibm/icu/util/VersionInfo.java
icu4j/main/classes/translit/src/com/ibm/icu/text/Transliterator.java
icu4j/tools/build/src/com/ibm/icu/dev/tool/docs/APIStatusConsistencyChecker.java [new file with mode: 0644]
icu4j/tools/build/src/com/ibm/icu/dev/tool/docs/DeprecatedAPIChecker.java

index 2ceb623ad4a618cb2ae8dee8c4f5f3cc2c9da32e..a939d12724a3a800dfc32394da1e8d516364f323 100644 (file)
         </java>
     </target>
 
+    <target name="checkAPIStatusConsistency" depends="info, build-tools, gatherapi"
+        description="Check consistency between API class status and methods overriding java.lang.Object">
+        <!--
+            If you need classes excluded from this check, define followig property in build-local.properties.
+            e.g. checkAPIStatusConsistency.skip.classes=com.ibm.icu.text.Normalizer;com.ibm.icu.util.ULocale
+        -->
+        <property name="checkAPIStatusConsistency.skip.classes" value=""/>
+        <java classname="com.ibm.icu.dev.tool.docs.APIStatusConsistencyChecker"
+                failonerror="true">
+            <arg value="${out.dir}/icu4j${api.report.version}.api3.gz" />
+            <arg value="${checkAPIStatusConsistency.skip.classes}" />
+            <classpath>
+                <pathelement location="${icu4j.build-tools.jar}"/>
+                <pathelement location="${icu4j.core.jar}"/>
+                <pathelement location="${icu4j.collate.jar}"/>
+                <pathelement location="${icu4j.charset.jar}"/>
+                <pathelement location="${icu4j.currdata.jar}"/>
+                <pathelement location="${icu4j.langdata.jar}"/>
+                <pathelement location="${icu4j.regiondata.jar}"/>
+                <pathelement location="${icu4j.translit.jar}"/>
+            </classpath>
+        </java>
+    </target>
+
+    <target name="checkAPIStatus" depends="checkAPIStatusConsistency, checkDeprecated"/>
+
     <target name="draftAPIs" depends="info, gatherapi" description="Run API collector tool and generate draft API report in html">
         <java classname="com.ibm.icu.dev.tool.docs.CollectAPI"
                 classpath="${icu4j.build-tools.jar}"
index 1940fe34230e9b000976a760c07989b1bdbaa4da..5a3dba21368aaef005001cba0f9f876493f2b4c0 100644 (file)
@@ -624,7 +624,7 @@ public final class CollationElementIterator
     }
 
     static final Map<Integer, Integer> computeMaxExpansions(CollationData data) {
-        Map<Integer, Integer> maxExpansions = new HashMap<Integer, Integer>();
+        Map<Integer, Integer> maxExpansions = new HashMap<>();
         MaxExpSink sink = new MaxExpSink(maxExpansions);
         new ContractionsAndExpansions(null, null, sink, true).forData(data);
         return maxExpansions;
@@ -692,11 +692,9 @@ public final class CollationElementIterator
     /**
      * Mock implementation of hashCode(). This implementation always returns a constant
      * value. When Java assertion is enabled, this method triggers an assertion failure.
-     * @internal
-     * @deprecated This API is ICU internal only.
+     * @stable ICU 2.8
      */
     @Override
-    @Deprecated
     public int hashCode() {
         assert false : "hashCode not designed";
         return 42;
index 79889c4296f53035eaaf6fd37705074ecc1d93eb..fdbbf36f370b1150c791c00c96f31580bf3fc172 100644 (file)
@@ -329,7 +329,7 @@ public abstract class Collator implements Comparator<Object>, Freezable<Collator
      * Subclasses should override this implementation.
      *
      * @return a hash code value.
-     * @stable ICU 58
+     * @stable ICU 2.8
      */
     @Override
     public int hashCode() {
@@ -477,7 +477,7 @@ public abstract class Collator implements Comparator<Object>, Freezable<Collator
 
     /**
      * Clones the collator.
-     * @stable ICU 2.6
+     * @stable ICU 2.8
      * @return a clone of this collator.
      */
     @Override
@@ -1016,7 +1016,7 @@ public abstract class Collator implements Comparator<Object>, Freezable<Collator
     }
 
     private static final class KeywordsSink extends UResource.Sink {
-        LinkedList<String> values = new LinkedList<String>();
+        LinkedList<String> values = new LinkedList<>();
         boolean hasDefault = false;
 
         @Override
index ea597a7edf87d4b85f052a14dba26fbde4c52a7f..29a75a9e029ddc4004b51d70fb590a58223dec00 100644 (file)
@@ -112,6 +112,8 @@ public final class CharacterProperties {
      * @return the property as a set
      * @see UProperty
      * @see UCharacter#hasBinaryProperty
+     * @draft ICU 63
+     * @provisional This API might change or be removed in a future release.
      */
     public static final UnicodeSet getBinaryPropertySet(int property) {
         if (property < 0 || UProperty.BINARY_LIMIT <= property) {
@@ -141,6 +143,8 @@ public final class CharacterProperties {
      * @return the property as a map
      * @see UProperty
      * @see UCharacter#getIntPropertyValue
+     * @draft ICU 63
+     * @provisional This API might change or be removed in a future release.
      */
     public static final CodePointMap getIntPropertyMap(int property) {
         if (property < UProperty.INT_START || UProperty.INT_LIMIT <= property) {
index fa0322bffede42869982f13a17bb3cf840883f55..d5cccc49622a57bdd718ab88094fd1eec332d689 100644 (file)
@@ -175,6 +175,7 @@ public abstract class NumberRangeFormatter {
      *
      * @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining.
      * @draft ICU 63
+     * @provisional This API might change or be removed in a future release.
      */
     public static UnlocalizedNumberRangeFormatter with() {
         return BASE;
@@ -188,6 +189,7 @@ public abstract class NumberRangeFormatter {
      *            The locale from which to load formats and symbols for number range formatting.
      * @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining.
      * @draft ICU 63
+     * @provisional This API might change or be removed in a future release.
      */
     public static LocalizedNumberRangeFormatter withLocale(Locale locale) {
         return BASE.locale(locale);
@@ -201,9 +203,15 @@ public abstract class NumberRangeFormatter {
      *            The locale from which to load formats and symbols for number range formatting.
      * @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining.
      * @draft ICU 63
+     * @provisional This API might change or be removed in a future release.
      */
     public static LocalizedNumberRangeFormatter withLocale(ULocale locale) {
         return BASE.locale(locale);
     }
 
+    /**
+     * Private constructor - this class is not designed for instantiation
+     */
+    private NumberRangeFormatter() {
+    }
 }
index 974bd7cdb0216e19761cfc204c774d353f48b01e..375b535b90ed45a75f85bd75afa74e67f905b7b6 100644 (file)
@@ -408,10 +408,10 @@ public abstract class Precision implements Cloneable {
     }
 
     /**
-     * @internal
-     * @deprecated This API is ICU internal only.
+     * {@inheritDoc}
+     * @draft ICU 62
+     * @provisional This API might change or be removed in a future release.
      */
-    @Deprecated
     @Override
     public Object clone() {
         try {
index bd0c723b859483f3e895bf928ca5576657226a54..0f2f0e7d21a5180600343a7c7df1b56b0520f19f 100644 (file)
@@ -93,10 +93,9 @@ public class ScientificNotation extends Notation implements Cloneable {
     }
 
     /**
-     * @internal
-     * @deprecated This API is ICU internal only.
+     * @draft ICU 60
+     * @provisional This API might change or be removed in a future release.
      */
-    @Deprecated
     @Override
     public Object clone() {
         try {
index afc0c2ec4ea97e210a63e157513cf8e890e79bc7..25c0e1c2e4af08323369bc045a50bce4cbffb75c 100644 (file)
@@ -202,7 +202,7 @@ public class CurrencyPluralInfo implements Cloneable, Serializable {
             //other.pluralRules = pluralRules;
             // clone content
             //other.pluralCountToCurrencyUnitPattern = pluralCountToCurrencyUnitPattern;
-            other.pluralCountToCurrencyUnitPattern = new HashMap<String, String>();
+            other.pluralCountToCurrencyUnitPattern = new HashMap<>();
             for (String pluralCount : pluralCountToCurrencyUnitPattern.keySet()) {
                 String currencyPattern = pluralCountToCurrencyUnitPattern.get(pluralCount);
                 other.pluralCountToCurrencyUnitPattern.put(pluralCount, currencyPattern);
@@ -231,11 +231,9 @@ public class CurrencyPluralInfo implements Cloneable, Serializable {
     /**
      * Override hashCode
      *
-     * @internal
-     * @deprecated This API is ICU internal only.
+     * @stable ICU 4.2
      */
     @Override
-    @Deprecated
     public int hashCode() {
       return pluralCountToCurrencyUnitPattern.hashCode()
           ^ pluralRules.hashCode()
@@ -283,7 +281,7 @@ public class CurrencyPluralInfo implements Cloneable, Serializable {
     }
 
     private void setupCurrencyPluralPattern(ULocale uloc) {
-        pluralCountToCurrencyUnitPattern = new HashMap<String, String>();
+        pluralCountToCurrencyUnitPattern = new HashMap<>();
 
         String numberStylePattern = NumberFormat.getPattern(uloc, NumberFormat.NUMBERSTYLE);
         // Split the number style pattern into pos and neg if applicable
index baa79b09695e20b4fcf93318015089da102589bf..a72da77a473aef7a885b2752a9e37390ad44dca1 100644 (file)
@@ -273,10 +273,8 @@ public class DateIntervalInfo implements Cloneable, Freezable<DateIntervalInfo>,
 
         /**
          * {@inheritDoc}
-         * @internal
-         * @deprecated This API is ICU internal only.
+         * @stable ICU 4.0
          */
-        @Deprecated
         @Override
         public String toString() {
             return "{first=«" + fIntervalPatternFirstPart + "», second=«" + fIntervalPatternSecondPart + "», reversed:" + fFirstDateInPtnIsLaterDate + "}";
index b97d54f00790ff5aa2f9b58b1f62a6921cc9e76d..89b46478744b1ae025ed77c54b692242432de970 100644 (file)
@@ -821,7 +821,8 @@ public final class Edits {
         /**
          * A string representation of the current edit represented by the iterator for debugging. You
          * should not depend on the contents of the return string; it may change over time.
-         * @internal
+         * @return a string representation of the object.
+         * @stable ICU 59
          */
         @Override
         public String toString() {
index 175d92e8d40ab8702a1033f1d559756be14e80d1..df13519c30670747af72a919a9886657b38a44ee 100644 (file)
@@ -126,9 +126,9 @@ public class MeasureFormat extends UFormat {
 
     private final transient LocalizedNumberFormatter numberFormatter;
 
-    private static final SimpleCache<ULocale, NumericFormatters> localeToNumericDurationFormatters = new SimpleCache<ULocale, NumericFormatters>();
+    private static final SimpleCache<ULocale, NumericFormatters> localeToNumericDurationFormatters = new SimpleCache<>();
 
-    private static final Map<MeasureUnit, Integer> hmsTo012 = new HashMap<MeasureUnit, Integer>();
+    private static final Map<MeasureUnit, Integer> hmsTo012 = new HashMap<>();
 
     static {
         hmsTo012.put(MeasureUnit.HOUR, 0);
@@ -486,7 +486,7 @@ public class MeasureFormat extends UFormat {
      * Two MeasureFormats, a and b, are equal if and only if they have the same formatWidth, locale, and
      * equal number formats.
      *
-     * @stable ICU 53
+     * @stable ICU 3.0
      */
     @Override
     public final boolean equals(Object other) {
@@ -506,7 +506,7 @@ public class MeasureFormat extends UFormat {
     /**
      * {@inheritDoc}
      *
-     * @stable ICU 53
+     * @stable ICU 3.0
      */
     @Override
     public final int hashCode() {
@@ -997,7 +997,7 @@ public class MeasureFormat extends UFormat {
             this.formatWidth = width;
             this.numberFormat = numberFormat;
             this.subClass = subClass;
-            this.keyValues = new HashMap<Object, Object>();
+            this.keyValues = new HashMap<>();
         }
 
         // Must have public constructor, to enable Externalizable
@@ -1070,7 +1070,7 @@ public class MeasureFormat extends UFormat {
         return values[ordinal];
     }
 
-    private static final Map<ULocale, String> localeIdToRangeFormat = new ConcurrentHashMap<ULocale, String>();
+    private static final Map<ULocale, String> localeIdToRangeFormat = new ConcurrentHashMap<>();
 
     /**
      * Return a formatter (compiled SimpleFormatter pattern) for a range, such as "{0}–{1}".
index d384c89426d866e84458b3485e1ba38f8d997033..2a6ab6f9f45a395a4e87496c500d834d25c64cd6 100644 (file)
@@ -1084,7 +1084,7 @@ public class PluralRules implements Serializable {
             SampleType sampleType2;
             boolean bounded2 = true;
             boolean haveBound = false;
-            Set<FixedDecimalRange> samples2 = new LinkedHashSet<FixedDecimalRange>();
+            Set<FixedDecimalRange> samples2 = new LinkedHashSet<>();
 
             if (source.startsWith("integer")) {
                 sampleType2 = SampleType.INTEGER;
@@ -1215,7 +1215,7 @@ public class PluralRules implements Serializable {
         static final UnicodeSet BREAK_AND_KEEP = new UnicodeSet('!', '!', '%', '%', ',', ',', '.', '.', '=', '=').freeze();
         static String[] split(String source) {
             int last = -1;
-            List<String> result = new ArrayList<String>();
+            List<String> result = new ArrayList<>();
             for (int i = 0; i < source.length(); ++i) {
                 char ch = source.charAt(i);
                 if (BREAK_AND_IGNORE.contains(ch)) {
@@ -1334,7 +1334,7 @@ public class PluralRules implements Serializable {
                         t = nextToken(tokens, x++, condition);
                     }
 
-                    List<Long> valueList = new ArrayList<Long>();
+                    List<Long> valueList = new ArrayList<>();
 
                     // the token t is always one item ahead
                     while (true) {
@@ -1756,10 +1756,9 @@ public class PluralRules implements Serializable {
         }
 
         /**
-         * @internal
-         * @deprecated This API is ICU internal only.
+         * {@inheritDoc}
+         * @stable ICU 3.8
          */
-        @Deprecated
         @Override
         public int hashCode() {
             return keyword.hashCode() ^ constraint.hashCode();
@@ -1773,7 +1772,7 @@ public class PluralRules implements Serializable {
     private static class RuleList implements Serializable {
         private boolean hasExplicitBoundingInfo = false;
         private static final long serialVersionUID = 1;
-        private final List<Rule> rules = new ArrayList<Rule>();
+        private final List<Rule> rules = new ArrayList<>();
 
         public RuleList addRule(Rule nextRule) {
             String keyword = nextRule.getKeyword();
@@ -1821,7 +1820,7 @@ public class PluralRules implements Serializable {
         }
 
         public Set<String> getKeywords() {
-            Set<String> result = new LinkedHashSet<String>();
+            Set<String> result = new LinkedHashSet<>();
             for (Rule rule : rules) {
                 result.add(rule.getKeyword());
             }
@@ -2020,10 +2019,9 @@ public class PluralRules implements Serializable {
     }
 
     /**
-     * @internal
-     * @deprecated This API is ICU internal only.
+     * {@inheritDoc}
+     * @stable ICU 3.8
      */
-    @Deprecated
     @Override
     public int hashCode() {
         return rules.hashCode();
@@ -2175,7 +2173,7 @@ public class PluralRules implements Serializable {
         if (!keywords.contains(keyword)) {
             return null;
         }
-        Set<Double> result = new TreeSet<Double>();
+        Set<Double> result = new TreeSet<>();
 
         if (rules.hasExplicitBoundingInfo) {
             FixedDecimalSamples samples = rules.getDecimalSamples(keyword, sampleType);
@@ -2420,7 +2418,7 @@ public class PluralRules implements Serializable {
 
         // Compute if the quick test is insufficient.
 
-        HashSet<Double> subtractedSet = new HashSet<Double>(values);
+        HashSet<Double> subtractedSet = new HashSet<>(values);
         for (Double explicit : explicits) {
             subtractedSet.remove(explicit - offset);
         }
index 719fefb07711d43e8b74d64005c45f9cb0dc27dc..dbab3142162616eee7ee2f7d0e14c29c23ce8d90 100644 (file)
@@ -941,13 +941,10 @@ public class RuleBasedNumberFormat extends NumberFormat {
     }
 
     /**
-     * Mock implementation of hashCode(). This implementation always returns a constant
-     * value. When Java assertion is enabled, this method triggers an assertion failure.
-     * @internal
-     * @deprecated This API is ICU internal only.
+     * {@inheritDoc}
+     * @stable ICU 2.0
      */
     @Override
-    @Deprecated
     public int hashCode() {
         return super.hashCode();
     }
@@ -1731,7 +1728,7 @@ public class RuleBasedNumberFormat extends NumberFormat {
 
         // our rule list is an array of the appropriate size
         ruleSets = new NFRuleSet[numRuleSets];
-        ruleSetsMap = new HashMap<String, NFRuleSet>(numRuleSets * 2 + 1);
+        ruleSetsMap = new HashMap<>(numRuleSets * 2 + 1);
         defaultRuleSet = null;
 
         // Used to count the number of public rule sets
@@ -1844,7 +1841,7 @@ public class RuleBasedNumberFormat extends NumberFormat {
         if (localizations != null) {
             publicRuleSetNames = localizations[0].clone();
 
-            Map<String, String[]> m = new HashMap<String, String[]>();
+            Map<String, String[]> m = new HashMap<>();
             for (int i = 1; i < localizations.length; ++i) {
                 String[] data = localizations[i];
                 String loc = data[0];
index 53ab8b0d80ca648f61564aa53232aff4921d057e..ca1015d7d139ac656a1253cd15fbf8f9543e629b 100644 (file)
@@ -506,7 +506,7 @@ public class SpoofChecker {
         SpoofData fSpoofData;
         final UnicodeSet fAllowedCharsSet = new UnicodeSet(0, 0x10ffff); // The UnicodeSet of allowed characters.
         // for this Spoof Checker. Defaults to all chars.
-        final Set<ULocale> fAllowedLocales = new LinkedHashSet<ULocale>(); // The list of allowed locales.
+        final Set<ULocale> fAllowedLocales = new LinkedHashSet<>(); // The list of allowed locales.
         private RestrictionLevel fRestrictionLevel;
 
         /**
@@ -567,7 +567,7 @@ public class SpoofChecker {
             result.fSpoofData = this.fSpoofData;
             result.fAllowedCharsSet = (UnicodeSet) (this.fAllowedCharsSet.clone());
             result.fAllowedCharsSet.freeze();
-            result.fAllowedLocales = new HashSet<ULocale>(this.fAllowedLocales);
+            result.fAllowedLocales = new HashSet<>(this.fAllowedLocales);
             result.fRestrictionLevel = this.fRestrictionLevel;
             return result;
         }
@@ -734,7 +734,7 @@ public class SpoofChecker {
          * @stable ICU 54
          */
         public Builder setAllowedJavaLocales(Set<Locale> locales) {
-            HashSet<ULocale> ulocales = new HashSet<ULocale>(locales.size());
+            HashSet<ULocale> ulocales = new HashSet<>(locales.size());
             for (Locale locale : locales) {
                 ulocales.add(ULocale.forLocale(locale));
             }
@@ -848,10 +848,10 @@ public class SpoofChecker {
             private int fLineNum;
 
             ConfusabledataBuilder() {
-                fTable = new Hashtable<Integer, SPUString>();
+                fTable = new Hashtable<>();
                 fKeySet = new UnicodeSet();
-                fKeyVec = new ArrayList<Integer>();
-                fValueVec = new ArrayList<Integer>();
+                fKeyVec = new ArrayList<>();
+                fValueVec = new ArrayList<>();
                 stringPool = new SPUStringPool();
             }
 
@@ -1093,8 +1093,8 @@ public class SpoofChecker {
             // combination of a uhash and a Vector.
             private static class SPUStringPool {
                 public SPUStringPool() {
-                    fVec = new Vector<SPUString>();
-                    fHash = new Hashtable<String, SPUString>();
+                    fVec = new Vector<>();
+                    fHash = new Hashtable<>();
                 }
 
                 public int size() {
@@ -1179,7 +1179,7 @@ public class SpoofChecker {
      * @stable ICU 54
      */
     public Set<Locale> getAllowedJavaLocales() {
-        HashSet<Locale> locales = new HashSet<Locale>(fAllowedLocales.size());
+        HashSet<Locale> locales = new HashSet<>(fAllowedLocales.size());
         for (ULocale uloc : fAllowedLocales) {
             locales.add(uloc.toLocale());
         }
@@ -1535,7 +1535,7 @@ public class SpoofChecker {
      * @param other
      *            the SpoofChecker being compared with.
      * @return true if the two SpoofCheckers are equal.
-     * @stable ICU 58
+     * @stable ICU 4.6
      */
     @Override
     public boolean equals(Object other) {
@@ -1565,7 +1565,7 @@ public class SpoofChecker {
 
     /**
      * Overrides {@link Object#hashCode()}.
-     * @stable ICU 58
+     * @stable ICU 4.6
      */
     @Override
     public int hashCode() {
index 1a73c8620986f74689d10a849c3ecf7f573db2b3..2b2a91124ad9fb117e3cac62ac03ec838f7bd40f 100644 (file)
@@ -143,11 +143,10 @@ public class StringPrepParseException extends ParseException {
     /**
      * Mock implementation of hashCode(). This implementation always returns a constant
      * value. When Java assertion is enabled, this method triggers an assertion failure.
-     * @internal
-     * @deprecated This API is ICU internal only.
+     * @return a hash code value for this object.
+     * @stable ICU 2.8
      */
     @Override
-    @Deprecated
     public int hashCode() {
         assert false : "hashCode not designed";
         return 42;
index 70a974ea85fd516410f49abd46daaf4f1de55d00..08c7dc4e18ef8416f55d60ea257871cf05d3e435 100644 (file)
@@ -343,7 +343,7 @@ public class TimeUnitFormat extends MeasureFormat {
             format = NumberFormat.getNumberInstance(locale);
         }
         pluralRules = PluralRules.forLocale(locale);
-        timeUnitToCountToPatterns = new HashMap<TimeUnit, Map<String, Object[]>>();
+        timeUnitToCountToPatterns = new HashMap<>();
         Set<String> pluralKeywords = pluralRules.getKeywords();
         setup("units/duration", timeUnitToCountToPatterns, FULL_NAME, pluralKeywords);
         setup("unitsShort/duration", timeUnitToCountToPatterns, ABBREVIATED_NAME, pluralKeywords);
@@ -400,7 +400,7 @@ public class TimeUnitFormat extends MeasureFormat {
 
                 Map<String, Object[]> countToPatterns = timeUnitToCountToPatterns.get(timeUnit);
                 if (countToPatterns == null) {
-                    countToPatterns = new TreeMap<String, Object[]>();
+                    countToPatterns = new TreeMap<>();
                     timeUnitToCountToPatterns.put(timeUnit, countToPatterns);
                 }
 
@@ -467,7 +467,7 @@ public class TimeUnitFormat extends MeasureFormat {
             final TimeUnit timeUnit = timeUnits[i];
             Map<String, Object[]> countToPatterns = timeUnitToCountToPatterns.get(timeUnit);
             if (countToPatterns == null) {
-                countToPatterns = new TreeMap<String, Object[]>();
+                countToPatterns = new TreeMap<>();
                 timeUnitToCountToPatterns.put(timeUnit, countToPatterns);
             }
             for (String pluralCount : keywords) {
@@ -556,8 +556,7 @@ public class TimeUnitFormat extends MeasureFormat {
     // MeasureFormat
 
     /**
-     * @internal
-     * @deprecated This API is ICU internal only.
+     * @deprecated ICU 53 see {@link MeasureFormat}
      */
     @Deprecated
     @Override
index ba1fd42a24cdc2eda2d1a9e77af5fff7f8a21bb9..e39fdd07cfe12a1246ff22b8d6699af716168876 100644 (file)
@@ -26,7 +26,7 @@ import com.ibm.icu.impl.Utility;
 public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
 {
     // public data member ------------------------------------------------
-    
+
     /**
      * Internal byte array.
      * @stable ICU 2.8
@@ -34,16 +34,16 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
     public byte[] bytes;
 
     /**
-     * Size of the internal byte array used. 
-     * Different from bytes.length, size will be &lt;= bytes.length. 
+     * Size of the internal byte array used.
+     * Different from bytes.length, size will be &lt;= bytes.length.
      * Semantics of size is similar to java.util.Vector.size().
      * @stable ICU 2.8
      */
     public int size;
-    
+
     // public constructor ------------------------------------------------
 
-    /** 
+    /**
      * Construct a new ByteArrayWrapper with no data.
      * @stable ICU 2.8
      */
@@ -103,15 +103,15 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
     // public methods ----------------------------------------------------
 
     /**
-     * Ensure that the internal byte array is at least of length capacity.     
-     * If the byte array is null or its length is less than capacity, a new 
-     * byte array of length capacity will be allocated.  
-     * The contents of the array (between 0 and size) remain unchanged. 
+     * Ensure that the internal byte array is at least of length capacity.
+     * If the byte array is null or its length is less than capacity, a new
+     * byte array of length capacity will be allocated.
+     * The contents of the array (between 0 and size) remain unchanged.
      * @param capacity minimum length of internal byte array.
      * @return this ByteArrayWrapper
      * @stable ICU 3.2
      */
-    public ByteArrayWrapper ensureCapacity(int capacity) 
+    public ByteArrayWrapper ensureCapacity(int capacity)
     {
         if (bytes == null || bytes.length < capacity) {
             byte[] newbytes = new byte[capacity];
@@ -122,11 +122,11 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
         }
         return this;
     }
-    
+
     /**
-     * Set the internal byte array from offset 0 to (limit - start) with the 
-     * contents of src from offset start to limit. If the byte array is null or its length is less than capacity, a new 
-     * byte array of length (limit - start) will be allocated.  
+     * Set the internal byte array from offset 0 to (limit - start) with the
+     * contents of src from offset start to limit. If the byte array is null or its length is less than capacity, a new
+     * byte array of length (limit - start) will be allocated.
      * This resets the size of the internal byte array to (limit - start).
      * @param src source byte array to copy from
      * @param start start offset of src to copy from
@@ -134,15 +134,15 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
      * @return this ByteArrayWrapper
      * @stable ICU 3.2
      */
-    public final ByteArrayWrapper set(byte[] src, int start, int limit) 
+    public final ByteArrayWrapper set(byte[] src, int start, int limit)
     {
         size = 0;
         append(src, start, limit);
         return this;
     }
-    
+
     /*
-    public final ByteArrayWrapper get(byte[] target, int start, int limit) 
+    public final ByteArrayWrapper get(byte[] target, int start, int limit)
     {
         int len = limit - start;
         if (len > size) throw new IllegalArgumentException("limit too long");
@@ -152,7 +152,7 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
     */
 
     /**
-     * Appends the internal byte array from offset size with the 
+     * Appends the internal byte array from offset size with the
      * contents of src from offset start to limit. This increases the size of
      * the internal byte array to (size + limit - start).
      * @param src source byte array to copy from
@@ -161,7 +161,7 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
      * @return this ByteArrayWrapper
      * @stable ICU 3.2
      */
-    public final ByteArrayWrapper append(byte[] src, int start, int limit) 
+    public final ByteArrayWrapper append(byte[] src, int start, int limit)
     {
         int len = limit - start;
         ensureCapacity(size + len);
@@ -171,7 +171,7 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
     }
 
     /*
-    public final ByteArrayWrapper append(ByteArrayWrapper other) 
+    public final ByteArrayWrapper append(ByteArrayWrapper other)
     {
         return append(other.bytes, 0, other.size);
     }
@@ -190,13 +190,14 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
         size = 0;
         return result;
     }
-    
+
     // Boilerplate ----------------------------------------------------
-    
+
     /**
      * Returns string value for debugging
-     * @stable ICU 3.2
+     * @stable ICU 2.8
      */
+    @Override
     public String toString() {
         StringBuilder result = new StringBuilder();
         for (int i = 0; i < size; ++i) {
@@ -210,8 +211,9 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
      * Return true if the bytes in each wrapper are equal.
      * @param other the object to compare to.
      * @return true if the two objects are equal.
-     * @stable ICU 3.2
+     * @stable ICU 2.8
      */
+    @Override
     public boolean equals(Object other) {
         if (this == other) return true;
         if (other == null) return false;
@@ -231,8 +233,9 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
     /**
      * Return the hashcode.
      * @return the hashcode.
-     * @stable ICU 3.2
+     * @stable ICU 2.8
      */
+    @Override
     public int hashCode() {
         int result = bytes.length;
         for (int i = 0; i < size; ++i) {
@@ -249,6 +252,7 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
      * @throws ClassCastException if the other object is not a ByteArrayWrapper
      * @stable ICU 4.4
      */
+    @Override
     public int compareTo(ByteArrayWrapper other) {
         if (this == other) return 0;
         int minSize = size < other.size ? size : other.size;
@@ -259,11 +263,11 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
         }
         return size - other.size;
     }
-    
+
     // private methods -----------------------------------------------------
-    
+
     /**
-     * Copies the contents of src byte array from offset srcoff to the 
+     * Copies the contents of src byte array from offset srcoff to the
      * target of tgt byte array at the offset tgtoff.
      * @param src source byte array to copy from
      * @param srcoff start offset of src to copy from
@@ -271,15 +275,15 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
      * @param tgtoff start offset of tgt to copy to
      * @param length size of contents to copy
      */
-    private static final void copyBytes(byte[] src, int srcoff, byte[] tgt, 
+    private static final void copyBytes(byte[] src, int srcoff, byte[] tgt,
                                        int tgtoff, int length) {
         if (length < 64) {
             for (int i = srcoff, n = tgtoff; -- length >= 0; ++ i, ++ n) {
                 tgt[n] = src[i];
             }
-        } 
+        }
         else {
             System.arraycopy(src, srcoff, tgt, tgtoff, length);
         }
-    }      
+    }
 }
index ff0ba2957b8748ba8cb67b9b0b571c10f9bc3eb0..8ecf7c32dbe8207de1d53cb94236c9780d24e5ad 100644 (file)
@@ -17,35 +17,35 @@ import com.ibm.icu.lang.UCharacter;
  * @stable ICU 2.0
  */
 public class CaseInsensitiveString {
-    
+
     private String string;
 
     private int hash = 0;
-    
+
     private String folded = null;
-    
+
     private static String foldCase(String foldee)
     {
         return UCharacter.foldCase(foldee, true);
     }
-    
+
     private void getFolded()
     {
         if (folded == null) {
             folded = foldCase(string);
         }
     }
-    
+
     /**
      * Constructs an CaseInsentiveString object from the given string
-     * @param s The string to construct this object from 
+     * @param s The string to construct this object from
      * @stable ICU 2.0
      */
     public CaseInsensitiveString(String s) {
         string = s;
     }
     /**
-     * returns the underlying string 
+     * returns the underlying string
      * @return String
      * @stable ICU 2.0
      */
@@ -53,10 +53,11 @@ public class CaseInsensitiveString {
         return string;
     }
     /**
-     * Compare the object with this 
-     * @param o Object to compare this object with 
+     * Compare the object with this
+     * @param o Object to compare this object with
      * @stable ICU 2.0
      */
+    @Override
     public boolean equals(Object o) {
         if (o == null) {
             return false;
@@ -72,26 +73,29 @@ public class CaseInsensitiveString {
         }
         return false;
     }
-    
+
     /**
      * Returns the hashCode of this object
      * @return int hashcode
      * @stable ICU 2.0
      */
+    @Override
     public int hashCode() {
         getFolded();
-        
+
         if (hash == 0) {
             hash = folded.hashCode();
         }
-        
+
         return hash;
     }
-    
+
     /**
      * Overrides superclass method
-     * @stable ICU 3.6
+     * @return a string representation of the object.
+     * @stable ICU 2.0
      */
+    @Override
     public String toString() {
         return string;
     }
index ffc60a3434b01b800d8be01c7c76052f254727c6..7277053bd8a6b6c7e346c7f6957e6ca56b80195d 100644 (file)
@@ -316,6 +316,15 @@ public abstract class CodePointMap implements Iterable<CodePointMap.Range> {
         public final int getValue() { return value; }
     }
 
+    /**
+     * Protected no-args constructor.
+     *
+     * @draft ICU 63
+     * @provisional This API might change or be removed in a future release.
+     */
+    protected CodePointMap() {
+    }
+
     /**
      * Returns the value for a code point as stored in the map, with range checking.
      * Returns an implementation-defined error value if c is not in the range 0..U+10FFFF.
index a4dedc72d0968af93bc40d40df160fd83ce13d76..5fb8e0bac1b51eca39c502d3870f296ba4baebce 100644 (file)
@@ -44,7 +44,7 @@ public class MeasureUnit implements Serializable {
     // All access to the cache or cacheIsPopulated flag must be synchronized on class MeasureUnit,
     // i.e. from synchronized static methods. Beware of non-static methods.
     private static final Map<String, Map<String,MeasureUnit>> cache
-        = new HashMap<String, Map<String,MeasureUnit>>();
+        = new HashMap<>();
     private static boolean cacheIsPopulated = false;
 
     /**
@@ -95,7 +95,7 @@ public class MeasureUnit implements Serializable {
     /**
      * {@inheritDoc}
      *
-     * @stable ICU 53
+     * @stable ICU 3.0
      */
     @Override
     public int hashCode() {
@@ -105,7 +105,7 @@ public class MeasureUnit implements Serializable {
     /**
      * {@inheritDoc}
      *
-     * @stable ICU 53
+     * @stable ICU 3.0
      */
     @Override
     public boolean equals(Object rhs) {
@@ -122,7 +122,7 @@ public class MeasureUnit implements Serializable {
     /**
      * {@inheritDoc}
      *
-     * @stable ICU 53
+     * @stable ICU 3.0
      */
     @Override
     public String toString() {
@@ -152,7 +152,7 @@ public class MeasureUnit implements Serializable {
         // flexibility for implementation.
         // Use CollectionSet instead of HashSet for better performance.
         return units == null ? Collections.<MeasureUnit>emptySet()
-                : Collections.unmodifiableSet(new CollectionSet<MeasureUnit>(units.values()));
+                : Collections.unmodifiableSet(new CollectionSet<>(units.values()));
     }
 
     /**
@@ -161,8 +161,8 @@ public class MeasureUnit implements Serializable {
      * @stable ICU 53
      */
     public synchronized static Set<MeasureUnit> getAvailable() {
-        Set<MeasureUnit> result = new HashSet<MeasureUnit>();
-        for (String type : new HashSet<String>(MeasureUnit.getAvailableTypes())) {
+        Set<MeasureUnit> result = new HashSet<>();
+        for (String type : new HashSet<>(MeasureUnit.getAvailableTypes())) {
             for (MeasureUnit unit : MeasureUnit.getAvailable(type)) {
                 result.add(unit);
             }
@@ -348,7 +348,7 @@ public class MeasureUnit implements Serializable {
     protected synchronized static MeasureUnit addUnit(String type, String unitName, Factory factory) {
         Map<String, MeasureUnit> tmp = cache.get(type);
         if (tmp == null) {
-            cache.put(type, tmp = new HashMap<String, MeasureUnit>());
+            cache.put(type, tmp = new HashMap<>());
         } else {
             // "intern" the type by setting to first item's type.
             type = tmp.entrySet().iterator().next().getValue().type;
@@ -1184,7 +1184,7 @@ public class MeasureUnit implements Serializable {
     public static final MeasureUnit TEASPOON = MeasureUnit.internalGetInstance("volume", "teaspoon");
 
     private static HashMap<Pair<MeasureUnit, MeasureUnit>, MeasureUnit>unitPerUnitToSingleUnit =
-            new HashMap<Pair<MeasureUnit, MeasureUnit>, MeasureUnit>();
+            new HashMap<>();
 
     static {
         unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.LITER, MeasureUnit.KILOMETER), MeasureUnit.LITER_PER_KILOMETER);
index 94dc82292af0d0d3490e26b40a64177e0be1350a..09f47ff99f376af1d3fbe917c1c3b931d59efc5d 100644 (file)
@@ -612,7 +612,7 @@ public class SimpleTimeZone extends BasicTimeZone {
     /**
      * Returns a string representation of this object.
      * @return  a string representation of this object
-     * @stable ICU 3.6
+     * @stable ICU 2.0
      */
     @Override
     public String toString() {
@@ -1140,7 +1140,7 @@ public class SimpleTimeZone extends BasicTimeZone {
     /**
      * Overrides equals.
      * @return true if obj is a SimpleTimeZone equivalent to this
-     * @stable ICU 3.6
+     * @stable ICU 2.0
      */
     @Override
     public boolean equals(Object obj){
@@ -1180,7 +1180,8 @@ public class SimpleTimeZone extends BasicTimeZone {
 
     /**
      * Overrides hashCode.
-     * @stable ICU 3.6
+     * @return a hash code value for this object.
+     * @stable ICU 2.0
      */
     @Override
     public int hashCode(){
@@ -1208,7 +1209,7 @@ public class SimpleTimeZone extends BasicTimeZone {
 
     /**
      * Overrides clone.
-     * @stable ICU 3.6
+     * @stable ICU 2.0
      */
     @Override
     public Object clone() {
index c7a2e8d545b57d465f9657cdbcc85cbcb60bdbd0..cea2babe5c71f7e25f407b1f18342ea08dd96430 100644 (file)
@@ -1052,7 +1052,8 @@ abstract public class TimeZone implements Serializable, Cloneable, Freezable<Tim
 
     /**
      * Overrides equals.
-     * @stable ICU 3.6
+     * @return <code>true</code> if this object is the same as the obj argument; <code>false</code> otherwise.
+     * @stable ICU 2.0
      */
     @Override
     public boolean equals(Object obj){
@@ -1063,7 +1064,8 @@ abstract public class TimeZone implements Serializable, Cloneable, Freezable<Tim
 
     /**
      * Overrides hashCode.
-     * @stable ICU 3.6
+     * @return a hash code value for this object.
+     * @stable ICU 2.0
      */
     @Override
     public int hashCode(){
index 2ec08ff73a9ab3e222e552073cf88afbaaef2f0f..11bf41dbb97b67bfa5a27b14b4e78eec80af8462 100644 (file)
@@ -668,7 +668,7 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
     /**
      * This is for compatibility with Locale-- in actuality, since ULocale is
      * immutable, there is no reason to clone it, so this API returns 'this'.
-     * @stable ICU 3.0
+     * @stable ICU 2.8
      */
     @Override
     public Object clone() {
@@ -677,7 +677,8 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
 
     /**
      * Returns the hashCode.
-     * @stable ICU 3.0
+     * @return a hash code value for this object.
+     * @stable ICU 2.8
      */
     @Override
     public int hashCode() {
@@ -691,7 +692,7 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
      * function identically might not compare equal.
      *
      * @return true if this Locale is equal to the specified object.
-     * @stable ICU 3.0
+     * @stable ICU 2.8
      */
     @Override
     public boolean equals(Object obj) {
@@ -1071,7 +1072,8 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
 
     /**
      * Returns a string representation of this object.
-     * @stable ICU 3.0
+     * @return a string representation of the object.
+     * @stable ICU 2.8
      */
     @Override
     public String toString() {
index e57a1737da8a2b79cf41c6f74a0001aaaac53cde..18c10eacf42d6df49edab89dfdfda42d69c4c19a 100644 (file)
@@ -482,7 +482,7 @@ public final class VersionInfo implements Comparable<VersionInfo>
      *
      * @return the hash code value for this set.
      * @see java.lang.Object#hashCode()
-     * @stable ICU 58
+     * @stable ICU 2.6
      */
     @Override
     public int hashCode() {
@@ -527,7 +527,7 @@ public final class VersionInfo implements Comparable<VersionInfo>
     /**
      * Map of singletons
      */
-    private static final ConcurrentHashMap<Integer, VersionInfo> MAP_ = new ConcurrentHashMap<Integer, VersionInfo>();
+    private static final ConcurrentHashMap<Integer, VersionInfo> MAP_ = new ConcurrentHashMap<>();
     /**
      * Last byte mask
      */
index 3d7a7e75316f5a6d897866f990aac79955becd98..b8f82558e27d2212ddfcb79071b9dc354f57a1a9 100644 (file)
@@ -358,7 +358,7 @@ public abstract class Transliterator implements StringTransform  {
 
         /**
          * Returns true if this Position is equal to the given object.
-         * @stable ICU 2.6
+         * @stable ICU 2.0
          */
         @Override
         public boolean equals(Object obj) {
@@ -373,7 +373,8 @@ public abstract class Transliterator implements StringTransform  {
         }
 
         /**
-         * @draft ICU 63
+         * {@inheritDoc}
+         * @stable ICU 2.0
          */
         @Override
         public int hashCode() {
@@ -382,7 +383,8 @@ public abstract class Transliterator implements StringTransform  {
 
         /**
          * Returns a string representation of this Position.
-         * @stable ICU 2.6
+         * @return a string representation of the object.
+         * @stable ICU 2.0
          */
         @Override
         public String toString() {
@@ -1343,7 +1345,7 @@ public abstract class Transliterator implements StringTransform  {
     public static Transliterator getInstance(String ID,
                                              int dir) {
         StringBuffer canonID = new StringBuffer();
-        List<SingleID> list = new ArrayList<SingleID>();
+        List<SingleID> list = new ArrayList<>();
         UnicodeSet[] globalFilter = new UnicodeSet[1];
         if (!TransliteratorIDParser.parseCompoundID(ID, dir, canonID, list, globalFilter)) {
             throw new IllegalArgumentException("Invalid ID " + ID);
@@ -1435,7 +1437,7 @@ public abstract class Transliterator implements StringTransform  {
             }
         }
         else {
-            List<Transliterator> transliterators = new ArrayList<Transliterator>();
+            List<Transliterator> transliterators = new ArrayList<>();
             int passNumber = 1;
 
             int limit = Math.max(parser.idBlockVector.size(), parser.dataVector.size());
diff --git a/icu4j/tools/build/src/com/ibm/icu/dev/tool/docs/APIStatusConsistencyChecker.java b/icu4j/tools/build/src/com/ibm/icu/dev/tool/docs/APIStatusConsistencyChecker.java
new file mode 100644 (file)
index 0000000..d6d850a
--- /dev/null
@@ -0,0 +1,124 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+package com.ibm.icu.dev.tool.docs;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * Checks if API status of equals/hashCode is same with its containing class.
+ *
+ * @author Yoshito
+ */
+public class APIStatusConsistencyChecker {
+    public static void main(String[] args) {
+        // args[0]  API signature file path
+        // args[1]  (Optional) List of classes to be skipped, separated by semicolon
+        if (args.length < 1) {
+            System.err.println("Missing API signature file path.");
+        } else if (args.length > 2) {
+            System.err.println("Too many command arguments");
+        }
+
+        List<String> skipClasses = Collections.emptyList();
+        if (args.length == 2) {
+            String[] classes = args[1].split(";");
+            skipClasses = Arrays.asList(classes);
+        }
+
+        // Load the ICU4J API signature file
+        Set<APIInfo> apiInfoSet = APIData.read(new File(args[0]), true).getAPIInfoSet();
+        APIStatusConsistencyChecker checker = new APIStatusConsistencyChecker(apiInfoSet, skipClasses, new PrintWriter(System.err, true));
+        checker.checkConsistency();
+        System.exit(checker.errCount);
+   }
+
+    private int errCount = 0;
+    private Set<APIInfo> apiInfoSet;
+    private PrintWriter pw;
+    private List<String> skipClasses;
+
+    public APIStatusConsistencyChecker(Set<APIInfo> apiInfoSet, List<String> skipClasses, PrintWriter pw) {
+        this.apiInfoSet = apiInfoSet;
+        this.skipClasses = skipClasses;
+        this.pw = pw;
+    }
+
+    public int errorCount() {
+        return errCount;
+    }
+
+    // Methods that should have same API status with a containing class
+    static final String[][] METHODS = {
+          //{"<method name>",   "<method signature in APIInfo data>"},
+            {"equals",      "boolean(java.lang.Object)"},
+            {"hashCode",    "int()"},
+            {"toString",    "java.lang.String()"},
+            {"clone",       "java.lang.Object()"},
+    };
+
+    public void checkConsistency() {
+        Map<String, APIInfo> classMap = new TreeMap<>();
+        // Build a map of APIInfo for classes, indexed by class name
+        for (APIInfo api : apiInfoSet) {
+            if (!api.isPublic() && !api.isProtected()) {
+                continue;
+            }
+            if (!api.isClass() && !api.isEnum()) {
+                continue;
+            }
+            String fullClassName = api.getPackageName() + "." + api.getName();
+            classMap.put(fullClassName, api);
+        }
+
+        // Walk through methods
+        for (APIInfo api : apiInfoSet) {
+            if (!api.isMethod()) {
+                continue;
+            }
+
+            String fullClassName = api.getPackageName() + "." + api.getClassName();
+            if (skipClasses.contains(fullClassName)) {
+                continue;
+            }
+
+            boolean checkWithClass = false;
+            String methodName = api.getName();
+            String methodSig = api.getSignature();
+
+            for (String[] method : METHODS) {
+                if (method[0].equals(methodName) && method[1].equals(methodSig)) {
+                    checkWithClass = true;
+                }
+            }
+
+            if (!checkWithClass) {
+                continue;
+            }
+
+            // Check if this method has same API status with the containing class
+            APIInfo clsApi = classMap.get(fullClassName);
+            if (clsApi == null) {
+                pw.println("## Error ## Class " + fullClassName + " is not found.");
+                errCount++;
+            }
+
+            int methodStatus = api.getVal(APIInfo.STA);
+            String methodVer = api.getStatusVersion();
+            int classStatus = clsApi.getVal(APIInfo.STA);
+            String classVer = clsApi.getStatusVersion();
+
+            if (methodStatus != classStatus || !Objects.equals(methodVer, classVer)) {
+                pw.println("## Error ## " + methodName + " in " + fullClassName);
+                errCount++;
+            }
+        }
+    }
+}
index 61abf722360ceab60e1ff16be273345a8c25138e..46aca4589de3348874aaa44712dc79421c1d084c 100644 (file)
@@ -56,7 +56,7 @@ public class DeprecatedAPIChecker {
     public void checkDeprecated() {
         // Gather API class/enum names and its names that can be
         // used for Class.forName()
-        Map<String, String> apiClassNameMap = new TreeMap<String, String>();
+        Map<String, String> apiClassNameMap = new TreeMap<>();
         for (APIInfo api : apiInfoSet) {
             if (!api.isPublic() && !api.isProtected()) {
                 continue;
@@ -133,6 +133,18 @@ public class DeprecatedAPIChecker {
             }
 
             List<String> paramNames = getParamNames(ctor);
+
+            Class<?> declClass = cls.getDeclaringClass();
+            if (declClass != null && !Modifier.isStatic(cls.getModifiers())) {
+                // This is non-static inner class's constructor.
+                // javac automatically injects instance of declaring class
+                // as the first param of the constructor, but ICU's API
+                // signature is based on javadoc and it generates signature
+                // without the implicit parameter.
+                assert paramNames.get(0).equals(declClass.getName());
+                paramNames.remove(0);
+            }
+
             api = findConstructorInfo(apiInfoSet, clsName, paramNames);
 
             if (api == null) {
@@ -351,7 +363,7 @@ public class DeprecatedAPIChecker {
             throw new IllegalArgumentException(api.toString() + " is not a constructor or a method.");
         }
 
-        List<String> nameList = new ArrayList<String>();
+        List<String> nameList = new ArrayList<>();
         String signature = api.getSignature();
         int start = signature.indexOf('(');
         int end = signature.indexOf(')');
@@ -410,7 +422,7 @@ public class DeprecatedAPIChecker {
     private static char[] PRIMITIVE_SIGNATURES = { 'B', 'S', 'I', 'J', 'F', 'D', 'Z', 'C' };
 
     private static List<String> toTypeNameList(Type[] types) {
-        List<String> nameList = new ArrayList<String>();
+        List<String> nameList = new ArrayList<>();
 
         for (Type t : types) {
             StringBuilder s = new StringBuilder();