Home | History | Annotate | Download | only in srcgen
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.icu4j.srcgen;
     17 
     18 import com.google.common.collect.ImmutableList;
     19 import com.google.common.collect.Lists;
     20 import com.google.currysrc.Main;
     21 import com.google.currysrc.api.Rules;
     22 import com.google.currysrc.api.input.InputFileGenerator;
     23 import com.google.currysrc.api.output.BasicOutputSourceFileGenerator;
     24 import com.google.currysrc.api.output.OutputSourceFileGenerator;
     25 import com.google.currysrc.api.process.DefaultRule;
     26 import com.google.currysrc.api.process.Rule;
     27 import com.google.currysrc.api.process.ast.BodyDeclarationLocator;
     28 import com.google.currysrc.api.process.ast.BodyDeclarationLocators;
     29 import com.google.currysrc.api.process.ast.TypeLocator;
     30 import com.google.currysrc.processors.HidePublicClasses;
     31 import com.google.currysrc.processors.InsertHeader;
     32 import com.google.currysrc.processors.ModifyQualifiedNames;
     33 import com.google.currysrc.processors.ModifyStringLiterals;
     34 import com.google.currysrc.processors.RemoveJavaDocTags;
     35 import com.google.currysrc.processors.RenamePackage;
     36 import com.google.currysrc.processors.ReplaceTextCommentScanner;
     37 
     38 import java.io.File;
     39 import java.io.IOException;
     40 import java.util.Arrays;
     41 import java.util.List;
     42 
     43 import static com.android.icu4j.srcgen.Icu4jTransformRules.createMandatoryRule;
     44 import static com.android.icu4j.srcgen.Icu4jTransformRules.createOptionalRule;
     45 
     46 /**
     47  * Applies Android's ICU4J source code transformation rules. If you make any changes to this class
     48  * then you should re-run the generate_android_icu4j.sh script.
     49  */
     50 public class Icu4jTransform {
     51 
     52   // The list of public ICU API classes exposed on Android. If you change this, you should change
     53   // the INITIAL_DEPRECATED_SET below to include entries from the new classes.
     54   static final String[] PUBLIC_API_CLASSES = new String[] {
     55       /* ASCII order please. */
     56       "android.icu.lang.UCharacter",
     57       "android.icu.lang.UCharacterCategory",
     58       "android.icu.lang.UCharacterDirection",
     59       "android.icu.lang.UCharacterEnums",
     60       "android.icu.lang.UProperty",
     61       "android.icu.lang.UScript",
     62       "android.icu.math.BigDecimal",
     63       "android.icu.math.MathContext",
     64       "android.icu.text.AlphabeticIndex",
     65       "android.icu.text.BreakIterator",
     66       "android.icu.text.CollationKey",
     67       "android.icu.text.Collator",
     68       "android.icu.text.CollationElementIterator",
     69       "android.icu.text.CompactDecimalFormat",
     70       "android.icu.text.CurrencyPluralInfo",
     71       "android.icu.text.DateFormat",
     72       "android.icu.text.DateFormatSymbols",
     73       "android.icu.text.DateIntervalInfo",
     74       "android.icu.text.DateIntervalFormat",
     75       "android.icu.text.DateTimePatternGenerator",
     76       "android.icu.text.DecimalFormat",
     77       "android.icu.text.DecimalFormatSymbols",
     78       "android.icu.text.DisplayContext",
     79       "android.icu.text.IDNA",
     80       "android.icu.text.ListFormatter",
     81       "android.icu.text.LocaleDisplayNames",
     82       "android.icu.text.LocaleDisplayNames$UiListItem",
     83       "android.icu.text.MeasureFormat",
     84       "android.icu.text.MessageFormat",
     85       "android.icu.text.MessagePattern",
     86       "android.icu.text.Normalizer",
     87       "android.icu.text.Normalizer2",
     88       "android.icu.text.NumberFormat",
     89       "android.icu.text.NumberingSystem",
     90       "android.icu.text.PluralFormat",
     91       "android.icu.text.PluralRules",
     92       "android.icu.text.RelativeDateTimeFormatter",
     93       "android.icu.text.Replaceable",
     94       "android.icu.text.RuleBasedCollator",
     95       "android.icu.text.ScientificNumberFormatter",
     96       "android.icu.text.SearchIterator",
     97       "android.icu.text.SelectFormat",
     98       "android.icu.text.SimpleDateFormat",
     99       "android.icu.text.StringPrepParseException",
    100       "android.icu.text.StringSearch",
    101       "android.icu.text.SymbolTable",
    102       "android.icu.text.TimeZoneFormat",
    103       "android.icu.text.TimeZoneNames",
    104       "android.icu.text.UCharacterIterator",
    105       "android.icu.text.UFormat",
    106       "android.icu.text.UnicodeFilter",
    107       "android.icu.text.UnicodeMatcher",
    108       "android.icu.text.UnicodeSet",
    109       "android.icu.text.UnicodeSetIterator",
    110       "android.icu.text.UnicodeSetSpanner",
    111       "android.icu.util.BuddhistCalendar",
    112       "android.icu.util.Calendar",
    113       "android.icu.util.CECalendar",
    114       "android.icu.util.ChineseCalendar",
    115       "android.icu.util.CopticCalendar",
    116       "android.icu.util.Currency",
    117       "android.icu.util.CurrencyAmount",
    118       "android.icu.util.DateInterval",
    119       "android.icu.util.EthiopicCalendar",
    120       "android.icu.util.Freezable",
    121       "android.icu.util.GregorianCalendar",
    122       "android.icu.util.HebrewCalendar",
    123       "android.icu.util.ICUUncheckedIOException",
    124       "android.icu.util.IllformedLocaleException",
    125       "android.icu.util.IndianCalendar",
    126       "android.icu.util.IslamicCalendar",
    127       "android.icu.util.JapaneseCalendar",
    128       "android.icu.util.LocaleData",
    129       "android.icu.util.Measure",
    130       "android.icu.util.MeasureUnit",
    131       "android.icu.util.Output",
    132       "android.icu.util.RangeValueIterator",
    133       "android.icu.util.TaiwanCalendar",
    134       "android.icu.util.TimeUnit",
    135       "android.icu.util.TimeZone",
    136       "android.icu.util.ULocale",
    137       "android.icu.util.UniversalTimeScale",
    138       "android.icu.util.ValueIterator",
    139       "android.icu.util.VersionInfo",
    140   };
    141 
    142   /**
    143    * The set of deprecated ICU types/methods/fields that must not be part of the public API as they
    144    * were deprecated when Android first exposed their classes as a public API. Methods deprecated by
    145    * ICU after this will be visible and deprecated in Android.
    146    */
    147   // This list was originally generated by the CaptureDeprecatedElements tool when run against
    148   // ICU56 with the original PUBLIC_API_CLASSES.
    149   private static final String[] INITIAL_DEPRECATED_SET = new String[] {
    150       /* ASCII order please. */
    151       "field:android.icu.lang.UProperty#ISO_COMMENT",
    152       "field:android.icu.lang.UProperty#UNDEFINED",
    153       "field:android.icu.lang.UProperty#UNICODE_1_NAME",
    154       "field:android.icu.lang.UScript#DUPLOYAN_SHORTAND",
    155       "field:android.icu.text.DateFormat#ABBR_STANDALONE_MONTH",
    156       "field:android.icu.text.DateFormat#DATE_SKELETONS",
    157       "field:android.icu.text.DateFormat#HOUR_GENERIC_TZ",
    158       "field:android.icu.text.DateFormat#HOUR_MINUTE_GENERIC_TZ",
    159       "field:android.icu.text.DateFormat#HOUR_MINUTE_TZ",
    160       "field:android.icu.text.DateFormat#HOUR_TZ",
    161       "field:android.icu.text.DateFormat#STANDALONE_MONTH",
    162       "field:android.icu.text.DateFormat#TIME_SKELETONS",
    163       "field:android.icu.text.DateFormat#ZONE_SKELETONS",
    164       "field:android.icu.text.DateFormatSymbols#DT_CONTEXT_COUNT",
    165       "field:android.icu.text.DateFormatSymbols#DT_WIDTH_COUNT",
    166       "field:android.icu.text.DateFormatSymbols#NUMERIC",
    167       "field:android.icu.text.DateTimePatternGenerator#MATCH_MINUTE_FIELD_LENGTH",
    168       "field:android.icu.text.DateTimePatternGenerator#MATCH_SECOND_FIELD_LENGTH",
    169       "field:android.icu.text.IDNA#ALLOW_UNASSIGNED",
    170       "field:android.icu.text.Normalizer#COMPARE_NORM_OPTIONS_SHIFT",
    171       "field:android.icu.text.Normalizer#COMPOSE",
    172       "field:android.icu.text.Normalizer#COMPOSE_COMPAT",
    173       "field:android.icu.text.Normalizer#DECOMP",
    174       "field:android.icu.text.Normalizer#DECOMP_COMPAT",
    175       "field:android.icu.text.Normalizer#DEFAULT",
    176       "field:android.icu.text.Normalizer#DONE",
    177       "field:android.icu.text.Normalizer#FCD",
    178       "field:android.icu.text.Normalizer#IGNORE_HANGUL",
    179       "field:android.icu.text.Normalizer#NFC",
    180       "field:android.icu.text.Normalizer#NFD",
    181       "field:android.icu.text.Normalizer#NFKC",
    182       "field:android.icu.text.Normalizer#NFKD",
    183       "field:android.icu.text.Normalizer#NONE",
    184       "field:android.icu.text.Normalizer#NO_OP",
    185       "field:android.icu.text.Normalizer#UNICODE_3_2",
    186       "field:android.icu.text.PluralRules#CATEGORY_SEPARATOR",
    187       "field:android.icu.text.PluralRules#KEYWORD_RULE_SEPARATOR",
    188       "field:android.icu.text.PluralRules$FixedDecimal#decimalDigits",
    189       "field:android.icu.text.PluralRules$FixedDecimal#decimalDigitsWithoutTrailingZeros",
    190       "field:android.icu.text.PluralRules$FixedDecimal#hasIntegerValue",
    191       "field:android.icu.text.PluralRules$FixedDecimal#integerValue",
    192       "field:android.icu.text.PluralRules$FixedDecimal#isNegative",
    193       "field:android.icu.text.PluralRules$FixedDecimal#source",
    194       "field:android.icu.text.PluralRules$FixedDecimal#visibleDecimalDigitCount",
    195       "field:android.icu.text.PluralRules$FixedDecimal#visibleDecimalDigitCountWithoutTrailingZeros",
    196       "field:android.icu.text.PluralRules$FixedDecimalRange#end",
    197       "field:android.icu.text.PluralRules$FixedDecimalRange#start",
    198       "field:android.icu.text.PluralRules$FixedDecimalSamples#bounded",
    199       "field:android.icu.text.PluralRules$FixedDecimalSamples#sampleType",
    200       "field:android.icu.text.PluralRules$FixedDecimalSamples#samples",
    201       "field:android.icu.text.PluralRules$StandardPluralCategories#COUNT",
    202       "field:android.icu.text.PluralRules$StandardPluralCategories#VALUES",
    203       "field:android.icu.text.UnicodeSetIterator#endElement",
    204       "field:android.icu.text.UnicodeSetIterator#nextElement",
    205       "field:android.icu.util.Calendar#WEEKDAY",
    206       "field:android.icu.util.Calendar#WEEKEND",
    207       "field:android.icu.util.Calendar#WEEKEND_CEASE",
    208       "field:android.icu.util.Calendar#WEEKEND_ONSET",
    209       "field:android.icu.util.LocaleData#DELIMITER_COUNT",
    210       "field:android.icu.util.LocaleData#ES_COUNT",
    211       "field:android.icu.util.LocaleData#ES_CURRENCY",
    212       "field:android.icu.util.MeasureUnit#subType",
    213       "field:android.icu.util.MeasureUnit#type",
    214       "field:android.icu.util.VersionInfo#ICU_DATA_VERSION",
    215       "field:android.icu.util.VersionInfo#ICU_DATA_VERSION_PATH",
    216       "field:android.icu.util.VersionInfo#UCOL_TAILORINGS_VERSION",
    217       "method:android.icu.lang.UCharacter#getCharFromName1_0(String)",
    218       "method:android.icu.lang.UCharacter#getISOComment(int)",
    219       "method:android.icu.lang.UCharacter#getName1_0(int)",
    220       "method:android.icu.lang.UCharacter#getName1_0Iterator()",
    221       "method:android.icu.lang.UCharacter#getPropertyValueEnumNoThrow(int,CharSequence)",
    222       "method:android.icu.lang.UCharacter#getStringPropertyValue(int,int,int)",
    223       "method:android.icu.lang.UCharacter#isJavaLetter(int)",
    224       "method:android.icu.lang.UCharacter#isJavaLetterOrDigit(int)",
    225       "method:android.icu.lang.UCharacter#isSpace(int)",
    226       "method:android.icu.lang.UCharacter#toTitleFirst(ULocale,String)",
    227       "method:android.icu.text.AlphabeticIndex#getFirstCharactersInScripts()",
    228       "method:android.icu.text.BreakIterator#getBreakInstance(ULocale,int)",
    229       "method:android.icu.text.CollationElementIterator#getRuleBasedCollator()",
    230       "method:android.icu.text.CollationElementIterator#hashCode()",
    231       "method:android.icu.text.Collator#doCompare(CharSequence,CharSequence)",
    232       "method:android.icu.text.Collator#setStrength2(int)",
    233       "method:android.icu.text.Collator#setVariableTop(String)",
    234       "method:android.icu.text.Collator#setVariableTop(int)",
    235       "method:android.icu.text.CompactDecimalFormat#CompactDecimalFormat(String,DecimalFormatSymbols,CompactStyle,PluralRules,long[],Map<String,String[][]>,Map<String,String[]>,Collection<String>)",
    236       "method:android.icu.text.CurrencyPluralInfo#hashCode()",
    237       "method:android.icu.text.DateFormatSymbols#getDateFormatBundle(Calendar,Locale)",
    238       "method:android.icu.text.DateFormatSymbols#getDateFormatBundle(Calendar,ULocale)",
    239       "method:android.icu.text.DateFormatSymbols#getDateFormatBundle(Class<? extends Calendar>,Locale)",
    240       "method:android.icu.text.DateFormatSymbols#getDateFormatBundle(Class<? extends Calendar>,ULocale)",
    241       "method:android.icu.text.DateFormatSymbols#getLeapMonthPattern(int,int)",
    242       "method:android.icu.text.DateFormatSymbols#initializeData(ULocale,CalendarData)",
    243       "method:android.icu.text.DateFormatSymbols#setLeapMonthPattern(String,int,int)",
    244       "method:android.icu.text.DateIntervalFormat#DateIntervalFormat(String,DateIntervalInfo,SimpleDateFormat)",
    245       "method:android.icu.text.DateIntervalFormat#getPatterns(Calendar,Calendar,Output<String>)",
    246       "method:android.icu.text.DateIntervalFormat#getRawPatterns()",
    247       "method:android.icu.text.DateIntervalFormat#parseObject(String,ParsePosition)",
    248       "method:android.icu.text.DateIntervalInfo#DateIntervalInfo()",
    249       "method:android.icu.text.DateIntervalInfo#genPatternInfo(String,boolean)",
    250       "method:android.icu.text.DateIntervalInfo#getPatterns()",
    251       "method:android.icu.text.DateIntervalInfo#getRawPatterns()",
    252       "method:android.icu.text.DateTimePatternGenerator#addPatternWithSkeleton(String,String,boolean,PatternInfo)",
    253       "method:android.icu.text.DateTimePatternGenerator#getAppendFormatNumber(String)",
    254       "method:android.icu.text.DateTimePatternGenerator#getCanonicalSkeletonAllowingDuplicates(String)",
    255       "method:android.icu.text.DateTimePatternGenerator#getDefaultHourFormatChar()",
    256       "method:android.icu.text.DateTimePatternGenerator#getFields(String)",
    257       "method:android.icu.text.DateTimePatternGenerator#getFrozenInstance(ULocale)",
    258       "method:android.icu.text.DateTimePatternGenerator#getRedundants(Collection<String>)",
    259       "method:android.icu.text.DateTimePatternGenerator#getSkeletonAllowingDuplicates(String)",
    260       "method:android.icu.text.DateTimePatternGenerator#isSingleField(String)",
    261       "method:android.icu.text.DateTimePatternGenerator#setDefaultHourFormatChar(char)",
    262       "method:android.icu.text.DateTimePatternGenerator#skeletonsAreSimilar(String,String)",
    263       "method:android.icu.text.DateTimePatternGenerator$FormatParser#FormatParser()",
    264       "method:android.icu.text.DateTimePatternGenerator$FormatParser#getItems()",
    265       "method:android.icu.text.DateTimePatternGenerator$FormatParser#hasDateAndTimeFields()",
    266       "method:android.icu.text.DateTimePatternGenerator$FormatParser#quoteLiteral(String)",
    267       "method:android.icu.text.DateTimePatternGenerator$FormatParser#set(String)",
    268       "method:android.icu.text.DateTimePatternGenerator$FormatParser#set(String,boolean)",
    269       "method:android.icu.text.DateTimePatternGenerator$FormatParser#toString()",
    270       "method:android.icu.text.DateTimePatternGenerator$FormatParser#toString(int,int)",
    271       "method:android.icu.text.DateTimePatternGenerator$VariableField#VariableField(String)",
    272       "method:android.icu.text.DateTimePatternGenerator$VariableField#VariableField(String,boolean)",
    273       "method:android.icu.text.DateTimePatternGenerator$VariableField#getCanonicalCode(int)",
    274       "method:android.icu.text.DateTimePatternGenerator$VariableField#getType()",
    275       "method:android.icu.text.DateTimePatternGenerator$VariableField#isNumeric()",
    276       "method:android.icu.text.DateTimePatternGenerator$VariableField#toString()",
    277       "method:android.icu.text.DecimalFormat#getEffectiveCurrency()",
    278       "method:android.icu.text.DecimalFormatSymbols#getMinusString()",
    279       "method:android.icu.text.DecimalFormatSymbols#getPlusString()",
    280       "method:android.icu.text.IDNA#IDNA()",
    281       "method:android.icu.text.IDNA#addError(Info,Error)",
    282       "method:android.icu.text.IDNA#addLabelError(Info,Error)",
    283       "method:android.icu.text.IDNA#compare(String,String,int)",
    284       "method:android.icu.text.IDNA#compare(StringBuffer,StringBuffer,int)",
    285       "method:android.icu.text.IDNA#compare(UCharacterIterator,UCharacterIterator,int)",
    286       "method:android.icu.text.IDNA#convertIDNToASCII(String,int)",
    287       "method:android.icu.text.IDNA#convertIDNToASCII(StringBuffer,int)",
    288       "method:android.icu.text.IDNA#convertIDNToASCII(UCharacterIterator,int)",
    289       "method:android.icu.text.IDNA#convertIDNToUnicode(String,int)",
    290       "method:android.icu.text.IDNA#convertIDNToUnicode(StringBuffer,int)",
    291       "method:android.icu.text.IDNA#convertIDNToUnicode(UCharacterIterator,int)",
    292       "method:android.icu.text.IDNA#convertToASCII(String,int)",
    293       "method:android.icu.text.IDNA#convertToASCII(StringBuffer,int)",
    294       "method:android.icu.text.IDNA#convertToASCII(UCharacterIterator,int)",
    295       "method:android.icu.text.IDNA#convertToUnicode(String,int)",
    296       "method:android.icu.text.IDNA#convertToUnicode(StringBuffer,int)",
    297       "method:android.icu.text.IDNA#convertToUnicode(UCharacterIterator,int)",
    298       "method:android.icu.text.IDNA#hasCertainErrors(Info,EnumSet<Error>)",
    299       "method:android.icu.text.IDNA#hasCertainLabelErrors(Info,EnumSet<Error>)",
    300       "method:android.icu.text.IDNA#isBiDi(Info)",
    301       "method:android.icu.text.IDNA#isOkBiDi(Info)",
    302       "method:android.icu.text.IDNA#promoteAndResetLabelErrors(Info)",
    303       "method:android.icu.text.IDNA#resetInfo(Info)",
    304       "method:android.icu.text.IDNA#setBiDi(Info)",
    305       "method:android.icu.text.IDNA#setNotOkBiDi(Info)",
    306       "method:android.icu.text.IDNA#setTransitionalDifferent(Info)",
    307       "method:android.icu.text.LocaleDisplayNames#LocaleDisplayNames()",
    308       "method:android.icu.text.LocaleDisplayNames#scriptDisplayNameInContext(String)",
    309       "method:android.icu.text.MeasureFormat#formatMeasureRange(Measure,Measure)",
    310       "method:android.icu.text.MeasureFormat#getRangeFormat(ULocale,FormatWidth)",
    311       "method:android.icu.text.MeasureFormat#getRangePattern(ULocale,FormatWidth)",
    312       "method:android.icu.text.Normalizer#Normalizer(CharacterIterator,Mode,int)",
    313       "method:android.icu.text.Normalizer#Normalizer(String,Mode,int)",
    314       "method:android.icu.text.Normalizer#Normalizer(UCharacterIterator,Mode,int)",
    315       "method:android.icu.text.Normalizer#clone()",
    316       "method:android.icu.text.Normalizer#compose(String,boolean)",
    317       "method:android.icu.text.Normalizer#compose(String,boolean,int)",
    318       "method:android.icu.text.Normalizer#compose(char[],char[],boolean,int)",
    319       "method:android.icu.text.Normalizer#compose(char[],int,int,char[],int,int,boolean,int)",
    320       "method:android.icu.text.Normalizer#concatenate(String,String,Mode,int)",
    321       "method:android.icu.text.Normalizer#concatenate(char[],char[],Mode,int)",
    322       "method:android.icu.text.Normalizer#concatenate(char[],int,int,char[],int,int,char[],int,int,Normalizer.Mode,int)",
    323       "method:android.icu.text.Normalizer#current()",
    324       "method:android.icu.text.Normalizer#decompose(String,boolean)",
    325       "method:android.icu.text.Normalizer#decompose(String,boolean,int)",
    326       "method:android.icu.text.Normalizer#decompose(char[],char[],boolean,int)",
    327       "method:android.icu.text.Normalizer#decompose(char[],int,int,char[],int,int,boolean,int)",
    328       "method:android.icu.text.Normalizer#endIndex()",
    329       "method:android.icu.text.Normalizer#first()",
    330       "method:android.icu.text.Normalizer#getBeginIndex()",
    331       "method:android.icu.text.Normalizer#getEndIndex()",
    332       "method:android.icu.text.Normalizer#getFC_NFKC_Closure(int)",
    333       "method:android.icu.text.Normalizer#getFC_NFKC_Closure(int,char[])",
    334       "method:android.icu.text.Normalizer#getIndex()",
    335       "method:android.icu.text.Normalizer#getLength()",
    336       "method:android.icu.text.Normalizer#getMode()",
    337       "method:android.icu.text.Normalizer#getOption(int)",
    338       "method:android.icu.text.Normalizer#getText()",
    339       "method:android.icu.text.Normalizer#getText(char[])",
    340       "method:android.icu.text.Normalizer#isNormalized(String,Mode,int)",
    341       "method:android.icu.text.Normalizer#isNormalized(char[],int,int,Mode,int)",
    342       "method:android.icu.text.Normalizer#isNormalized(int,Mode,int)",
    343       "method:android.icu.text.Normalizer#last()",
    344       "method:android.icu.text.Normalizer#next()",
    345       "method:android.icu.text.Normalizer#normalize(String,Mode)",
    346       "method:android.icu.text.Normalizer#normalize(String,Mode,int)",
    347       "method:android.icu.text.Normalizer#normalize(char[],char[],Mode,int)",
    348       "method:android.icu.text.Normalizer#normalize(char[],int,int,char[],int,int,Mode,int)",
    349       "method:android.icu.text.Normalizer#normalize(int,Mode)",
    350       "method:android.icu.text.Normalizer#normalize(int,Mode,int)",
    351       "method:android.icu.text.Normalizer#previous()",
    352       "method:android.icu.text.Normalizer#quickCheck(String,Mode)",
    353       "method:android.icu.text.Normalizer#quickCheck(String,Mode,int)",
    354       "method:android.icu.text.Normalizer#quickCheck(char[],Mode,int)",
    355       "method:android.icu.text.Normalizer#quickCheck(char[],int,int,Mode,int)",
    356       "method:android.icu.text.Normalizer#reset()",
    357       "method:android.icu.text.Normalizer#setIndex(int)",
    358       "method:android.icu.text.Normalizer#setIndexOnly(int)",
    359       "method:android.icu.text.Normalizer#setMode(Mode)",
    360       "method:android.icu.text.Normalizer#setOption(int,boolean)",
    361       "method:android.icu.text.Normalizer#setText(CharacterIterator)",
    362       "method:android.icu.text.Normalizer#setText(String)",
    363       "method:android.icu.text.Normalizer#setText(StringBuffer)",
    364       "method:android.icu.text.Normalizer#setText(UCharacterIterator)",
    365       "method:android.icu.text.Normalizer#setText(char[])",
    366       "method:android.icu.text.Normalizer#startIndex()",
    367       "method:android.icu.text.Normalizer$Mode#Mode()",
    368       "method:android.icu.text.Normalizer$Mode#getNormalizer2(int)",
    369       "method:android.icu.text.Normalizer2#Normalizer2()",
    370       "method:android.icu.text.NumberFormat#getEffectiveCurrency()",
    371       "method:android.icu.text.NumberFormat#getPattern(Locale,int)",
    372       "method:android.icu.text.PluralFormat#setLocale(ULocale)",
    373       "method:android.icu.text.PluralRules#addSample(String,Number,int,Set<Double>)",
    374       "method:android.icu.text.PluralRules#compareTo(PluralRules)",
    375       "method:android.icu.text.PluralRules#computeLimited(String,SampleType)",
    376       "method:android.icu.text.PluralRules#getAllKeywordValues(String,SampleType)",
    377       "method:android.icu.text.PluralRules#getDecimalSamples(String,SampleType)",
    378       "method:android.icu.text.PluralRules#getKeywordStatus(String,int,Set<Double>,Output<Double>,SampleType)",
    379       "method:android.icu.text.PluralRules#getRules(String)",
    380       "method:android.icu.text.PluralRules#getSamples(String,SampleType)",
    381       "method:android.icu.text.PluralRules#hashCode()",
    382       "method:android.icu.text.PluralRules#isLimited(String)",
    383       "method:android.icu.text.PluralRules#isLimited(String,SampleType)",
    384       "method:android.icu.text.PluralRules#matches(FixedDecimal,String)",
    385       "method:android.icu.text.PluralRules#select(FixedDecimal)",
    386       "method:android.icu.text.PluralRules#select(double,int,long)",
    387       "method:android.icu.text.PluralRules$Factory#Factory()",
    388       "method:android.icu.text.PluralRules$Factory#forLocale(ULocale)",
    389       "method:android.icu.text.PluralRules$Factory#forLocale(ULocale,PluralType)",
    390       "method:android.icu.text.PluralRules$Factory#getAvailableULocales()",
    391       "method:android.icu.text.PluralRules$Factory#getDefaultFactory()",
    392       "method:android.icu.text.PluralRules$Factory#getFunctionalEquivalent(ULocale,boolean[])",
    393       "method:android.icu.text.PluralRules$Factory#hasOverride(ULocale)",
    394       "method:android.icu.text.PluralRules$FixedDecimal#FixedDecimal(String)",
    395       "method:android.icu.text.PluralRules$FixedDecimal#FixedDecimal(double)",
    396       "method:android.icu.text.PluralRules$FixedDecimal#FixedDecimal(double,int)",
    397       "method:android.icu.text.PluralRules$FixedDecimal#FixedDecimal(double,int,long)",
    398       "method:android.icu.text.PluralRules$FixedDecimal#FixedDecimal(long)",
    399       "method:android.icu.text.PluralRules$FixedDecimal#compareTo(FixedDecimal)",
    400       "method:android.icu.text.PluralRules$FixedDecimal#decimals(double)",
    401       "method:android.icu.text.PluralRules$FixedDecimal#doubleValue()",
    402       "method:android.icu.text.PluralRules$FixedDecimal#equals(Object)",
    403       "method:android.icu.text.PluralRules$FixedDecimal#floatValue()",
    404       "method:android.icu.text.PluralRules$FixedDecimal#get(Operand)",
    405       "method:android.icu.text.PluralRules$FixedDecimal#getBaseFactor()",
    406       "method:android.icu.text.PluralRules$FixedDecimal#getDecimalDigits()",
    407       "method:android.icu.text.PluralRules$FixedDecimal#getDecimalDigitsWithoutTrailingZeros()",
    408       "method:android.icu.text.PluralRules$FixedDecimal#getIntegerValue()",
    409       "method:android.icu.text.PluralRules$FixedDecimal#getOperand(String)",
    410       "method:android.icu.text.PluralRules$FixedDecimal#getShiftedValue()",
    411       "method:android.icu.text.PluralRules$FixedDecimal#getSource()",
    412       "method:android.icu.text.PluralRules$FixedDecimal#getVisibleDecimalDigitCount()",
    413       "method:android.icu.text.PluralRules$FixedDecimal#getVisibleDecimalDigitCountWithoutTrailingZeros()",
    414       "method:android.icu.text.PluralRules$FixedDecimal#hasIntegerValue()",
    415       "method:android.icu.text.PluralRules$FixedDecimal#hashCode()",
    416       "method:android.icu.text.PluralRules$FixedDecimal#intValue()",
    417       "method:android.icu.text.PluralRules$FixedDecimal#isHasIntegerValue()",
    418       "method:android.icu.text.PluralRules$FixedDecimal#isNegative()",
    419       "method:android.icu.text.PluralRules$FixedDecimal#longValue()",
    420       "method:android.icu.text.PluralRules$FixedDecimal#toString()",
    421       "method:android.icu.text.PluralRules$FixedDecimalRange#FixedDecimalRange(FixedDecimal,FixedDecimal)",
    422       "method:android.icu.text.PluralRules$FixedDecimalRange#toString()",
    423       "method:android.icu.text.PluralRules$FixedDecimalSamples#addSamples(Set<Double>)",
    424       "method:android.icu.text.PluralRules$FixedDecimalSamples#getSamples()",
    425       "method:android.icu.text.PluralRules$FixedDecimalSamples#getStartEndSamples(Set<FixedDecimal>)",
    426       "method:android.icu.text.PluralRules$FixedDecimalSamples#toString()",
    427       "method:android.icu.text.RuleBasedCollator#doCompare(CharSequence,CharSequence)",
    428       "method:android.icu.text.RuleBasedCollator#internalGetCEs(CharSequence)",
    429       "method:android.icu.text.RuleBasedCollator#isHiraganaQuaternary()",
    430       "method:android.icu.text.RuleBasedCollator#setHiraganaQuaternary(boolean)",
    431       "method:android.icu.text.RuleBasedCollator#setHiraganaQuaternaryDefault()",
    432       "method:android.icu.text.RuleBasedCollator#setVariableTop(String)",
    433       "method:android.icu.text.RuleBasedCollator#setVariableTop(int)",
    434       "method:android.icu.text.SearchIterator#setMatchNotFound()",
    435       "method:android.icu.text.SimpleDateFormat#SimpleDateFormat(String,DateFormatSymbols,ULocale)",
    436       "method:android.icu.text.SimpleDateFormat#getInstance(Calendar.FormatConfiguration)",
    437       "method:android.icu.text.SimpleDateFormat#intervalFormatByAlgorithm(Calendar,Calendar,StringBuffer,FieldPosition)",
    438       "method:android.icu.text.SimpleDateFormat#subFormat(StringBuffer,char,int,int,int,DisplayContext,FieldPosition,Calendar)",
    439       "method:android.icu.text.SimpleDateFormat#subFormat(char,int,int,int,DisplayContext,FieldPosition,Calendar)",
    440       "method:android.icu.text.SimpleDateFormat#zeroPaddingNumber(NumberFormat,StringBuffer,int,int,int)",
    441       "method:android.icu.text.StringPrepParseException#hashCode()",
    442       "method:android.icu.text.StringSearch#setMatchNotFound()",
    443       "method:android.icu.text.TimeZoneNames#getDisplayNames(String,NameType[],long,String[],int)",
    444       "method:android.icu.text.TimeZoneNames#loadAllDisplayNames()",
    445       "method:android.icu.text.TimeZoneNames$Factory#Factory()",
    446       "method:android.icu.text.TimeZoneNames$Factory#getTimeZoneNames(ULocale)",
    447       "method:android.icu.text.UnicodeFilter#UnicodeFilter()",
    448       "method:android.icu.text.UnicodeSet#addBridges(UnicodeSet)",
    449       "method:android.icu.text.UnicodeSet#applyPattern(String,ParsePosition,SymbolTable,int)",
    450       "method:android.icu.text.UnicodeSet#compare(Iterator<T>,Iterator<T>)",
    451       "method:android.icu.text.UnicodeSet#findIn(CharSequence,int,boolean)",
    452       "method:android.icu.text.UnicodeSet#findLastIn(CharSequence,int,boolean)",
    453       "method:android.icu.text.UnicodeSet#getDefaultXSymbolTable()",
    454       "method:android.icu.text.UnicodeSet#getRegexEquivalent()",
    455       "method:android.icu.text.UnicodeSet#getSingleCodePoint(CharSequence)",
    456       "method:android.icu.text.UnicodeSet#matchesAt(CharSequence,int)",
    457       "method:android.icu.text.UnicodeSet#setDefaultXSymbolTable(XSymbolTable)",
    458       "method:android.icu.text.UnicodeSet#spanAndCount(CharSequence,int,SpanCondition,OutputInt)",
    459       "method:android.icu.text.UnicodeSet#stripFrom(CharSequence,boolean)",
    460       "method:android.icu.text.UnicodeSetIterator#getSet()",
    461       "method:android.icu.text.UnicodeSetIterator#loadRange(int)",
    462       "method:android.icu.util.Calendar#getDateTimePattern(Calendar,ULocale,int)",
    463       "method:android.icu.util.Calendar#getDayOfWeekType(int)",
    464       "method:android.icu.util.Calendar#getRelatedYear()",
    465       "method:android.icu.util.Calendar#getWeekendTransition(int)",
    466       "method:android.icu.util.Calendar#haveDefaultCentury()",
    467       "method:android.icu.util.Calendar#setRelatedYear(int)",
    468       "method:android.icu.util.Calendar$FormatConfiguration#getCalendar()",
    469       "method:android.icu.util.Calendar$FormatConfiguration#getDateFormatSymbols()",
    470       "method:android.icu.util.Calendar$FormatConfiguration#getLocale()",
    471       "method:android.icu.util.Calendar$FormatConfiguration#getOverrideString()",
    472       "method:android.icu.util.Calendar$FormatConfiguration#getPatternString()",
    473       "method:android.icu.util.ChineseCalendar#ChineseCalendar(TimeZone,ULocale,int,TimeZone)",
    474       "method:android.icu.util.ChineseCalendar#haveDefaultCentury()",
    475       "method:android.icu.util.CopticCalendar#getJDEpochOffset()",
    476       "method:android.icu.util.CopticCalendar#handleComputeFields(int)",
    477       "method:android.icu.util.CopticCalendar#handleGetExtendedYear()",
    478       "method:android.icu.util.Currency#parse(ULocale,String,int,ParsePosition)",
    479       "method:android.icu.util.HebrewCalendar#isLeapYear(int)",
    480       "method:android.icu.util.HebrewCalendar#validateField(int)",
    481       "method:android.icu.util.JapaneseCalendar#haveDefaultCentury()",
    482       "method:android.icu.util.MeasureUnit#MeasureUnit(String,String)",
    483       "method:android.icu.util.MeasureUnit#addUnit(String,String,Factory)",
    484       "method:android.icu.util.MeasureUnit#internalGetInstance(String,String)",
    485       "method:android.icu.util.MeasureUnit#resolveUnitPerUnit(MeasureUnit,MeasureUnit)",
    486       "method:android.icu.util.MeasureUnit$Factory#create(String,String)",
    487       "method:android.icu.util.TimeZone#TimeZone(String)",
    488       "method:android.icu.util.ULocale#getDisplayScriptInContext()",
    489       "method:android.icu.util.ULocale#getDisplayScriptInContext(String,String)",
    490       "method:android.icu.util.ULocale#getDisplayScriptInContext(String,ULocale)",
    491       "method:android.icu.util.ULocale#getDisplayScriptInContext(ULocale)",
    492       "method:android.icu.util.ULocale#minimizeSubtags(ULocale,Minimize)",
    493       "method:android.icu.util.VersionInfo#getVersionString(int,int)",
    494       "method:android.icu.util.VersionInfo#javaVersion()",
    495       "type:android.icu.text.DateTimePatternGenerator$FormatParser",
    496       "type:android.icu.text.DateTimePatternGenerator$VariableField",
    497       "type:android.icu.text.Normalizer$Mode",
    498       "type:android.icu.text.PluralRules$Factory",
    499       "type:android.icu.text.PluralRules$FixedDecimal",
    500       "type:android.icu.text.PluralRules$FixedDecimalRange",
    501       "type:android.icu.text.PluralRules$FixedDecimalSamples",
    502       "type:android.icu.text.PluralRules$SampleType",
    503       "type:android.icu.text.PluralRules$StandardPluralCategories",
    504       "type:android.icu.text.TimeZoneNames$Factory",
    505       "type:android.icu.util.Calendar$FormatConfiguration",
    506       "type:android.icu.util.MeasureUnit$Factory",
    507       "type:android.icu.util.ULocale$Minimize",
    508   };
    509 
    510   /** A set of declarations we don't want to expose in Android. */
    511   private static final String[] DECLARATIONS_TO_HIDE = {
    512       /* ASCII order please. */
    513       "field:android.icu.lang.UCharacter$BidiPairedBracketType#COUNT",
    514       "field:android.icu.lang.UCharacter$DecompositionType#COUNT",
    515       "field:android.icu.lang.UCharacter$EastAsianWidth#COUNT",
    516       "field:android.icu.lang.UCharacter$GraphemeClusterBreak#COUNT",
    517       "field:android.icu.lang.UCharacter$HangulSyllableType#COUNT",
    518       "field:android.icu.lang.UCharacter$JoiningGroup#COUNT",
    519       "field:android.icu.lang.UCharacter$JoiningType#COUNT",
    520       "field:android.icu.lang.UCharacter$LineBreak#COUNT",
    521       "field:android.icu.lang.UCharacter$NumericType#COUNT",
    522       "field:android.icu.lang.UCharacter$SentenceBreak#COUNT",
    523       "field:android.icu.lang.UCharacter$UnicodeBlock#COUNT",
    524       "field:android.icu.lang.UCharacter$WordBreak#COUNT",
    525       "field:android.icu.lang.UCharacterEnums$ECharacterCategory#CHAR_CATEGORY_COUNT",
    526       "field:android.icu.lang.UCharacterEnums$ECharacterDirection#CHAR_DIRECTION_COUNT",
    527       "field:android.icu.lang.UProperty#BINARY_LIMIT",
    528       "field:android.icu.lang.UProperty#DOUBLE_LIMIT",
    529       "field:android.icu.lang.UProperty#INT_LIMIT",
    530       "field:android.icu.lang.UProperty#MASK_LIMIT",
    531       "field:android.icu.lang.UProperty#OTHER_PROPERTY_LIMIT",
    532       "field:android.icu.lang.UProperty#STRING_LIMIT",
    533       "field:android.icu.lang.UProperty$NameChoice#COUNT",
    534       "field:android.icu.lang.UScript#CODE_LIMIT",
    535       "field:android.icu.text.CollationKey$BoundMode#COUNT",
    536       "field:android.icu.text.Collator$ReorderCodes#LIMIT",
    537       "field:android.icu.text.DateFormat#FIELD_COUNT",
    538       "field:android.icu.text.DateTimePatternGenerator#TYPE_LIMIT",
    539       "field:android.icu.util.LocaleData#ES_AUXILIARY",
    540       "field:android.icu.util.LocaleData#ES_INDEX",
    541       "field:android.icu.util.LocaleData#ES_PUNCTUATION",
    542       "field:android.icu.util.LocaleData#ES_STANDARD",
    543       "method:android.icu.text.BreakIterator#registerInstance(BreakIterator,Locale,int)",
    544       "method:android.icu.text.BreakIterator#registerInstance(BreakIterator,ULocale,int)",
    545       "method:android.icu.text.BreakIterator#unregister(Object)",
    546       "method:android.icu.text.CollationKey#CollationKey(String,RawCollationKey)",
    547       "method:android.icu.text.Collator#getRawCollationKey(String,RawCollationKey)",
    548       "method:android.icu.text.Collator#registerFactory(CollatorFactory)",
    549       "method:android.icu.text.Collator#registerInstance(Collator,ULocale)",
    550       "method:android.icu.text.Collator#unregister(Object)",
    551       "method:android.icu.text.NumberFormat#registerFactory(NumberFormatFactory)",
    552       "method:android.icu.text.NumberFormat#unregister(Object)",
    553       "method:android.icu.text.RuleBasedCollator#getRawCollationKey(String,RawCollationKey)",
    554       "method:android.icu.text.UnicodeSet#addAllTo(Iterable<T>,T[])",
    555       "method:android.icu.text.UnicodeSet#addAllTo(Iterable<T>,U)",
    556       "method:android.icu.text.UnicodeSet#addAllTo(String[])",
    557       "method:android.icu.text.UnicodeSet#compare(CharSequence,int)",
    558       "method:android.icu.text.UnicodeSet#compare(Collection<T>,Collection<T>,ComparisonStyle)",
    559       "method:android.icu.text.UnicodeSet#compare(Iterable<T>,Iterable<T>)",
    560       "method:android.icu.text.UnicodeSet#compare(int,CharSequence)",
    561       "method:android.icu.text.UnicodeSet#resemblesPattern(String,int)",
    562       "method:android.icu.text.UnicodeSet#toArray(UnicodeSet)",
    563       "method:android.icu.util.CECalendar#ceToJD(long,int,int,int)",
    564       "method:android.icu.util.CECalendar#getJDEpochOffset()",
    565       "method:android.icu.util.CECalendar#jdToCE(int,int,int[])",
    566       "method:android.icu.util.Currency#registerInstance(Currency,ULocale)",
    567       "method:android.icu.util.Currency#unregister(Object)",
    568       "method:android.icu.util.IslamicCalendar#isCivil()",
    569       "method:android.icu.util.IslamicCalendar#setCivil(boolean)",
    570       "method:android.icu.util.LocaleData#getExemplarSet(int,int)",
    571       "method:android.icu.util.LocaleData#getExemplarSet(ULocale,int)",
    572       "method:android.icu.util.LocaleData#getExemplarSet(ULocale,int,int)",
    573       "method:android.icu.util.LocaleData#getLocaleDisplayPattern()",
    574       "method:android.icu.util.LocaleData#getLocaleSeparator()",
    575       "method:android.icu.util.TimeZone#clearCachedDefault()",
    576       "method:android.icu.util.TimeZone#getDefaultTimeZoneType()",
    577       "method:android.icu.util.TimeZone#setDefault(TimeZone)",
    578       "method:android.icu.util.TimeZone#setDefaultTimeZoneType(int)",
    579       "method:android.icu.util.ULocale#setDefault(Category,ULocale)",
    580       "method:android.icu.util.ULocale#setDefault(ULocale)",
    581       "method:android.icu.util.VersionInfo#main(String[])",
    582       "type:android.icu.text.Collator$CollatorFactory",
    583       "type:android.icu.text.NumberFormat$NumberFormatFactory",
    584       "type:android.icu.text.NumberFormat$SimpleNumberFormatFactory",
    585   };
    586 
    587   // The declarations with JavaDocs that have @.jcite tags that should be transformed to doclava
    588   // @sample tags. Ones not on this list will just be escaped and could show up in the generated
    589   // docs. It is assumed that the complete set of ones that should appear in the public API are
    590   // listed below and it's ok to escape those that are not.
    591   private static final String[] JCITE_TRANSFORM_SET = {
    592       "method:android.icu.text.DateIntervalFormat#getInstance(String,Locale)",
    593       "method:android.icu.text.DateIntervalFormat#getInstance(String,Locale,DateIntervalInfo)",
    594       "method:android.icu.text.DateTimePatternGenerator#addPattern(String,boolean,PatternInfo)",
    595       "method:android.icu.text.DateTimePatternGenerator#getBestPattern(String)",
    596       "method:android.icu.text.DateTimePatternGenerator#replaceFieldTypes(String,String)",
    597       "method:android.icu.text.PluralFormat#PluralFormat(ULocale,String)",
    598   };
    599 
    600   public static final String ANDROID_ICU4J_SAMPLE_DIR =
    601       "external/icu/android_icu4j/src/samples/java";
    602 
    603   private static final boolean DEBUG = false;
    604 
    605   static final String ORIGINAL_ICU_PACKAGE = "com.ibm.icu";
    606   static final String ANDROID_ICU_PACKAGE = "android.icu";
    607 
    608   private Icu4jTransform() {
    609   }
    610 
    611   /**
    612    * Usage:
    613    * java com.android.icu4j.srcgen.Icu4JTransform {source files/directories} {target dir}
    614    */
    615   public static void main(String[] args) throws Exception {
    616     new Main(DEBUG).execute(new Icu4jRules(args));
    617   }
    618 
    619   static class Icu4jRules implements Rules {
    620 
    621     private static final String SOURCE_CODE_HEADER = "/* GENERATED SOURCE. DO NOT MODIFY. */\n";
    622 
    623     private final InputFileGenerator inputFileGenerator;
    624     private final List<Rule> rules;
    625     private final BasicOutputSourceFileGenerator outputSourceFileGenerator;
    626 
    627     public Icu4jRules(String[] args) throws IOException {
    628       if (args.length < 2) {
    629         throw new IllegalArgumentException("At least 2 arguments required.");
    630       }
    631 
    632       String[] inputDirNames = new String[args.length - 1];
    633       System.arraycopy(args, 0, inputDirNames, 0, args.length - 1);
    634       inputFileGenerator = Icu4jTransformRules.createInputFileGenerator(inputDirNames);
    635       rules = createTransformRules();
    636       outputSourceFileGenerator =
    637           Icu4jTransformRules.createOutputFileGenerator(args[args.length - 1]);
    638     }
    639 
    640     @Override
    641     public List<Rule> getRuleList(File ignored) {
    642       return rules;
    643     }
    644 
    645     @Override
    646     public InputFileGenerator getInputFileGenerator() {
    647       return inputFileGenerator;
    648     }
    649 
    650     @Override
    651     public OutputSourceFileGenerator getOutputSourceFileGenerator() {
    652       return outputSourceFileGenerator;
    653     }
    654 
    655     // Rules for migrating com.ibm.icu source over to android.icu. Pulled out separately so they
    656     // can be used for modifying ICU4J sample code as well.
    657     static Rule[] getRepackagingRules() {
    658       return new Rule[] {
    659           // Doc change: Insert a warning about the source code being generated.
    660           createMandatoryRule(new InsertHeader(SOURCE_CODE_HEADER)),
    661           // AST change: Change the package of each CompilationUnit from com.ibm.icu to android.icu.
    662           createMandatoryRule(new RenamePackage(ORIGINAL_ICU_PACKAGE, ANDROID_ICU_PACKAGE)),
    663           // AST change: Change all qualified names in code and javadoc.
    664           createOptionalRule(new ModifyQualifiedNames(ORIGINAL_ICU_PACKAGE, ANDROID_ICU_PACKAGE)),
    665           // AST change: Change all string literals containing package names in code.
    666           createOptionalRule(new ModifyStringLiterals(ORIGINAL_ICU_PACKAGE, ANDROID_ICU_PACKAGE)),
    667           // AST change: Change all string literals containing paths in code.
    668           createOptionalRule(new ModifyStringLiterals("com/ibm/icu", "android/icu")),
    669       };
    670     }
    671 
    672     private static List<Rule> createTransformRules() throws IOException {
    673       // The rules needed to repackage source code that declares or references com.ibm.icu code
    674       // so it references android.icu instead.
    675       Rule[] repackageRules = getRepackagingRules();
    676 
    677       // The rules needed to fix up Android's documentation rules.
    678       Rule[] apiDocsRules = new Rule[] {
    679           // Below are the fixes that ensure the Android API documentation generation can be run
    680           // over the source.
    681 
    682           // Doc change: Switch all documentation references from com.ibm.icu to android.icu.
    683           // e.g. importantly in <code> blocks and unimportantly in non-Javadoc comments.
    684           createOptionalRule(
    685               new ReplaceTextCommentScanner(ORIGINAL_ICU_PACKAGE, ANDROID_ICU_PACKAGE)),
    686 
    687           // AST change: Hide all ICU public classes except those in the whitelist.
    688           createHidePublicClassesRule(),
    689 
    690           // AST change: Hide ICU methods that are deprecated and Android does not want to make
    691           // public.
    692           createHideOriginalDeprecatedClassesRule(),
    693           // AST change: Explicitly hide blacklisted methods such as those that get/set static
    694           // default values that might lead to confusion or strange interactions between Android's
    695           // ICU4J and java.text / java.util classes.
    696           createHideBlacklistedDeclarationsRule(),
    697           // AST change: Explicitly hide any elements that are marked as
    698           // @draft / @provisional / @internal
    699           createOptionalRule(new HideDraftProvisionalInternal()),
    700 
    701           // AST change: Remove JavaDoc tags that Android has no need of:
    702           // @hide has been added in place of @draft, @provisional and @internal
    703           // @stable <ICU version> will not mean much on Android.
    704           createOptionalRule(new RemoveJavaDocTags(
    705               "@stable", "@draft", "@provisional", "@internal", "@since")),
    706           // AST change: Replace @icu and @icuenhanced with standard text.
    707           createOptionalRule(new ReplaceIcuTags()),
    708 
    709           // AST change: Translate some of the @.jcite tags used by ICU into @sample tags used by
    710           // doclava. Those that are not translated are escaped.
    711           createTranslateJciteInclusionRule(),
    712       };
    713 
    714       List<Rule> rulesList = Lists.newArrayList(repackageRules);
    715       rulesList.addAll(Arrays.asList(apiDocsRules));
    716       return rulesList;
    717     }
    718 
    719     private static Rule createTranslateJciteInclusionRule() {
    720       List<BodyDeclarationLocator> whitelist =
    721           BodyDeclarationLocators.createLocatorsFromStrings(JCITE_TRANSFORM_SET);
    722       TranslateJcite.InclusionHandler transformer =
    723           new TranslateJcite.InclusionHandler(ANDROID_ICU4J_SAMPLE_DIR, whitelist);
    724       return createOptionalRule(transformer);
    725     }
    726 
    727     private static Rule createHideOriginalDeprecatedClassesRule() {
    728       List<BodyDeclarationLocator> blacklist =
    729           BodyDeclarationLocators.createLocatorsFromStrings(INITIAL_DEPRECATED_SET);
    730       return createOptionalRule(
    731           new TagMatchingDeclarations(blacklist, "@hide original deprecated declaration"));
    732     }
    733 
    734     private static Rule createHideBlacklistedDeclarationsRule() {
    735       List<BodyDeclarationLocator> blacklist =
    736           BodyDeclarationLocators.createLocatorsFromStrings(DECLARATIONS_TO_HIDE);
    737       return createOptionalRule(
    738           new TagMatchingDeclarations(blacklist, "@hide unsupported on Android"));
    739     }
    740 
    741     private static Rule createHidePublicClassesRule() {
    742       ImmutableList.Builder<TypeLocator> apiClassesWhitelistBuilder = ImmutableList.builder();
    743       for (String publicClassName : PUBLIC_API_CLASSES) {
    744         apiClassesWhitelistBuilder.add(new TypeLocator(publicClassName));
    745       }
    746       return createOptionalRule(
    747           new HidePublicClasses(
    748               apiClassesWhitelistBuilder.build(),
    749               "Only a subset of ICU is exposed in Android"));
    750     }
    751   }
    752 }
    753