diff options
author | 2017-06-26 16:45:45 +0200 | |
---|---|---|
committer | 2017-06-26 18:42:47 +0200 | |
commit | 192422d2e554d297972c1cdc02127b1ca8be54ab (patch) | |
tree | 6974ef64d77fb9305a453fc383b79164bc8179df /src/main/java/com/google/devtools/build/lib/rules/android/ResourceFilter.java | |
parent | 0507fd5eaa0b30fcabe39db02ef9fb090ef7edc6 (diff) |
ResourceFilter properly handles special language qualifiers
Two special types of language qualifiers are commonly used:
Serbian can be written in Latin or Cyrillic characters. Serbian in Latin
characters is referred to as sr-Latn (or, with a misplaced region prefix,
sr-rLatn, or with the permutation common in some code for the old verions of
regions supported by Aapt, sr_Latn).
Spanish spoken across Latin America and the Caribbean can be represented by
es-419 (or, using the permutation for old qualifier formats, es_419).
For both of these, transform the resource qualifier into an appropriate BCP-47
representation that can be handled by FolderConfiguration.
Also, add attribute warnings when these qualifiers are used in their specially-handled form (instead of in BCP-47 form).
RELNOTES: none
PiperOrigin-RevId: 160143247
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/android/ResourceFilter.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/android/ResourceFilter.java | 95 |
1 files changed, 75 insertions, 20 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceFilter.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceFilter.java index 2a504b360f..76a8eb702c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceFilter.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceFilter.java @@ -38,6 +38,8 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Filters resources based on their qualifiers. @@ -203,7 +205,7 @@ public class ResourceFilter { ImmutableList.Builder<FolderConfiguration> filterBuilder = ImmutableList.builder(); for (String filter : configFilters) { addIfNotNull( - getFolderConfiguration(filter), + getFolderConfiguration(ruleErrorConsumer, filter), filter, filterBuilder, ruleErrorConsumer, @@ -212,28 +214,81 @@ public class ResourceFilter { return filterBuilder.build(); } + private FolderConfiguration getFolderConfiguration( + RuleErrorConsumer ruleErrorConsumer, String filter) { - private static FolderConfiguration getFolderConfiguration(String filter) { - /* - * Aapt used to expect locale configurations of form 'en_US'. It now also supports the correct - * 'en-rUS' format. For backwards comparability, use a regex to convert filters with locales in - * the old format to filters with locales of the correct format. - * - * The correct format for locales is defined at - * https://developer.android.com/guide/topics/resources/providing-resources.html#LocaleQualifier - * - * TODO(bazel-team): Migrate consumers away from the old Aapt locale format, then remove this - * replacement. - * - * The regex is a bit complicated to avoid modifying potential new qualifiers that contain - * underscores. Specifically, it searches for the entire beginning of the resource qualifier, - * including (optionally) MCC and MNC, and then the locale itself. - */ - String fixedFilter = - filter.replaceFirst("^((mcc[0-9]{3}-(mnc[0-9]{3}-)?)?[a-z]{2})_([A-Z]{2})", "$1-r$4"); - return FolderConfiguration.getConfigForQualifierString(fixedFilter); + // Clean up deprecated representations of resource qualifiers that FolderConfiguration can't + // handle. + for (DeprecatedQualifierHandler handler : deprecatedQualifierHandlers) { + filter = handler.replaceIfNeeded(ruleErrorConsumer, filter); + } + + return FolderConfiguration.getConfigForQualifierString(filter); } + private static final class DeprecatedQualifierHandler { + private final Pattern pattern; + private final String replacement; + private final String description; + + private boolean warned = false; + + private DeprecatedQualifierHandler(String pattern, String replacement, String description) { + this.pattern = Pattern.compile(pattern); + this.replacement = replacement; + this.description = description; + } + + private String replaceIfNeeded(RuleErrorConsumer ruleErrorConsumer, String qualifier) { + Matcher matcher = pattern.matcher(qualifier); + + if (!matcher.matches()) { + return qualifier; + } + + String fixed = matcher.replaceFirst(replacement); + // We don't want to spam users. Only warn about this kind of issue once per target. + // TODO(asteinb): Will this cause problems when settings are propogated via dynamic + // configuration? + if (!warned) { + ruleErrorConsumer.attributeWarning( + RESOURCE_CONFIGURATION_FILTERS_NAME, + String.format( + "When referring to %s, use of qualifier '%s' is deprecated. Use '%s' instead.", + description, matcher.group(), fixed)); + warned = true; + } + + return fixed; + } + } + + /** List of deprecated qualifiers that should currently by handled with a warning */ + private final List<DeprecatedQualifierHandler> deprecatedQualifierHandlers = ImmutableList.of( + /* + * Aapt used to expect locale configurations of form 'en_US'. It now also supports the correct + * 'en-rUS' format. For backwards comparability, use a regex to convert filters with locales + * in the old format to filters with locales of the correct format. + * + * The correct format for locales is defined at + * https://developer.android.com/guide/topics/resources/providing-resources.html#LocaleQualifier + * + * TODO(bazel-team): Migrate consumers away from the old Aapt locale format, then remove this + * replacement. + * + * The regex is a bit complicated to avoid modifying potential new qualifiers that contain + * underscores. Specifically, it searches for the entire beginning of the resource qualifier, + * including (optionally) MCC and MNC, and then the locale itself. + */ + new DeprecatedQualifierHandler( + "^((mcc[0-9]{3}-(mnc[0-9]{3}-)?)?[a-z]{2})_([A-Z]{2}).*", + "$1-r$4", "locale qualifiers with regions"), + new DeprecatedQualifierHandler( + "sr[_\\-]r?Latn.*", "b+sr+Latn", "Serbian in Latin characters"), + new DeprecatedQualifierHandler( + "es[_\\-]419.*", "b+es+419", "Spanish for Latin America and the Caribbean") + ); + private ImmutableList<Density> getDensities(RuleErrorConsumer ruleErrorConsumer) { ImmutableList.Builder<Density> densityBuilder = ImmutableList.builder(); for (String density : densities) { |