• 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 static com.google.currysrc.api.process.Rules.createMandatoryRule;
19 import static com.google.currysrc.api.process.Rules.createOptionalRule;
20 
21 import org.eclipse.jdt.core.JavaCore;
22 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
23 
24 import com.google.common.collect.Lists;
25 import com.google.currysrc.Main;
26 import com.google.currysrc.aosp.Annotations;
27 import com.google.currysrc.api.RuleSet;
28 import com.google.currysrc.api.input.InputFileGenerator;
29 import com.google.currysrc.api.output.BasicOutputSourceFileGenerator;
30 import com.google.currysrc.api.output.OutputSourceFileGenerator;
31 import com.google.currysrc.api.process.Rule;
32 import com.google.currysrc.api.process.ast.BodyDeclarationLocator;
33 import com.google.currysrc.api.process.ast.BodyDeclarationLocators;
34 import com.google.currysrc.api.process.ast.TypeLocator;
35 import com.google.currysrc.processors.AddAnnotation;
36 import com.google.currysrc.processors.AddDefaultConstructor;
37 import com.google.currysrc.processors.AnnotationInfo;
38 import com.google.currysrc.processors.HidePublicClasses;
39 import com.google.currysrc.processors.InsertHeader;
40 import com.google.currysrc.processors.ModifyQualifiedNames;
41 import com.google.currysrc.processors.ModifyStringLiterals;
42 import com.google.currysrc.processors.RemoveJavaDocTags;
43 import com.google.currysrc.processors.RenamePackage;
44 import com.google.currysrc.processors.ReplaceTextCommentScanner;
45 
46 import java.io.File;
47 import java.nio.file.Path;
48 import java.nio.file.Paths;
49 import java.util.Arrays;
50 import java.util.List;
51 import java.util.Map;
52 import java.util.stream.Collectors;
53 
54 /**
55  * Applies Android's ICU4J source code transformation rules. If you make any changes to this class
56  * then you should re-run the generate_android_icu4j.sh script.
57  */
58 public class Icu4jTransform {
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.UCharacter$BidiPairedBracketType",
66       "android.icu.lang.UCharacter$DecompositionType",
67       "android.icu.lang.UCharacter$EastAsianWidth",
68       "android.icu.lang.UCharacter$GraphemeClusterBreak",
69       "android.icu.lang.UCharacter$HangulSyllableType",
70       "android.icu.lang.UCharacter$IndicPositionalCategory",
71       "android.icu.lang.UCharacter$IndicSyllabicCategory",
72       "android.icu.lang.UCharacter$JoiningGroup",
73       "android.icu.lang.UCharacter$JoiningType",
74       "android.icu.lang.UCharacter$LineBreak",
75       "android.icu.lang.UCharacter$NumericType",
76       "android.icu.lang.UCharacter$SentenceBreak",
77       "android.icu.lang.UCharacter$UnicodeBlock",
78       "android.icu.lang.UCharacter$VerticalOrientation",
79       "android.icu.lang.UCharacter$WordBreak",
80       "android.icu.lang.UCharacterCategory",
81       "android.icu.lang.UCharacterDirection",
82       "android.icu.lang.UCharacterEnums",
83       "android.icu.lang.UCharacterEnums$ECharacterCategory",
84       "android.icu.lang.UCharacterEnums$ECharacterDirection",
85       "android.icu.lang.UProperty",
86       "android.icu.lang.UProperty$NameChoice",
87       "android.icu.lang.UScript",
88       "android.icu.lang.UScript$ScriptUsage",
89       "android.icu.math.BigDecimal",
90       "android.icu.math.MathContext",
91       "android.icu.number.CompactNotation",
92       "android.icu.number.CurrencyPrecision",
93       "android.icu.number.FormattedNumber",
94       "android.icu.number.FormattedNumberRange",
95       "android.icu.number.FractionPrecision",
96       "android.icu.number.IntegerWidth",
97       "android.icu.number.LocalizedNumberFormatter",
98       "android.icu.number.LocalizedNumberRangeFormatter",
99       "android.icu.number.Notation",
100       "android.icu.number.NumberFormatter",
101       "android.icu.number.NumberFormatter$DecimalSeparatorDisplay",
102       "android.icu.number.NumberFormatter$GroupingStrategy",
103       "android.icu.number.NumberFormatter$RoundingPriority",
104       "android.icu.number.NumberFormatter$SignDisplay",
105       "android.icu.number.NumberFormatter$TrailingZeroDisplay",
106       "android.icu.number.NumberFormatter$UnitWidth",
107       "android.icu.number.NumberFormatterSettings",
108       "android.icu.number.NumberRangeFormatter",
109       "android.icu.number.NumberRangeFormatter$RangeCollapse",
110       "android.icu.number.NumberRangeFormatter$RangeIdentityFallback",
111       "android.icu.number.NumberRangeFormatter$RangeIdentityResult",
112       "android.icu.number.NumberRangeFormatterSettings",
113       "android.icu.number.Precision",
114       "android.icu.number.Scale",
115       "android.icu.number.ScientificNotation",
116       "android.icu.number.SimpleNotation",
117       "android.icu.number.UnlocalizedNumberFormatter",
118       "android.icu.number.UnlocalizedNumberRangeFormatter",
119       "android.icu.text.AlphabeticIndex",
120       "android.icu.text.AlphabeticIndex$Bucket",
121       "android.icu.text.AlphabeticIndex$Bucket$LabelType",
122       "android.icu.text.AlphabeticIndex$ImmutableIndex",
123       "android.icu.text.AlphabeticIndex$Record",
124       "android.icu.text.Bidi",
125       "android.icu.text.BidiClassifier",
126       "android.icu.text.BidiRun",
127       "android.icu.text.BreakIterator",
128       "android.icu.text.CaseMap",
129       "android.icu.text.CaseMap$Fold",
130       "android.icu.text.CaseMap$Lower",
131       "android.icu.text.CaseMap$Title",
132       "android.icu.text.CaseMap$Upper",
133       "android.icu.text.CollationElementIterator",
134       "android.icu.text.CollationKey",
135       "android.icu.text.CollationKey$BoundMode",
136       "android.icu.text.Collator",
137       "android.icu.text.Collator$CollatorFactory",
138       "android.icu.text.Collator$ReorderCodes",
139       "android.icu.text.CompactDecimalFormat",
140       "android.icu.text.CompactDecimalFormat$CompactStyle",
141       "android.icu.text.ConstrainedFieldPosition",
142       "android.icu.text.CurrencyPluralInfo",
143       "android.icu.text.DateFormat",
144       "android.icu.text.DateFormat$BooleanAttribute",
145       "android.icu.text.DateFormat$Field",
146       "android.icu.text.DateFormat$HourCycle",
147       "android.icu.text.DateFormatSymbols",
148       "android.icu.text.DateIntervalFormat",
149       "android.icu.text.DateIntervalFormat$FormattedDateInterval",
150       "android.icu.text.DateIntervalInfo",
151       "android.icu.text.DateIntervalInfo$PatternInfo",
152       "android.icu.text.DateTimePatternGenerator",
153       "android.icu.text.DateTimePatternGenerator$DisplayWidth",
154       "android.icu.text.DateTimePatternGenerator$PatternInfo",
155       "android.icu.text.DecimalFormat",
156       "android.icu.text.DecimalFormatSymbols",
157       "android.icu.text.DisplayContext",
158       "android.icu.text.DisplayContext$Type",
159       "android.icu.text.DisplayOptions",
160       "android.icu.text.DisplayOptions$Builder",
161       "android.icu.text.DisplayOptions$Capitalization",
162       "android.icu.text.DisplayOptions$DisplayLength",
163       "android.icu.text.DisplayOptions$GrammaticalCase",
164       "android.icu.text.DisplayOptions$NameStyle",
165       "android.icu.text.DisplayOptions$NounClass",
166       "android.icu.text.DisplayOptions$PluralCategory",
167       "android.icu.text.DisplayOptions$SubstituteHandling",
168       "android.icu.text.Edits",
169       "android.icu.text.Edits$Iterator",
170       "android.icu.text.FormattedValue",
171       "android.icu.text.IDNA",
172       "android.icu.text.IDNA$Error",
173       "android.icu.text.IDNA$Info",
174       "android.icu.text.ListFormatter",
175       "android.icu.text.ListFormatter$FormattedList",
176       "android.icu.text.ListFormatter$Type",
177       "android.icu.text.ListFormatter$Width",
178       "android.icu.text.LocaleDisplayNames",
179       "android.icu.text.LocaleDisplayNames$DialectHandling",
180       "android.icu.text.LocaleDisplayNames$UiListItem",
181       "android.icu.text.MeasureFormat",
182       "android.icu.text.MeasureFormat$FormatWidth",
183       "android.icu.text.MessageFormat",
184       "android.icu.text.MessageFormat$Field",
185       "android.icu.text.MessagePattern",
186       "android.icu.text.MessagePattern$ApostropheMode",
187       "android.icu.text.MessagePattern$ArgType",
188       "android.icu.text.MessagePattern$Part",
189       "android.icu.text.MessagePattern$Part$Type",
190       "android.icu.text.Normalizer",
191       "android.icu.text.Normalizer$QuickCheckResult",
192       "android.icu.text.Normalizer2",
193       "android.icu.text.Normalizer2$Mode",
194       "android.icu.text.NumberFormat",
195       "android.icu.text.NumberFormat$Field",
196       "android.icu.text.NumberingSystem",
197       "android.icu.text.PluralFormat",
198       "android.icu.text.PluralRules",
199       "android.icu.text.PluralRules$PluralType",
200       "android.icu.text.RelativeDateTimeFormatter",
201       "android.icu.text.RelativeDateTimeFormatter$AbsoluteUnit",
202       "android.icu.text.RelativeDateTimeFormatter$Direction",
203       "android.icu.text.RelativeDateTimeFormatter$FormattedRelativeDateTime",
204       "android.icu.text.RelativeDateTimeFormatter$RelativeDateTimeUnit",
205       "android.icu.text.RelativeDateTimeFormatter$RelativeUnit",
206       "android.icu.text.RelativeDateTimeFormatter$Style",
207       "android.icu.text.Replaceable",
208       "android.icu.text.RuleBasedCollator",
209       "android.icu.text.ScientificNumberFormatter",
210       "android.icu.text.SearchIterator",
211       "android.icu.text.SearchIterator$ElementComparisonType",
212       "android.icu.text.SelectFormat",
213       "android.icu.text.SimpleDateFormat",
214       "android.icu.text.StringPrepParseException",
215       "android.icu.text.StringSearch",
216       "android.icu.text.SymbolTable",
217       "android.icu.text.TimeZoneFormat",
218       "android.icu.text.TimeZoneFormat$GMTOffsetPatternType",
219       "android.icu.text.TimeZoneFormat$ParseOption",
220       "android.icu.text.TimeZoneFormat$Style",
221       "android.icu.text.TimeZoneFormat$TimeType",
222       "android.icu.text.TimeZoneNames",
223       "android.icu.text.TimeZoneNames$NameType",
224       "android.icu.text.Transliterator",
225       "android.icu.text.Transliterator$Position",
226       "android.icu.text.UCharacterIterator",
227       "android.icu.text.UFormat",
228       "android.icu.text.UnicodeFilter",
229       "android.icu.text.UnicodeMatcher",
230       "android.icu.text.UnicodeSet",
231       "android.icu.text.UnicodeSet$ComparisonStyle",
232       "android.icu.text.UnicodeSet$EntryRange",
233       "android.icu.text.UnicodeSet$SpanCondition",
234       "android.icu.text.UnicodeSetIterator",
235       "android.icu.text.UnicodeSetSpanner",
236       "android.icu.text.UnicodeSetSpanner$CountMethod",
237       "android.icu.text.UnicodeSetSpanner$TrimOption",
238       "android.icu.util.BuddhistCalendar",
239       "android.icu.util.CECalendar",
240       "android.icu.util.Calendar",
241       "android.icu.util.Calendar$WeekData",
242       "android.icu.util.ChineseCalendar",
243       "android.icu.util.CopticCalendar",
244       "android.icu.util.Currency",
245       "android.icu.util.Currency$CurrencyUsage",
246       "android.icu.util.CurrencyAmount",
247       "android.icu.util.DateInterval",
248       "android.icu.util.EthiopicCalendar",
249       "android.icu.util.Freezable",
250       "android.icu.util.GregorianCalendar",
251       "android.icu.util.HebrewCalendar",
252       "android.icu.util.ICUUncheckedIOException",
253       "android.icu.util.IllformedLocaleException",
254       "android.icu.util.IndianCalendar",
255       "android.icu.util.IslamicCalendar",
256       "android.icu.util.IslamicCalendar$CalculationType",
257       "android.icu.util.JapaneseCalendar",
258       "android.icu.util.LocaleData",
259       "android.icu.util.LocaleData$MeasurementSystem",
260       "android.icu.util.LocaleData$PaperSize",
261       "android.icu.util.Measure",
262       "android.icu.util.MeasureUnit",
263       "android.icu.util.MeasureUnit$Complexity",
264       "android.icu.util.MeasureUnit$MeasurePrefix",
265       "android.icu.util.Output",
266       "android.icu.util.RangeValueIterator",
267       "android.icu.util.RangeValueIterator$Element",
268       "android.icu.util.TaiwanCalendar",
269       "android.icu.util.TimeUnit",
270       "android.icu.util.TimeZone",
271       "android.icu.util.TimeZone$SystemTimeZoneType",
272       "android.icu.util.ULocale",
273       "android.icu.util.ULocale$AvailableType",
274       "android.icu.util.ULocale$Builder",
275       "android.icu.util.ULocale$Category",
276       "android.icu.util.UniversalTimeScale",
277       "android.icu.util.ValueIterator",
278       "android.icu.util.ValueIterator$Element",
279       "android.icu.util.VersionInfo",
280 
281   };
282 
283   /**
284    * The set of deprecated ICU types/methods/fields that must not be part of the public API as they
285    * were deprecated when Android first exposed their classes as a public API. Methods deprecated by
286    * ICU after this will be visible and deprecated in Android.
287    */
288   // This list was originally generated by the CaptureDeprecatedElements tool when run against
289   // ICU56 with the original PUBLIC_API_CLASSES.
290   private static final String[] INITIAL_DEPRECATED_SET = new String[] {
291       /* ASCII order please. */
292       "field:android.icu.lang.UProperty#ISO_COMMENT",
293       "field:android.icu.lang.UProperty#UNDEFINED",
294       "field:android.icu.lang.UProperty#UNICODE_1_NAME",
295       "field:android.icu.lang.UScript#DUPLOYAN_SHORTAND",
296       "field:android.icu.text.Bidi#CLASS_DEFAULT",
297       "field:android.icu.text.CaseMap#internalOptions",
298       "field:android.icu.text.DateFormat#ABBR_STANDALONE_MONTH",
299       "field:android.icu.text.DateFormat#DATE_SKELETONS",
300       "field:android.icu.text.DateFormat#HOUR_GENERIC_TZ",
301       "field:android.icu.text.DateFormat#HOUR_MINUTE_GENERIC_TZ",
302       "field:android.icu.text.DateFormat#HOUR_MINUTE_TZ",
303       "field:android.icu.text.DateFormat#HOUR_TZ",
304       "field:android.icu.text.DateFormat#STANDALONE_MONTH",
305       "field:android.icu.text.DateFormat#TIME_SKELETONS",
306       "field:android.icu.text.DateFormat#ZONE_SKELETONS",
307       "field:android.icu.text.DateFormatSymbols#DT_CONTEXT_COUNT",
308       "field:android.icu.text.DateFormatSymbols#DT_WIDTH_COUNT",
309       "field:android.icu.text.DateFormatSymbols#NUMERIC",
310       "field:android.icu.text.DateTimePatternGenerator#MATCH_MINUTE_FIELD_LENGTH",
311       "field:android.icu.text.DateTimePatternGenerator#MATCH_SECOND_FIELD_LENGTH",
312       "field:android.icu.text.IDNA#ALLOW_UNASSIGNED",
313       "field:android.icu.text.Normalizer#COMPARE_NORM_OPTIONS_SHIFT",
314       "field:android.icu.text.Normalizer#COMPOSE",
315       "field:android.icu.text.Normalizer#COMPOSE_COMPAT",
316       "field:android.icu.text.Normalizer#DECOMP",
317       "field:android.icu.text.Normalizer#DECOMP_COMPAT",
318       "field:android.icu.text.Normalizer#DEFAULT",
319       "field:android.icu.text.Normalizer#DONE",
320       "field:android.icu.text.Normalizer#FCD",
321       "field:android.icu.text.Normalizer#IGNORE_HANGUL",
322       "field:android.icu.text.Normalizer#NFC",
323       "field:android.icu.text.Normalizer#NFD",
324       "field:android.icu.text.Normalizer#NFKC",
325       "field:android.icu.text.Normalizer#NFKD",
326       "field:android.icu.text.Normalizer#NONE",
327       "field:android.icu.text.Normalizer#NO_OP",
328       "field:android.icu.text.Normalizer#UNICODE_3_2",
329       "field:android.icu.text.PluralRules#CATEGORY_SEPARATOR",
330       "field:android.icu.text.PluralRules#KEYWORD_RULE_SEPARATOR",
331       "field:android.icu.text.PluralRules$FixedDecimal#decimalDigits",
332       "field:android.icu.text.PluralRules$FixedDecimal#decimalDigitsWithoutTrailingZeros",
333       "field:android.icu.text.PluralRules$FixedDecimal#hasIntegerValue",
334       "field:android.icu.text.PluralRules$FixedDecimal#integerValue",
335       "field:android.icu.text.PluralRules$FixedDecimal#isNegative",
336       "field:android.icu.text.PluralRules$FixedDecimal#source",
337       "field:android.icu.text.PluralRules$FixedDecimal#visibleDecimalDigitCount",
338       "field:android.icu.text.PluralRules$FixedDecimal#visibleDecimalDigitCountWithoutTrailingZeros",
339       "field:android.icu.text.PluralRules$FixedDecimalRange#end",
340       "field:android.icu.text.PluralRules$FixedDecimalRange#start",
341       "field:android.icu.text.PluralRules$FixedDecimalSamples#bounded",
342       "field:android.icu.text.PluralRules$FixedDecimalSamples#sampleType",
343       "field:android.icu.text.PluralRules$FixedDecimalSamples#samples",
344       "field:android.icu.text.PluralRules$StandardPluralCategories#COUNT",
345       "field:android.icu.text.PluralRules$StandardPluralCategories#VALUES",
346       "field:android.icu.text.UnicodeSetIterator#endElement",
347       "field:android.icu.text.UnicodeSetIterator#nextElement",
348       "field:android.icu.util.Calendar#WEEKDAY",
349       "field:android.icu.util.Calendar#WEEKEND",
350       "field:android.icu.util.Calendar#WEEKEND_CEASE",
351       "field:android.icu.util.Calendar#WEEKEND_ONSET",
352       "field:android.icu.util.LocaleData#DELIMITER_COUNT",
353       "field:android.icu.util.LocaleData#ES_COUNT",
354       "field:android.icu.util.LocaleData#ES_CURRENCY",
355       "field:android.icu.util.MeasureUnit#subType",
356       "field:android.icu.util.MeasureUnit#type",
357       "field:android.icu.util.VersionInfo#ICU_DATA_VERSION",
358       "field:android.icu.util.VersionInfo#ICU_DATA_VERSION_PATH",
359       "field:android.icu.util.VersionInfo#UCOL_TAILORINGS_VERSION",
360       "method:android.icu.lang.UCharacter#getCharFromName1_0(String)",
361       "method:android.icu.lang.UCharacter#getISOComment(int)",
362       "method:android.icu.lang.UCharacter#getName1_0(int)",
363       "method:android.icu.lang.UCharacter#getName1_0Iterator()",
364       "method:android.icu.lang.UCharacter#getPropertyValueEnumNoThrow(int,CharSequence)",
365       "method:android.icu.lang.UCharacter#getStringPropertyValue(int,int,int)",
366       "method:android.icu.lang.UCharacter#isJavaLetter(int)",
367       "method:android.icu.lang.UCharacter#isJavaLetterOrDigit(int)",
368       "method:android.icu.lang.UCharacter#isSpace(int)",
369       "method:android.icu.lang.UCharacter#toTitleFirst(ULocale,String)",
370       "method:android.icu.text.AlphabeticIndex#getFirstCharactersInScripts()",
371       "method:android.icu.text.BreakIterator#getBreakInstance(ULocale,int)",
372       "method:android.icu.text.CollationElementIterator#getRuleBasedCollator()",
373       "method:android.icu.text.CollationElementIterator#hashCode()",
374       "method:android.icu.text.Collator#doCompare(CharSequence,CharSequence)",
375       "method:android.icu.text.Collator#setStrength2(int)",
376       "method:android.icu.text.Collator#setVariableTop(String)",
377       "method:android.icu.text.Collator#setVariableTop(int)",
378       "method:android.icu.text.CompactDecimalFormat#CompactDecimalFormat(String,DecimalFormatSymbols,CompactStyle,PluralRules,long[],Map<String,String[][]>,Map<String,String[]>,Collection<String>)",
379       "method:android.icu.text.CurrencyPluralInfo#hashCode()",
380       "method:android.icu.text.DateFormatSymbols#getDateFormatBundle(Calendar,Locale)",
381       "method:android.icu.text.DateFormatSymbols#getDateFormatBundle(Calendar,ULocale)",
382       "method:android.icu.text.DateFormatSymbols#getDateFormatBundle(Class<? extends Calendar>,Locale)",
383       "method:android.icu.text.DateFormatSymbols#getDateFormatBundle(Class<? extends Calendar>,ULocale)",
384       "method:android.icu.text.DateFormatSymbols#getLeapMonthPattern(int,int)",
385       "method:android.icu.text.DateFormatSymbols#initializeData(ULocale,CalendarData)",
386       "method:android.icu.text.DateFormatSymbols#setLeapMonthPattern(String,int,int)",
387       "method:android.icu.text.DateIntervalFormat#DateIntervalFormat(String,DateIntervalInfo,SimpleDateFormat)",
388       "method:android.icu.text.DateIntervalFormat#getPatterns(Calendar,Calendar,Output<String>)",
389       "method:android.icu.text.DateIntervalFormat#getRawPatterns()",
390       "method:android.icu.text.DateIntervalFormat#parseObject(String,ParsePosition)",
391       "method:android.icu.text.DateIntervalInfo#DateIntervalInfo()",
392       "method:android.icu.text.DateIntervalInfo#genPatternInfo(String,boolean)",
393       "method:android.icu.text.DateIntervalInfo#getPatterns()",
394       "method:android.icu.text.DateIntervalInfo#getRawPatterns()",
395       "method:android.icu.text.DateTimePatternGenerator#addPatternWithSkeleton(String,String,boolean,PatternInfo)",
396       "method:android.icu.text.DateTimePatternGenerator#getAppendFormatNumber(String)",
397       "method:android.icu.text.DateTimePatternGenerator#getCanonicalSkeletonAllowingDuplicates(String)",
398       "method:android.icu.text.DateTimePatternGenerator#getDefaultHourFormatChar()",
399       "method:android.icu.text.DateTimePatternGenerator#getFields(String)",
400       "method:android.icu.text.DateTimePatternGenerator#getFrozenInstance(ULocale)",
401       "method:android.icu.text.DateTimePatternGenerator#getRedundants(Collection<String>)",
402       "method:android.icu.text.DateTimePatternGenerator#getSkeletonAllowingDuplicates(String)",
403       "method:android.icu.text.DateTimePatternGenerator#isSingleField(String)",
404       "method:android.icu.text.DateTimePatternGenerator#setDefaultHourFormatChar(char)",
405       "method:android.icu.text.DateTimePatternGenerator#skeletonsAreSimilar(String,String)",
406       "method:android.icu.text.DateTimePatternGenerator$FormatParser#FormatParser()",
407       "method:android.icu.text.DateTimePatternGenerator$FormatParser#getItems()",
408       "method:android.icu.text.DateTimePatternGenerator$FormatParser#hasDateAndTimeFields()",
409       "method:android.icu.text.DateTimePatternGenerator$FormatParser#quoteLiteral(String)",
410       "method:android.icu.text.DateTimePatternGenerator$FormatParser#set(String)",
411       "method:android.icu.text.DateTimePatternGenerator$FormatParser#set(String,boolean)",
412       "method:android.icu.text.DateTimePatternGenerator$FormatParser#toString()",
413       "method:android.icu.text.DateTimePatternGenerator$FormatParser#toString(int,int)",
414       "method:android.icu.text.DateTimePatternGenerator$VariableField#VariableField(String)",
415       "method:android.icu.text.DateTimePatternGenerator$VariableField#VariableField(String,boolean)",
416       "method:android.icu.text.DateTimePatternGenerator$VariableField#getCanonicalCode(int)",
417       "method:android.icu.text.DateTimePatternGenerator$VariableField#getType()",
418       "method:android.icu.text.DateTimePatternGenerator$VariableField#isNumeric()",
419       "method:android.icu.text.DateTimePatternGenerator$VariableField#toString()",
420       "method:android.icu.text.DecimalFormat#getEffectiveCurrency()",
421       "method:android.icu.text.DecimalFormatSymbols#getMinusString()",
422       "method:android.icu.text.DecimalFormatSymbols#getPlusString()",
423       "method:android.icu.text.IDNA#IDNA()",
424       "method:android.icu.text.IDNA#addError(Info,Error)",
425       "method:android.icu.text.IDNA#addLabelError(Info,Error)",
426       "method:android.icu.text.IDNA#compare(String,String,int)",
427       "method:android.icu.text.IDNA#compare(StringBuffer,StringBuffer,int)",
428       "method:android.icu.text.IDNA#compare(UCharacterIterator,UCharacterIterator,int)",
429       "method:android.icu.text.IDNA#convertIDNToASCII(String,int)",
430       "method:android.icu.text.IDNA#convertIDNToASCII(StringBuffer,int)",
431       "method:android.icu.text.IDNA#convertIDNToASCII(UCharacterIterator,int)",
432       "method:android.icu.text.IDNA#convertIDNToUnicode(String,int)",
433       "method:android.icu.text.IDNA#convertIDNToUnicode(StringBuffer,int)",
434       "method:android.icu.text.IDNA#convertIDNToUnicode(UCharacterIterator,int)",
435       "method:android.icu.text.IDNA#convertToASCII(String,int)",
436       "method:android.icu.text.IDNA#convertToASCII(StringBuffer,int)",
437       "method:android.icu.text.IDNA#convertToASCII(UCharacterIterator,int)",
438       "method:android.icu.text.IDNA#convertToUnicode(String,int)",
439       "method:android.icu.text.IDNA#convertToUnicode(StringBuffer,int)",
440       "method:android.icu.text.IDNA#convertToUnicode(UCharacterIterator,int)",
441       "method:android.icu.text.IDNA#hasCertainErrors(Info,EnumSet<Error>)",
442       "method:android.icu.text.IDNA#hasCertainLabelErrors(Info,EnumSet<Error>)",
443       "method:android.icu.text.IDNA#isBiDi(Info)",
444       "method:android.icu.text.IDNA#isOkBiDi(Info)",
445       "method:android.icu.text.IDNA#promoteAndResetLabelErrors(Info)",
446       "method:android.icu.text.IDNA#resetInfo(Info)",
447       "method:android.icu.text.IDNA#setBiDi(Info)",
448       "method:android.icu.text.IDNA#setNotOkBiDi(Info)",
449       "method:android.icu.text.IDNA#setTransitionalDifferent(Info)",
450       "method:android.icu.text.LocaleDisplayNames#LocaleDisplayNames()",
451       "method:android.icu.text.LocaleDisplayNames#scriptDisplayNameInContext(String)",
452       "method:android.icu.text.MeasureFormat#formatMeasureRange(Measure,Measure)",
453       "method:android.icu.text.MeasureFormat#getRangeFormat(ULocale,FormatWidth)",
454       "method:android.icu.text.MeasureFormat#getRangePattern(ULocale,FormatWidth)",
455       "method:android.icu.text.Normalizer#Normalizer(CharacterIterator,Mode,int)",
456       "method:android.icu.text.Normalizer#Normalizer(String,Mode,int)",
457       "method:android.icu.text.Normalizer#Normalizer(UCharacterIterator,Mode,int)",
458       "method:android.icu.text.Normalizer#clone()",
459       "method:android.icu.text.Normalizer#compose(String,boolean)",
460       "method:android.icu.text.Normalizer#compose(String,boolean,int)",
461       "method:android.icu.text.Normalizer#compose(char[],char[],boolean,int)",
462       "method:android.icu.text.Normalizer#compose(char[],int,int,char[],int,int,boolean,int)",
463       "method:android.icu.text.Normalizer#concatenate(String,String,Mode,int)",
464       "method:android.icu.text.Normalizer#concatenate(char[],char[],Mode,int)",
465       "method:android.icu.text.Normalizer#concatenate(char[],int,int,char[],int,int,char[],int,int,Normalizer.Mode,int)",
466       "method:android.icu.text.Normalizer#current()",
467       "method:android.icu.text.Normalizer#decompose(String,boolean)",
468       "method:android.icu.text.Normalizer#decompose(String,boolean,int)",
469       "method:android.icu.text.Normalizer#decompose(char[],char[],boolean,int)",
470       "method:android.icu.text.Normalizer#decompose(char[],int,int,char[],int,int,boolean,int)",
471       "method:android.icu.text.Normalizer#endIndex()",
472       "method:android.icu.text.Normalizer#first()",
473       "method:android.icu.text.Normalizer#getBeginIndex()",
474       "method:android.icu.text.Normalizer#getEndIndex()",
475       "method:android.icu.text.Normalizer#getFC_NFKC_Closure(int)",
476       "method:android.icu.text.Normalizer#getFC_NFKC_Closure(int,char[])",
477       "method:android.icu.text.Normalizer#getIndex()",
478       "method:android.icu.text.Normalizer#getLength()",
479       "method:android.icu.text.Normalizer#getMode()",
480       "method:android.icu.text.Normalizer#getOption(int)",
481       "method:android.icu.text.Normalizer#getText()",
482       "method:android.icu.text.Normalizer#getText(char[])",
483       "method:android.icu.text.Normalizer#isNormalized(String,Mode,int)",
484       "method:android.icu.text.Normalizer#isNormalized(char[],int,int,Mode,int)",
485       "method:android.icu.text.Normalizer#isNormalized(int,Mode,int)",
486       "method:android.icu.text.Normalizer#last()",
487       "method:android.icu.text.Normalizer#next()",
488       "method:android.icu.text.Normalizer#normalize(String,Mode)",
489       "method:android.icu.text.Normalizer#normalize(String,Mode,int)",
490       "method:android.icu.text.Normalizer#normalize(char[],char[],Mode,int)",
491       "method:android.icu.text.Normalizer#normalize(char[],int,int,char[],int,int,Mode,int)",
492       "method:android.icu.text.Normalizer#normalize(int,Mode)",
493       "method:android.icu.text.Normalizer#normalize(int,Mode,int)",
494       "method:android.icu.text.Normalizer#previous()",
495       "method:android.icu.text.Normalizer#quickCheck(String,Mode)",
496       "method:android.icu.text.Normalizer#quickCheck(String,Mode,int)",
497       "method:android.icu.text.Normalizer#quickCheck(char[],Mode,int)",
498       "method:android.icu.text.Normalizer#quickCheck(char[],int,int,Mode,int)",
499       "method:android.icu.text.Normalizer#reset()",
500       "method:android.icu.text.Normalizer#setIndex(int)",
501       "method:android.icu.text.Normalizer#setIndexOnly(int)",
502       "method:android.icu.text.Normalizer#setMode(Mode)",
503       "method:android.icu.text.Normalizer#setOption(int,boolean)",
504       "method:android.icu.text.Normalizer#setText(CharacterIterator)",
505       "method:android.icu.text.Normalizer#setText(String)",
506       "method:android.icu.text.Normalizer#setText(StringBuffer)",
507       "method:android.icu.text.Normalizer#setText(UCharacterIterator)",
508       "method:android.icu.text.Normalizer#setText(char[])",
509       "method:android.icu.text.Normalizer#startIndex()",
510       "method:android.icu.text.Normalizer$Mode#Mode()",
511       "method:android.icu.text.Normalizer$Mode#getNormalizer2(int)",
512       "method:android.icu.text.Normalizer2#Normalizer2()",
513       "method:android.icu.text.NumberFormat#getEffectiveCurrency()",
514       "method:android.icu.text.NumberFormat#getPattern(Locale,int)",
515       "method:android.icu.text.PluralFormat#setLocale(ULocale)",
516       "method:android.icu.text.PluralRules#addSample(String,Number,int,Set<Double>)",
517       "method:android.icu.text.PluralRules#compareTo(PluralRules)",
518       "method:android.icu.text.PluralRules#computeLimited(String,SampleType)",
519       "method:android.icu.text.PluralRules#getAllKeywordValues(String,SampleType)",
520       "method:android.icu.text.PluralRules#getDecimalSamples(String,SampleType)",
521       "method:android.icu.text.PluralRules#getKeywordStatus(String,int,Set<Double>,Output<Double>,SampleType)",
522       "method:android.icu.text.PluralRules#getRules(String)",
523       "method:android.icu.text.PluralRules#getSamples(String,SampleType)",
524       "method:android.icu.text.PluralRules#hashCode()",
525       "method:android.icu.text.PluralRules#isLimited(String)",
526       "method:android.icu.text.PluralRules#isLimited(String,SampleType)",
527       "method:android.icu.text.PluralRules#matches(FixedDecimal,String)",
528       "method:android.icu.text.PluralRules#select(FixedDecimal)",
529       "method:android.icu.text.PluralRules#select(double,int,long)",
530       "method:android.icu.text.PluralRules$Factory#Factory()",
531       "method:android.icu.text.PluralRules$Factory#forLocale(ULocale)",
532       "method:android.icu.text.PluralRules$Factory#forLocale(ULocale,PluralType)",
533       "method:android.icu.text.PluralRules$Factory#getAvailableULocales()",
534       "method:android.icu.text.PluralRules$Factory#getDefaultFactory()",
535       "method:android.icu.text.PluralRules$Factory#getFunctionalEquivalent(ULocale,boolean[])",
536       "method:android.icu.text.PluralRules$Factory#hasOverride(ULocale)",
537       "method:android.icu.text.PluralRules$FixedDecimal#FixedDecimal(String)",
538       "method:android.icu.text.PluralRules$FixedDecimal#FixedDecimal(double)",
539       "method:android.icu.text.PluralRules$FixedDecimal#FixedDecimal(double,int)",
540       "method:android.icu.text.PluralRules$FixedDecimal#FixedDecimal(double,int,long)",
541       "method:android.icu.text.PluralRules$FixedDecimal#FixedDecimal(long)",
542       "method:android.icu.text.PluralRules$FixedDecimal#compareTo(FixedDecimal)",
543       "method:android.icu.text.PluralRules$FixedDecimal#decimals(double)",
544       "method:android.icu.text.PluralRules$FixedDecimal#doubleValue()",
545       "method:android.icu.text.PluralRules$FixedDecimal#equals(Object)",
546       "method:android.icu.text.PluralRules$FixedDecimal#floatValue()",
547       "method:android.icu.text.PluralRules$FixedDecimal#get(Operand)",
548       "method:android.icu.text.PluralRules$FixedDecimal#getBaseFactor()",
549       "method:android.icu.text.PluralRules$FixedDecimal#getDecimalDigits()",
550       "method:android.icu.text.PluralRules$FixedDecimal#getDecimalDigitsWithoutTrailingZeros()",
551       "method:android.icu.text.PluralRules$FixedDecimal#getIntegerValue()",
552       "method:android.icu.text.PluralRules$FixedDecimal#getOperand(String)",
553       "method:android.icu.text.PluralRules$FixedDecimal#getShiftedValue()",
554       "method:android.icu.text.PluralRules$FixedDecimal#getSource()",
555       "method:android.icu.text.PluralRules$FixedDecimal#getVisibleDecimalDigitCount()",
556       "method:android.icu.text.PluralRules$FixedDecimal#getVisibleDecimalDigitCountWithoutTrailingZeros()",
557       "method:android.icu.text.PluralRules$FixedDecimal#hasIntegerValue()",
558       "method:android.icu.text.PluralRules$FixedDecimal#hashCode()",
559       "method:android.icu.text.PluralRules$FixedDecimal#intValue()",
560       "method:android.icu.text.PluralRules$FixedDecimal#isHasIntegerValue()",
561       "method:android.icu.text.PluralRules$FixedDecimal#isNegative()",
562       "method:android.icu.text.PluralRules$FixedDecimal#longValue()",
563       "method:android.icu.text.PluralRules$FixedDecimal#toString()",
564       "method:android.icu.text.PluralRules$FixedDecimalRange#FixedDecimalRange(FixedDecimal,FixedDecimal)",
565       "method:android.icu.text.PluralRules$FixedDecimalRange#toString()",
566       "method:android.icu.text.PluralRules$FixedDecimalSamples#addSamples(Set<Double>)",
567       "method:android.icu.text.PluralRules$FixedDecimalSamples#getSamples()",
568       "method:android.icu.text.PluralRules$FixedDecimalSamples#getStartEndSamples(Set<FixedDecimal>)",
569       "method:android.icu.text.PluralRules$FixedDecimalSamples#toString()",
570       "method:android.icu.text.RuleBasedCollator#doCompare(CharSequence,CharSequence)",
571       "method:android.icu.text.RuleBasedCollator#internalGetCEs(CharSequence)",
572       "method:android.icu.text.RuleBasedCollator#isHiraganaQuaternary()",
573       "method:android.icu.text.RuleBasedCollator#setHiraganaQuaternary(boolean)",
574       "method:android.icu.text.RuleBasedCollator#setHiraganaQuaternaryDefault()",
575       "method:android.icu.text.RuleBasedCollator#setVariableTop(String)",
576       "method:android.icu.text.RuleBasedCollator#setVariableTop(int)",
577       "method:android.icu.text.SearchIterator#setMatchNotFound()",
578       "method:android.icu.text.SimpleDateFormat#SimpleDateFormat(String,DateFormatSymbols,ULocale)",
579       "method:android.icu.text.SimpleDateFormat#getInstance(Calendar.FormatConfiguration)",
580       "method:android.icu.text.SimpleDateFormat#intervalFormatByAlgorithm(Calendar,Calendar,StringBuffer,FieldPosition)",
581       "method:android.icu.text.SimpleDateFormat#subFormat(StringBuffer,char,int,int,int,DisplayContext,FieldPosition,Calendar)",
582       "method:android.icu.text.SimpleDateFormat#subFormat(char,int,int,int,DisplayContext,FieldPosition,Calendar)",
583       "method:android.icu.text.SimpleDateFormat#zeroPaddingNumber(NumberFormat,StringBuffer,int,int,int)",
584       "method:android.icu.text.StringPrepParseException#hashCode()",
585       "method:android.icu.text.StringSearch#setMatchNotFound()",
586       "method:android.icu.text.TimeZoneNames#getDisplayNames(String,NameType[],long,String[],int)",
587       "method:android.icu.text.TimeZoneNames#loadAllDisplayNames()",
588       "method:android.icu.text.TimeZoneNames$Factory#Factory()",
589       "method:android.icu.text.TimeZoneNames$Factory#getTimeZoneNames(ULocale)",
590       "method:android.icu.text.UnicodeFilter#UnicodeFilter()",
591       "method:android.icu.text.UnicodeSet#addBridges(UnicodeSet)",
592       "method:android.icu.text.UnicodeSet#applyPattern(String,ParsePosition,SymbolTable,int)",
593       "method:android.icu.text.UnicodeSet#compare(Iterator<T>,Iterator<T>)",
594       "method:android.icu.text.UnicodeSet#findIn(CharSequence,int,boolean)",
595       "method:android.icu.text.UnicodeSet#findLastIn(CharSequence,int,boolean)",
596       "method:android.icu.text.UnicodeSet#getDefaultXSymbolTable()",
597       "method:android.icu.text.UnicodeSet#getRegexEquivalent()",
598       "method:android.icu.text.UnicodeSet#getSingleCodePoint(CharSequence)",
599       "method:android.icu.text.UnicodeSet#matchesAt(CharSequence,int)",
600       "method:android.icu.text.UnicodeSet#setDefaultXSymbolTable(XSymbolTable)",
601       "method:android.icu.text.UnicodeSet#spanAndCount(CharSequence,int,SpanCondition,OutputInt)",
602       "method:android.icu.text.UnicodeSet#stripFrom(CharSequence,boolean)",
603       "method:android.icu.text.UnicodeSetIterator#getSet()",
604       "method:android.icu.text.UnicodeSetIterator#loadRange(int)",
605       "method:android.icu.text.Transliterator#addSourceTargetSet(UnicodeSet,UnicodeSet,UnicodeSet)",
606       "method:android.icu.text.Transliterator#getFilterAsUnicodeSet(UnicodeSet)",
607       "method:android.icu.text.Transliterator#registerAny()",
608       "method:android.icu.util.Calendar#getDateTimePattern(Calendar,ULocale,int)",
609       "method:android.icu.util.Calendar#getDayOfWeekType(int)",
610       "method:android.icu.util.Calendar#getRelatedYear()",
611       "method:android.icu.util.Calendar#getWeekendTransition(int)",
612       "method:android.icu.util.Calendar#haveDefaultCentury()",
613       "method:android.icu.util.Calendar#setRelatedYear(int)",
614       "method:android.icu.util.Calendar$FormatConfiguration#getCalendar()",
615       "method:android.icu.util.Calendar$FormatConfiguration#getDateFormatSymbols()",
616       "method:android.icu.util.Calendar$FormatConfiguration#getLocale()",
617       "method:android.icu.util.Calendar$FormatConfiguration#getOverrideString()",
618       "method:android.icu.util.Calendar$FormatConfiguration#getPatternString()",
619       "method:android.icu.util.ChineseCalendar#ChineseCalendar(TimeZone,ULocale,int,TimeZone)",
620       "method:android.icu.util.ChineseCalendar#haveDefaultCentury()",
621       "method:android.icu.util.CopticCalendar#getJDEpochOffset()",
622       "method:android.icu.util.CopticCalendar#handleComputeFields(int)",
623       "method:android.icu.util.CopticCalendar#handleGetExtendedYear()",
624       "method:android.icu.util.Currency#parse(ULocale,String,int,ParsePosition)",
625       "method:android.icu.util.HebrewCalendar#isLeapYear(int)",
626       "method:android.icu.util.HebrewCalendar#validateField(int)",
627       "method:android.icu.util.JapaneseCalendar#haveDefaultCentury()",
628       "method:android.icu.util.MeasureUnit#MeasureUnit(String,String)",
629       "method:android.icu.util.MeasureUnit#addUnit(String,String,Factory)",
630       "method:android.icu.util.MeasureUnit#internalGetInstance(String,String)",
631       "method:android.icu.util.MeasureUnit#resolveUnitPerUnit(MeasureUnit,MeasureUnit)",
632       "method:android.icu.util.MeasureUnit$Factory#create(String,String)",
633       "method:android.icu.util.TimeZone#TimeZone(String)",
634       "method:android.icu.util.ULocale#getDisplayScriptInContext()",
635       "method:android.icu.util.ULocale#getDisplayScriptInContext(String,String)",
636       "method:android.icu.util.ULocale#getDisplayScriptInContext(String,ULocale)",
637       "method:android.icu.util.ULocale#getDisplayScriptInContext(ULocale)",
638       "method:android.icu.util.ULocale#minimizeSubtags(ULocale,Minimize)",
639       "method:android.icu.util.VersionInfo#getVersionString(int,int)",
640       "method:android.icu.util.VersionInfo#javaVersion()",
641       "type:android.icu.text.DateTimePatternGenerator$FormatParser",
642       "type:android.icu.text.DateTimePatternGenerator$VariableField",
643       "type:android.icu.text.Normalizer$Mode",
644       "type:android.icu.text.PluralRules$Factory",
645       "type:android.icu.text.PluralRules$FixedDecimal",
646       "type:android.icu.text.PluralRules$FixedDecimalRange",
647       "type:android.icu.text.PluralRules$FixedDecimalSamples",
648       "type:android.icu.text.PluralRules$SampleType",
649       "type:android.icu.text.PluralRules$StandardPluralCategories",
650       "type:android.icu.text.TimeZoneNames$Factory",
651       "type:android.icu.util.Calendar$FormatConfiguration",
652       "type:android.icu.util.MeasureUnit$Factory",
653       "type:android.icu.util.ULocale$Minimize",
654   };
655 
656   /**
657    * A set of declarations we don't want to expose in Android.
658    * We generally hide:
659    * Any API we find that relates to a final static primitive that a compiler could inline
660    * and could change between ICU releases.
661    * Methods that relate to registration of static defaults / factories, which cannot be
662    * configured on Android "before use", because a lot of initialization happens in the zygote.
663    */
664   private static final String[] DECLARATIONS_TO_HIDE = {
665       /* ASCII order please. */
666       "field:android.icu.lang.UCharacter$BidiPairedBracketType#COUNT",
667       "field:android.icu.lang.UCharacter$DecompositionType#COUNT",
668       "field:android.icu.lang.UCharacter$EastAsianWidth#COUNT",
669       "field:android.icu.lang.UCharacter$GraphemeClusterBreak#COUNT",
670       "field:android.icu.lang.UCharacter$HangulSyllableType#COUNT",
671       "field:android.icu.lang.UCharacter$JoiningGroup#COUNT",
672       "field:android.icu.lang.UCharacter$JoiningType#COUNT",
673       "field:android.icu.lang.UCharacter$LineBreak#COUNT",
674       "field:android.icu.lang.UCharacter$NumericType#COUNT",
675       "field:android.icu.lang.UCharacter$SentenceBreak#COUNT",
676       "field:android.icu.lang.UCharacter$UnicodeBlock#COUNT",
677       "field:android.icu.lang.UCharacter$WordBreak#COUNT",
678       "field:android.icu.lang.UCharacterEnums$ECharacterCategory#CHAR_CATEGORY_COUNT",
679       "field:android.icu.lang.UCharacterEnums$ECharacterDirection#CHAR_DIRECTION_COUNT",
680       "field:android.icu.lang.UProperty#BINARY_LIMIT",
681       "field:android.icu.lang.UProperty#DOUBLE_LIMIT",
682       "field:android.icu.lang.UProperty#INT_LIMIT",
683       "field:android.icu.lang.UProperty#MASK_LIMIT",
684       "field:android.icu.lang.UProperty#OTHER_PROPERTY_LIMIT",
685       "field:android.icu.lang.UProperty#STRING_LIMIT",
686       "field:android.icu.lang.UProperty$NameChoice#COUNT",
687       "field:android.icu.lang.UScript#CODE_LIMIT",
688       "field:android.icu.text.BidiClassifier#context",
689       "field:android.icu.text.CollationKey$BoundMode#COUNT",
690       "field:android.icu.text.Collator$ReorderCodes#LIMIT",
691       "field:android.icu.text.DateFormat#FIELD_COUNT",
692       "field:android.icu.text.DateTimePatternGenerator#TYPE_LIMIT",
693       "field:android.icu.util.LocaleData#ES_AUXILIARY",
694       "field:android.icu.util.LocaleData#ES_INDEX",
695       "field:android.icu.util.LocaleData#ES_PUNCTUATION",
696       "field:android.icu.util.LocaleData#ES_STANDARD",
697       // Hide new measure units until a clear use case on Android is found.
698       // The cost of these APIs is the storage due to the additional locale data embedded
699       // in the ICU data file.
700       "field:android.icu.util.MeasureUnit#DUNAM",
701       "field:android.icu.util.MeasureUnit#MOLE",
702       "field:android.icu.util.MeasureUnit#PERMYRIAD",
703       "field:android.icu.util.MeasureUnit#DAY_PERSON",
704       "field:android.icu.util.MeasureUnit#MONTH_PERSON",
705       "field:android.icu.util.MeasureUnit#WEEK_PERSON",
706       "field:android.icu.util.MeasureUnit#YEAR_PERSON",
707       "field:android.icu.util.MeasureUnit#BRITISH_THERMAL_UNIT",
708       "field:android.icu.util.MeasureUnit#ELECTRONVOLT",
709       "field:android.icu.util.MeasureUnit#NEWTON",
710       "field:android.icu.util.MeasureUnit#POUND_FORCE",
711       "field:android.icu.util.MeasureUnit#SOLAR_RADIUS",
712       "field:android.icu.util.MeasureUnit#SOLAR_LUMINOSITY",
713       "field:android.icu.util.MeasureUnit#DALTON",
714       "field:android.icu.util.MeasureUnit#EARTH_MASS",
715       "field:android.icu.util.MeasureUnit#SOLAR_MASS",
716       "field:android.icu.util.MeasureUnit#KILOPASCAL",
717       "field:android.icu.util.MeasureUnit#MEGAPASCAL",
718       "field:android.icu.util.MeasureUnit#NEWTON_METER",
719       "field:android.icu.util.MeasureUnit#POUND_FOOT",
720       "field:android.icu.util.MeasureUnit#BARREL",
721       "field:android.icu.util.MeasureUnit#FLUID_OUNCE_IMPERIAL",
722       "field:android.icu.util.MeasureUnit#BAR",
723       "field:android.icu.util.MeasureUnit#PASCAL",
724       "field:android.icu.util.MeasureUnit#THERM_US",
725       "field:android.icu.util.MeasureUnit#EARTH_RADIUS",
726       "field:android.icu.util.MeasureUnit#GRAIN",
727       "field:android.icu.util.MeasureUnit#DESSERT_SPOON",
728       "field:android.icu.util.MeasureUnit#DESSERT_SPOON_IMPERIAL",
729       "field:android.icu.util.MeasureUnit#DRAM",
730       "field:android.icu.util.MeasureUnit#DROP",
731       "field:android.icu.util.MeasureUnit#JIGGER",
732       "field:android.icu.util.MeasureUnit#PINCH",
733       "field:android.icu.util.MeasureUnit#QUART_IMPERIAL",
734       // Skeleton syntax can evolve over time. Currently, the skeleton APIs are not prioritized to
735       // be public. Android developers could easily miss the API version check for new syntax and
736       // cause app crashing on older devices.
737       // See the syntax details in https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md.
738       "method:android.icu.number.NumberFormatterSettings#toSkeleton()",
739       "method:android.icu.number.NumberFormatter#forSkeleton(String)",
740       "method:android.icu.text.BreakIterator#registerInstance(BreakIterator,Locale,int)",
741       "method:android.icu.text.BreakIterator#registerInstance(BreakIterator,ULocale,int)",
742       "method:android.icu.text.BreakIterator#unregister(Object)",
743       "method:android.icu.text.CollationKey#CollationKey(String,RawCollationKey)",
744       "method:android.icu.text.Collator#getRawCollationKey(String,RawCollationKey)",
745       "method:android.icu.text.Collator#registerFactory(CollatorFactory)",
746       "method:android.icu.text.Collator#registerInstance(Collator,ULocale)",
747       "method:android.icu.text.Collator#unregister(Object)",
748       "method:android.icu.text.DecimalFormat#toNumberFormatter()",
749       "method:android.icu.text.DecimalFormatSymbols#getCurrencyPattern()",
750       "method:android.icu.text.NumberFormat#registerFactory(NumberFormatFactory)",
751       "method:android.icu.text.NumberFormat#unregister(Object)",
752       "method:android.icu.text.RuleBasedCollator#getRawCollationKey(String,RawCollationKey)",
753       "method:android.icu.text.UnicodeSet#addAllTo(Iterable<T>,T[])",
754       "method:android.icu.text.UnicodeSet#addAllTo(Iterable<T>,U)",
755       "method:android.icu.text.UnicodeSet#addAllTo(String[])",
756       "method:android.icu.text.UnicodeSet#compare(CharSequence,int)",
757       "method:android.icu.text.UnicodeSet#compare(Collection<T>,Collection<T>,ComparisonStyle)",
758       "method:android.icu.text.UnicodeSet#compare(Iterable<T>,Iterable<T>)",
759       "method:android.icu.text.UnicodeSet#compare(int,CharSequence)",
760       "method:android.icu.text.UnicodeSet#resemblesPattern(String,int)",
761       "method:android.icu.text.UnicodeSet#toArray(UnicodeSet)",
762       "method:android.icu.text.Transliterator#Transliterator(String,UnicodeFilter)",
763       "method:android.icu.text.Transliterator#baseToRules(boolean)",
764       "method:android.icu.text.Transliterator#handleGetSourceSet()",
765       "method:android.icu.text.Transliterator#handleTransliterate(Replaceable,Position,boolean)",
766       "method:android.icu.text.Transliterator#registerAlias(String,String)",
767       "method:android.icu.text.Transliterator#registerClass(String,Class<? extends Transliterator>,String)",
768       "method:android.icu.text.Transliterator#registerFactory(String,Factory)",
769       "method:android.icu.text.Transliterator#registerInstance(Transliterator)",
770       "method:android.icu.text.Transliterator#transform(String)",
771       "method:android.icu.text.Transliterator#unregister(String)",
772       "method:android.icu.text.Transliterator#setID(String)",
773       "method:android.icu.text.Transliterator#setMaximumContextLength(int)",
774       "method:android.icu.util.CECalendar#ceToJD(long,int,int,int)",
775       "method:android.icu.util.CECalendar#getJDEpochOffset()",
776       "method:android.icu.util.CECalendar#jdToCE(int,int,int[])",
777       "method:android.icu.util.Currency#registerInstance(Currency,ULocale)",
778       "method:android.icu.util.Currency#unregister(Object)",
779       "method:android.icu.util.IslamicCalendar#isCivil()",
780       "method:android.icu.util.IslamicCalendar#setCivil(boolean)",
781       "method:android.icu.util.LocaleData#getExemplarSet(int,int)",
782       "method:android.icu.util.LocaleData#getExemplarSet(ULocale,int)",
783       "method:android.icu.util.LocaleData#getExemplarSet(ULocale,int,int)",
784       "method:android.icu.util.LocaleData#getLocaleDisplayPattern()",
785       "method:android.icu.util.LocaleData#getLocaleSeparator()",
786       "method:android.icu.util.TimeZone#clearCachedDefault()",
787       "method:android.icu.util.TimeZone#getDefaultTimeZoneType()",
788       "method:android.icu.util.TimeZone#setDefault(TimeZone)",
789       "method:android.icu.util.TimeZone#setDefaultTimeZoneType(int)",
790       "method:android.icu.util.ULocale#setDefault(Category,ULocale)",
791       "method:android.icu.util.ULocale#setDefault(ULocale)",
792       "method:android.icu.util.VersionInfo#main(String[])",
793       "type:android.icu.text.Collator$CollatorFactory",
794       "type:android.icu.text.NumberFormat$NumberFormatFactory",
795       "type:android.icu.text.NumberFormat$SimpleNumberFormatFactory",
796   };
797 
798   /**
799    * ICU APIs that are in the Android SDK API but are deprecated on Android and not deprecated in
800    * ICU. Entries can be removed if ICU also decide to deprecate.
801    * Entries are usually the result of Android mistakenly exposing an API, an ICU API problem,
802    * and/or ICU's stability guarantees differing from Android's requirements.
803    */
804   private static final Map<String, String> ANDROID_DEPRECATED_SET = Map.of(
805       /* ASCII order please. */
806 
807       // Unstable "constant" value - different values in different API levels. http://b/77850660.
808       "field:android.icu.util.JapaneseCalendar#CURRENT_ERA",
809           "Use era constants, e.g. {@link #REIWA}, instead.",
810       // The method reads unstable .nrm file format. http://b/173821060
811       "method:android.icu.text.Normalizer2#getInstance(InputStream,String,Mode)",
812           "Don't use because the binary {@code data} format is not stable across API levels."
813   );
814 
815   /**
816    * ICU APIs that are in the Android SDK API but are removed on Android and @stable in ICU.
817    * Entries can be removed if ICU also decide to remove the APIs.
818    * Entries are usually the result of Android mistakenly exposing an API, an ICU API problem,
819    * and/or ICU's stability guarantees differing from Android's requirements.
820    */
821   private static final String[] ANDROID_REMOVED_SET = {
822       /* ASCII order please. */
823       // Unstable "constant" value - different values in different API levels. http://b/77850660.
824       "field:android.icu.util.JapaneseCalendar#CURRENT_ERA",
825   };
826 
827   // The declarations with JavaDocs that have @.jcite tags that should be transformed to doclava
828   // @sample tags. Ones not on this list will just be escaped and could show up in the generated
829   // docs. It is assumed that the complete set of ones that should appear in the public API are
830   // listed below and it's ok to escape those that are not.
831   private static final String[] JCITE_TRANSFORM_SET = {
832       "method:android.icu.text.DateIntervalFormat#getInstance(String,Locale)",
833       "method:android.icu.text.DateIntervalFormat#getInstance(String,Locale,DateIntervalInfo)",
834       "method:android.icu.text.DateTimePatternGenerator#addPattern(String,boolean,PatternInfo)",
835       "method:android.icu.text.DateTimePatternGenerator#getBestPattern(String)",
836       "method:android.icu.text.DateTimePatternGenerator#replaceFieldTypes(String,String)",
837       "method:android.icu.text.PluralFormat#PluralFormat(ULocale,String)",
838   };
839 
840   private static final String[] DEFAULT_CONSTRUCTORS = {
841       "android.icu.text.DateTimePatternGenerator$DistanceInfo",
842       "android.icu.text.SpoofChecker$ScriptSet",
843       "android.icu.text.TimeZoneNames$DefaultTimeZoneNames$FactoryImpl",
844   };
845 
846   // Metalava disallows hidden abstract methods in public abstract classes because classes
847   // inheriting such class can cause runtime crashes instead of a compile error. Due to historic
848   // reason, we have such classes in the public SDK. This is the allowlist of hidden abstract
849   // methods, and @SuppressWarnings("HiddenAbstractMethod") annotation will be added into those
850   // methods. See http://b/147445486 for more details.
851   private static final String[] HIDDEN_ABSTRACT_METHODS = {
852       "method:android.icu.text.Collator#getRawCollationKey(String,RawCollationKey)",
853       "method:android.icu.text.Collator#setVariableTop(String)",
854       "method:android.icu.text.Collator#setVariableTop(int)",
855   };
856 
857   public static final String ANDROID_ICU4J_SAMPLE_DIR =
858       "external/icu/android_icu4j/src/samples/java";
859 
860   private static final boolean DEBUG = false;
861 
862   static final String ORIGINAL_ICU_PACKAGE = "com.ibm.icu";
863   static final String ANDROID_ICU_PACKAGE = "android.icu";
864 
Icu4jTransform()865   private Icu4jTransform() {
866   }
867 
868   /**
869    * Usage: See {@link Icu4jRules#COMMAND_USAGE}
870    *
871    * The option --hide-non-allowlisted-api can be used to explicitly describe the API surface to be
872    * exposed; anything not in the list will be hidden in additional to other rules. This is useful
873    * when upgrading ICU when we haven't yet added new classes/methods to various hard-coded lists
874    * described below.
875    *
876    * This tool hides the following in the knowledge that classes that are not explicitly
877    * hidden are exposed in the public API set:
878    *
879    * 1) Public classes that are not in the PUBLIC_API_CLASSES list.
880    * 2) Types / fields / methods that were deprecated when the class was first exposed in Android,
881    *    listed in INITIAL_DEPRECATED_SET
882    * 3) Types / fields / methods that we explicitly want to hide, listed in DECLARATIONS_TO_HIDE
883    * 4) Types / fields / methods that are flagged with ICU javadoc as draft / provisional or
884    *    internal.
885    * 5) If the --hide-non-allowlisted-api option is provided, types / fields / methods that are not
886    *    in the allowlisted-api-file.
887    */
main(String[] args)888   public static void main(String[] args) throws Exception {
889     Map<String, String> options = JavaCore.getOptions();
890     options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
891     options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
892     options.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
893     options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
894     options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
895 
896     new Main(DEBUG)
897         .setJdtOptions(options)
898         .execute(new Icu4jRules(args));
899   }
900 
901   static class Icu4jRules implements RuleSet {
902 
903     private static final String SOURCE_CODE_HEADER = "/* GENERATED SOURCE. DO NOT MODIFY. */\n";
904     private static final String COMMAND_USAGE = "Usage: " + Icu4jTransform.class.getCanonicalName()
905             + " [--hide-non-allowlisted-api <allowlisted-api-file>]"
906             + " [--flagged-api <flagged-api-file>]"
907             + " <source-dir>+ <target-dir> <core-platform-api-file> <intra-core-api-file>"
908             + " <unsupported-app-usage-file>";
909 
910     private final InputFileGenerator inputFileGenerator;
911     private final List<Rule> rules;
912     private final BasicOutputSourceFileGenerator outputSourceFileGenerator;
913 
Icu4jRules(String[] args)914     public Icu4jRules(String[] args) {
915       Path allowlistedApiPath = null;
916       if ("--hide-non-allowlisted-api".equals(args[0])) {
917         allowlistedApiPath = Paths.get(args[1]);
918         String[] newArgs = new String[args.length - 2];
919         System.arraycopy(args, 2, newArgs, 0, args.length - 2);
920         args = newArgs;
921       }
922 
923       Path flaggedApiListPath = null;
924       if ("--flagged-api".equals(args[0])) {
925         flaggedApiListPath = Paths.get(args[1]);
926         String[] newArgs = new String[args.length - 2];
927         System.arraycopy(args, 2, newArgs, 0, args.length - 2);
928         args = newArgs;
929       }
930 
931       if (args.length < 5) {
932           throw new IllegalArgumentException(COMMAND_USAGE);
933       }
934 
935       // Extract the source directories.
936       String[] inputDirNames = new String[args.length - 4];
937       System.arraycopy(args, 0, inputDirNames, 0, args.length - 4);
938       inputFileGenerator = Icu4jTransformRules.createInputFileGenerator(inputDirNames);
939 
940       // Extract the additional arguments.
941       int argIndex = inputDirNames.length;
942       String targetDir = args[argIndex++];
943       Path corePlatformApiFile = Paths.get(args[argIndex++]);
944       Path intraCoreApiFile = Paths.get(args[argIndex++]);
945       Path unsupportedAppUsageFile = Paths.get(args[argIndex++]);
946 
947       // Ensure that all the arguments were used.
948       if (argIndex != args.length) {
949         throw new IllegalArgumentException(COMMAND_USAGE);
950       }
951 
952       rules = createTransformRules(corePlatformApiFile, intraCoreApiFile,
953           unsupportedAppUsageFile, allowlistedApiPath, flaggedApiListPath);
954       outputSourceFileGenerator = Icu4jTransformRules.createOutputFileGenerator(targetDir);
955     }
956 
957     @Override
getRuleList(File ignored)958     public List<Rule> getRuleList(File ignored) {
959       return rules;
960     }
961 
962     @Override
getInputFileGenerator()963     public InputFileGenerator getInputFileGenerator() {
964       return inputFileGenerator;
965     }
966 
967     @Override
getOutputSourceFileGenerator()968     public OutputSourceFileGenerator getOutputSourceFileGenerator() {
969       return outputSourceFileGenerator;
970     }
971 
972     // Rules for migrating com.ibm.icu source over to android.icu. Pulled out separately so they
973     // can be used for modifying ICU4J sample code as well.
getRepackagingRules()974     static Rule[] getRepackagingRules() {
975       return new Rule[] {
976           // Doc change: Insert a warning about the source code being generated.
977           createMandatoryRule(new InsertHeader(SOURCE_CODE_HEADER)),
978           // AST change: Change the package of each CompilationUnit from com.ibm.icu to android.icu.
979           createMandatoryRule(new RenamePackage(ORIGINAL_ICU_PACKAGE, ANDROID_ICU_PACKAGE)),
980           // AST change: Change all qualified names in code and javadoc.
981           createOptionalRule(new ModifyQualifiedNames(ORIGINAL_ICU_PACKAGE, ANDROID_ICU_PACKAGE)),
982           // AST change: Change all string literals containing package names in code.
983           createOptionalRule(new ModifyStringLiterals(ORIGINAL_ICU_PACKAGE, ANDROID_ICU_PACKAGE)),
984           // AST change: Change all string literals containing paths in code.
985           createOptionalRule(new ModifyStringLiterals("com/ibm/icu", "android/icu")),
986       };
987     }
988 
createTransformRules(Path corePlatformApiFile, Path intraCoreApiFile, Path unsupportedAppUsagePath, Path allowlistedApiPath, Path flaggedApiListPath)989     private static List<Rule> createTransformRules(Path corePlatformApiFile,
990             Path intraCoreApiFile,
991             Path unsupportedAppUsagePath,
992             Path allowlistedApiPath, Path flaggedApiListPath) {
993       // The rules needed to repackage source code that declares or references com.ibm.icu code
994       // so it references android.icu instead.
995       Rule[] repackageRules = getRepackagingRules();
996 
997       // The rules needed to fix up Android's documentation rules.
998       Rule[] apiDocsRules = new Rule[] {
999           // Below are the fixes that ensure the Android API documentation generation can be run
1000           // over the source.
1001 
1002           // Doc change: Switch all documentation references from com.ibm.icu to android.icu.
1003           // e.g. importantly in <code> blocks and unimportantly in non-Javadoc comments.
1004           createOptionalRule(
1005               new ReplaceTextCommentScanner(ORIGINAL_ICU_PACKAGE, ANDROID_ICU_PACKAGE)),
1006 
1007           // AST change: Hide all ICU public classes except those in the PUBLIC_API_CLASSES
1008           // allowlist.
1009           createHidePublicClassesRule(),
1010 
1011           // AST change: Hide ICU methods that are in INITIAL_DEPRECATED_SET and Android does not
1012           // want to make public.
1013           createHideOriginalDeprecatedClassesRule(),
1014           // AST change: Explicitly hide blocklisted methods in DECLARATIONS_TO_HIDE such as those
1015           // that get/set static default values that might lead to confusion or strange interactions
1016           // between Android's ICU4J and java.text / java.util classes.
1017           createHideBlocklistedDeclarationsRule(),
1018           // AST change: Explicitly hide any elements that are marked as
1019           // @draft / @provisional / @internal
1020           createOptionalRule(new HideDraftProvisionalInternal()),
1021 
1022           // AST change: Hide new non-allowlisted API in Android temporarily
1023           // Usually used for avoiding the new API introduced by upstream to show up in Android.
1024           createHideNonAllowlistedRule(allowlistedApiPath),
1025 
1026           // AST change: Add @Deprecated annotation and @deprecated doc to deprecated API in Android
1027           createMarkElementsWithDeprecatedAnnotationRule(),
1028           createMarkElementsWithDeprecatedJavadocTagRule(),
1029 
1030           // AST change: Add @removed doc to removed API in Android
1031           createMarkElementsWithRemovedJavadocTagRule(),
1032 
1033 
1034           // AST change: Remove JavaDoc tags that Android has no need of:
1035           // @hide has been added in place of @draft, @provisional and @internal
1036           // @stable <ICU version> will not mean much on Android.
1037           createOptionalRule(new RemoveJavaDocTags(
1038               "@stable", "@draft", "@provisional", "@internal", "@since")),
1039           // AST change: Replace @icu and @icuenhanced with standard text.
1040           createOptionalRule(new ReplaceIcuTags()),
1041 
1042           // AST change: Translate some of the @.jcite tags used by ICU into @sample tags used by
1043           // doclava. Those that are not translated are escaped.
1044           createTranslateJciteInclusionRule(),
1045 
1046           // AST change: Add CorePlatformApi to specified classes and members
1047           createOptionalRule(AddAnnotation.markerAnnotationFromFlatFile(
1048               "libcore.api.CorePlatformApi", corePlatformApiFile)),
1049 
1050           // AST change: Add IntraCoreApi to specified classes and members
1051           createOptionalRule(AddAnnotation.markerAnnotationFromFlatFile(
1052               "libcore.api.IntraCoreApi", intraCoreApiFile)),
1053 
1054           // AST change: Add default constructors, must come before processor to add
1055           // UnsupportedAppUsage.
1056           createOptionalRule(new AddDefaultConstructor(
1057               TypeLocator.createLocatorsFromStrings(DEFAULT_CONSTRUCTORS))),
1058 
1059           // AST change: Add UnsupportedAppUsage to specified classes and members
1060           createOptionalRule(Annotations.addUnsupportedAppUsage(unsupportedAppUsagePath)),
1061 
1062           // AST change: Add @SuppressWarnings("HiddenAbstractMethod") to specified methods
1063           createHiddenAbstractMethodRule(),
1064       };
1065 
1066       List<Rule> rulesList = Lists.newArrayList(repackageRules);
1067       rulesList.addAll(Arrays.asList(apiDocsRules));
1068       if (flaggedApiListPath != null) {
1069           // AST change: Add FlaggedApi to specified classes and members
1070           rulesList.add(createOptionalRule(Annotations.addFlaggedApi(flaggedApiListPath)));
1071       }
1072       return rulesList;
1073     }
1074 
createTranslateJciteInclusionRule()1075     private static Rule createTranslateJciteInclusionRule() {
1076       List<BodyDeclarationLocator> allowlist =
1077           BodyDeclarationLocators.createLocatorsFromStrings(JCITE_TRANSFORM_SET);
1078       TranslateJcite.InclusionHandler transformer =
1079           new TranslateJcite.InclusionHandler(ANDROID_ICU4J_SAMPLE_DIR, allowlist);
1080       return createOptionalRule(transformer);
1081     }
1082 
createHideOriginalDeprecatedClassesRule()1083     private static Rule createHideOriginalDeprecatedClassesRule() {
1084       List<BodyDeclarationLocator> blocklist =
1085           BodyDeclarationLocators.createLocatorsFromStrings(INITIAL_DEPRECATED_SET);
1086       return createOptionalRule(
1087           new TagMatchingDeclarations(blocklist, "@hide original deprecated declaration"));
1088     }
1089 
createMarkElementsWithDeprecatedAnnotationRule()1090     private static Rule createMarkElementsWithDeprecatedAnnotationRule() {
1091       List<BodyDeclarationLocator> locators =
1092           BodyDeclarationLocators.createLocatorsFromStrings(
1093                   ANDROID_DEPRECATED_SET.keySet().toArray(new String[0]));
1094       return createOptionalRule(AddAnnotation.markerAnnotationFromLocators(
1095           "Deprecated", locators));
1096     }
1097 
createMarkElementsWithDeprecatedJavadocTagRule()1098     private static Rule createMarkElementsWithDeprecatedJavadocTagRule() {
1099       Map<BodyDeclarationLocator, String> locatorTags = ANDROID_DEPRECATED_SET.entrySet().stream()
1100               .collect(Collectors.toMap(
1101                       (entry) -> BodyDeclarationLocators.fromStringForm(entry.getKey()),
1102                       (entry) -> "@deprecated " + entry.getValue())
1103               );
1104       return createOptionalRule(new TagMatchingDeclarations(locatorTags));
1105     }
1106 
createMarkElementsWithRemovedJavadocTagRule()1107     private static Rule createMarkElementsWithRemovedJavadocTagRule() {
1108       List<BodyDeclarationLocator> locators =
1109           BodyDeclarationLocators.createLocatorsFromStrings(ANDROID_REMOVED_SET);
1110       return createOptionalRule(new TagMatchingDeclarations(locators,
1111           "@removed on Android but @stable in ICU"));
1112     }
1113 
createHideBlocklistedDeclarationsRule()1114     private static Rule createHideBlocklistedDeclarationsRule() {
1115       List<BodyDeclarationLocator> blocklist =
1116           BodyDeclarationLocators.createLocatorsFromStrings(DECLARATIONS_TO_HIDE);
1117       return createOptionalRule(
1118           new TagMatchingDeclarations(blocklist, "@hide unsupported on Android"));
1119     }
1120 
createHidePublicClassesRule()1121     private static Rule createHidePublicClassesRule() {
1122       List<TypeLocator> allowlist = TypeLocator.createLocatorsFromStrings(PUBLIC_API_CLASSES);
1123       return createOptionalRule(
1124           new HidePublicClasses(allowlist, "Only a subset of ICU is exposed in Android"));
1125     }
1126 
createHiddenAbstractMethodRule()1127     private static Rule createHiddenAbstractMethodRule() {
1128       List<BodyDeclarationLocator> loactors =
1129               BodyDeclarationLocators.createLocatorsFromStrings(HIDDEN_ABSTRACT_METHODS);
1130       return createOptionalRule(
1131               AddAnnotation.markerAnnotationWithPropertyFromLocators("SuppressWarnings",
1132                       "value", String.class, "HiddenAbstractMethod", loactors));
1133     }
1134   }
1135 
createHideNonAllowlistedRule(Path allowlistedApiPath)1136   private static Rule createHideNonAllowlistedRule(Path allowlistedApiPath) {
1137     List<BodyDeclarationLocator> bodyDeclarationLocators = null;
1138     if (allowlistedApiPath != null) {
1139       bodyDeclarationLocators = BodyDeclarationLocators.readBodyDeclarationLocators(
1140               allowlistedApiPath);
1141     }
1142     return createOptionalRule(new HideNonAllowlistedDeclarations(bodyDeclarationLocators,
1143             "@hide Hide new API in Android temporarily"));
1144   }
1145 }
1146