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