Unverified Commit 4705e0cc authored by Abhishek Ghaskata's avatar Abhishek Ghaskata Committed by GitHub

migrate localization to null safety (#84064)

migrate localization to null safety
parent 4265acd6
......@@ -13,8 +13,6 @@
// This utility is run by `gen_localizations.dart` if --overwrite is passed
// in as an option.
// @dart = 2.8
import 'dart:convert';
import 'dart:io';
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
/// This program extracts localized date symbols and patterns from the intl
/// package for the subset of locales supported by the flutter_localizations
/// package.
......@@ -42,7 +40,7 @@ const String _kCommandName = 'gen_date_localizations.dart';
// Date symbols for the Kannada locale ('kn') are handled specially because
// some of the strings contain characters that can crash Emacs on Linux.
// See packages/flutter_localizations/lib/src/l10n/README for more information.
String currentLocale;
String? currentLocale;
Future<void> main(List<String> rawArgs) async {
checkCwdIsRepoRoot(_kCommandName);
......@@ -66,7 +64,7 @@ Future<void> main(List<String> rawArgs) async {
(String line) => line.startsWith('intl:'),
orElse: () {
exitWithError('intl dependency not found in ${dotPackagesFile.path}');
return null; // unreachable
return ''; // unreachable
},
)
.split(':')
......@@ -143,7 +141,7 @@ String _jsonToMap(dynamic json) {
return '$json';
if (json is String)
return generateEncodedString(currentLocale, json);
return generateEncodedString(currentLocale!, json);
if (json is Iterable) {
final StringBuffer buffer = StringBuffer('<dynamic>[');
......@@ -180,7 +178,7 @@ Set<String> _supportedLocales() {
for (final FileSystemEntity entity in supportedLocalesDirectory.listSync()) {
final String filePath = entity.path;
if (FileSystemEntity.isFileSync(filePath) && filenameRE.hasMatch(filePath)) {
supportedLocales.add(filenameRE.firstMatch(filePath)[1]);
supportedLocales.add(filenameRE.firstMatch(filePath)![1]!);
}
}
......@@ -200,5 +198,5 @@ Map<String, File> _listIntlData(Directory directory) {
final List<String> locales = localeFiles.keys.toList(growable: false);
locales.sort();
return Map<String, File>.fromIterable(locales, value: (dynamic locale) => localeFiles[locale]);
return Map<String, File>.fromIterable(locales, value: (dynamic locale) => localeFiles[locale]!);
}
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// This program updates the language locale arb files with any missing resource
// entries that are included in the English arb files. This is useful when
// adding new resources for localization. You can just add the appropriate
......@@ -68,10 +66,10 @@ bool intentionallyOmitted(String key, Map<String, dynamic> bundle) {
/// Whether `key` corresponds to one of the plural variations of a key with
/// the same prefix and suffix "Other".
bool isPluralVariation(String key, Map<String, dynamic> bundle) {
final Match pluralMatch = kPluralRegexp.firstMatch(key);
final Match? pluralMatch = kPluralRegexp.firstMatch(key);
if (pluralMatch == null)
return false;
final String prefix = pluralMatch[1];
final String prefix = pluralMatch[1]!;
return bundle.containsKey('${prefix}Other');
}
......@@ -85,7 +83,7 @@ void updateMissingResources(String localizationPath, String groupPrefix) {
for (final FileSystemEntity entity in localizationDir.listSync().toList()..sort(sortFilesByPath)) {
final String entityPath = entity.path;
if (FileSystemEntity.isFileSync(entityPath) && filenamePattern.hasMatch(entityPath)) {
final String localeString = filenamePattern.firstMatch(entityPath)[1];
final String localeString = filenamePattern.firstMatch(entityPath)![1]!;
final LocaleInfo locale = LocaleInfo.fromString(localeString);
// Only look at top-level language locales
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'localizations_utils.dart';
String generateCupertinoHeader(String regenerateInstructions) {
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'localizations_utils.dart';
String generateMaterialHeader(String regenerateInstructions) {
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:convert';
import 'dart:io';
......@@ -23,11 +21,11 @@ int sortFilesByPath (FileSystemEntity a, FileSystemEntity b) {
@immutable
class LocaleInfo implements Comparable<LocaleInfo> {
const LocaleInfo({
this.languageCode,
required this.languageCode,
this.scriptCode,
this.countryCode,
this.length,
this.originalString,
required this.length,
required this.originalString,
});
/// Simple parser. Expects the locale string to be in the form of 'language_script_COUNTRY'
......@@ -42,8 +40,8 @@ class LocaleInfo implements Comparable<LocaleInfo> {
final List<String> codes = locale.split('_'); // [language, script, country]
assert(codes.isNotEmpty && codes.length < 4);
final String languageCode = codes[0];
String scriptCode;
String countryCode;
String? scriptCode;
String? countryCode;
int length = codes.length;
String originalString = locale;
if (codes.length == 2) {
......@@ -111,8 +109,8 @@ class LocaleInfo implements Comparable<LocaleInfo> {
}
final String languageCode;
final String scriptCode;
final String countryCode;
final String? scriptCode;
final String? countryCode;
final int length; // The number of fields. Ranges from 1-3.
final String originalString; // Original un-parsed locale string.
......@@ -148,10 +146,10 @@ class LocaleInfo implements Comparable<LocaleInfo> {
/// Parse the data for a locale from a file, and store it in the [attributes]
/// and [resources] keys.
void loadMatchingArbsIntoBundleMaps({
@required Directory directory,
@required RegExp filenamePattern,
@required Map<LocaleInfo, Map<String, String>> localeToResources,
@required Map<LocaleInfo, Map<String, dynamic>> localeToResourceAttributes,
required Directory directory,
required RegExp filenamePattern,
required Map<LocaleInfo, Map<String, String>> localeToResources,
required Map<LocaleInfo, Map<String, dynamic>> localeToResourceAttributes,
}) {
assert(directory != null);
assert(filenamePattern != null);
......@@ -169,13 +167,13 @@ void loadMatchingArbsIntoBundleMaps({
for (final FileSystemEntity entity in directory.listSync().toList()..sort(sortFilesByPath)) {
final String entityPath = entity.path;
if (FileSystemEntity.isFileSync(entityPath) && filenamePattern.hasMatch(entityPath)) {
final String localeString = filenamePattern.firstMatch(entityPath)[1];
final String localeString = filenamePattern.firstMatch(entityPath)![1]!;
final File arbFile = File(entityPath);
// Helper method to fill the maps with the correct data from file.
void populateResources(LocaleInfo locale, File file) {
final Map<String, String> resources = localeToResources[locale];
final Map<String, dynamic> attributes = localeToResourceAttributes[locale];
final Map<String, String> resources = localeToResources[locale]!;
final Map<String, dynamic> attributes = localeToResourceAttributes[locale]!;
final Map<String, dynamic> bundle = json.decode(file.readAsStringSync()) as Map<String, dynamic>;
for (final String key in bundle.keys) {
// The ARB file resource "attributes" for foo are called @foo.
......@@ -258,9 +256,9 @@ GeneratorOptions parseArgs(List<String> rawArgs) {
class GeneratorOptions {
GeneratorOptions({
@required this.writeToFile,
@required this.materialOnly,
@required this.cupertinoOnly,
required this.writeToFile,
required this.materialOnly,
required this.cupertinoOnly,
});
final bool writeToFile;
......@@ -271,7 +269,7 @@ class GeneratorOptions {
// See also //master/tools/gen_locale.dart in the engine repo.
Map<String, List<String>> _parseSection(String section) {
final Map<String, List<String>> result = <String, List<String>>{};
List<String> lastHeading;
late List<String> lastHeading;
for (final String line in section.split('\n')) {
if (line == '')
continue;
......@@ -285,7 +283,7 @@ Map<String, List<String>> _parseSection(String section) {
final String name = line.substring(0, colon);
final String value = line.substring(colon + 2);
lastHeading = result.putIfAbsent(name, () => <String>[]);
result[name].add(value);
result[name]!.add(value);
}
return result;
}
......@@ -304,11 +302,11 @@ void precacheLanguageAndRegionTags() {
languageSubtagRegistry.split('%%').skip(1).map<Map<String, List<String>>>(_parseSection).toList();
for (final Map<String, List<String>> section in sections) {
assert(section.containsKey('Type'), section.toString());
final String type = section['Type'].single;
final String type = section['Type']!.single;
if (type == 'language' || type == 'region' || type == 'script') {
assert(section.containsKey('Subtag') && section.containsKey('Description'), section.toString());
final String subtag = section['Subtag'].single;
String description = section['Description'].join(' ');
final String subtag = section['Subtag']!.single;
String description = section['Description']!.join(' ');
if (description.startsWith('United '))
description = 'the $description';
if (description.contains(kParentheticalPrefix))
......@@ -336,10 +334,10 @@ String describeLocale(String tag) {
final List<String> subtags = tag.split('_');
assert(subtags.isNotEmpty);
assert(_languages.containsKey(subtags[0]));
final String language = _languages[subtags[0]];
final String language = _languages[subtags[0]]!;
String output = language;
String region;
String script;
String? region;
String? script;
if (subtags.length == 2) {
region = _regions[subtags[1]];
script = _scripts[subtags[1]];
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:convert' show json;
import 'dart:io';
......@@ -62,7 +60,7 @@ void validateEnglishLocalizations(File file) {
continue;
final dynamic atResourceValue = bundle[atResourceId];
final Map<String, dynamic> atResource =
final Map<String, dynamic>? atResource =
atResourceValue is Map<String, dynamic> ? atResourceValue : null;
if (atResource == null) {
errorMessages.writeln('A map value was not specified for $atResourceId');
......@@ -103,12 +101,12 @@ void validateLocalizations(
Map<LocaleInfo, Map<String, String>> localeToResources,
Map<LocaleInfo, Map<String, dynamic>> localeToAttributes,
) {
final Map<String, String> canonicalLocalizations = localeToResources[LocaleInfo.fromString('en')];
final Map<String, String> canonicalLocalizations = localeToResources[LocaleInfo.fromString('en')]!;
final Set<String> canonicalKeys = Set<String>.from(canonicalLocalizations.keys);
final StringBuffer errorMessages = StringBuffer();
bool explainMissingKeys = false;
for (final LocaleInfo locale in localeToResources.keys) {
final Map<String, String> resources = localeToResources[locale];
final Map<String, String> resources = localeToResources[locale]!;
// Whether `key` corresponds to one of the plural variations of a key with
// the same prefix and suffix "Other".
......@@ -116,10 +114,10 @@ void validateLocalizations(
// Many languages require only a subset of these variations, so we do not
// require them so long as the "Other" variation exists.
bool isPluralVariation(String key) {
final Match pluralMatch = kPluralRegexp.firstMatch(key);
final Match? pluralMatch = kPluralRegexp.firstMatch(key);
if (pluralMatch == null)
return false;
final String prefix = pluralMatch[1];
final String? prefix = pluralMatch[1];
return resources.containsKey('${prefix}Other');
}
......@@ -135,10 +133,10 @@ void validateLocalizations(
// For language-level locales only, check that they have a complete list of
// keys, or opted out of using certain ones.
if (locale.length == 1) {
final Map<String, dynamic> attributes = localeToAttributes[locale];
final List<String> missingKeys = <String>[];
final Map<String, dynamic>? attributes = localeToAttributes[locale];
final List<String?> missingKeys = <String?>[];
for (final String missingKey in canonicalKeys.difference(keys)) {
final dynamic attribute = attributes[missingKey];
final dynamic attribute = attributes?[missingKey];
final bool intentionallyOmitted = attribute is Map && attribute.containsKey('notUsed');
if (!intentionallyOmitted && !isPluralVariation(missingKey))
missingKeys.add(missingKey);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment