Unverified Commit bd940073 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Migrate localizations_utils to null safety (#78939)

parent b8041178
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:yaml/yaml.dart'; import 'package:yaml/yaml.dart';
...@@ -22,11 +20,11 @@ int sortFilesByPath (File a, File b) { ...@@ -22,11 +20,11 @@ int sortFilesByPath (File a, File b) {
@immutable @immutable
class LocaleInfo implements Comparable<LocaleInfo> { class LocaleInfo implements Comparable<LocaleInfo> {
const LocaleInfo({ const LocaleInfo({
this.languageCode, required this.languageCode,
this.scriptCode, required this.scriptCode,
this.countryCode, required this.countryCode,
this.length, required this.length,
this.originalString, required this.originalString,
}); });
/// Simple parser. Expects the locale string to be in the form of 'language_script_COUNTRY' /// Simple parser. Expects the locale string to be in the form of 'language_script_COUNTRY'
...@@ -41,8 +39,8 @@ class LocaleInfo implements Comparable<LocaleInfo> { ...@@ -41,8 +39,8 @@ class LocaleInfo implements Comparable<LocaleInfo> {
final List<String> codes = locale.split('_'); // [language, script, country] final List<String> codes = locale.split('_'); // [language, script, country]
assert(codes.isNotEmpty && codes.length < 4); assert(codes.isNotEmpty && codes.length < 4);
final String languageCode = codes[0]; final String languageCode = codes[0];
String scriptCode; String? scriptCode;
String countryCode; String? countryCode;
int length = codes.length; int length = codes.length;
String originalString = locale; String originalString = locale;
if (codes.length == 2) { if (codes.length == 2) {
...@@ -112,8 +110,8 @@ class LocaleInfo implements Comparable<LocaleInfo> { ...@@ -112,8 +110,8 @@ class LocaleInfo implements Comparable<LocaleInfo> {
} }
final String languageCode; final String languageCode;
final String scriptCode; final String? scriptCode;
final String countryCode; final String? countryCode;
final int length; // The number of fields. Ranges from 1-3. final int length; // The number of fields. Ranges from 1-3.
final String originalString; // Original un-parsed locale string. final String originalString; // Original un-parsed locale string.
...@@ -149,7 +147,7 @@ class LocaleInfo implements Comparable<LocaleInfo> { ...@@ -149,7 +147,7 @@ class LocaleInfo implements Comparable<LocaleInfo> {
// See also //master/tools/gen_locale.dart in the engine repo. // See also //master/tools/gen_locale.dart in the engine repo.
Map<String, List<String>> _parseSection(String section) { Map<String, List<String>> _parseSection(String section) {
final Map<String, List<String>> result = <String, List<String>>{}; final Map<String, List<String>> result = <String, List<String>>{};
List<String> lastHeading; late List<String> lastHeading;
for (final String line in section.split('\n')) { for (final String line in section.split('\n')) {
if (line == '') { if (line == '') {
continue; continue;
...@@ -165,7 +163,7 @@ Map<String, List<String>> _parseSection(String section) { ...@@ -165,7 +163,7 @@ Map<String, List<String>> _parseSection(String section) {
final String name = line.substring(0, colon); final String name = line.substring(0, colon);
final String value = line.substring(colon + 2); final String value = line.substring(colon + 2);
lastHeading = result.putIfAbsent(name, () => <String>[]); lastHeading = result.putIfAbsent(name, () => <String>[]);
result[name].add(value); result[name]!.add(value);
} }
return result; return result;
} }
...@@ -184,11 +182,11 @@ void precacheLanguageAndRegionTags() { ...@@ -184,11 +182,11 @@ void precacheLanguageAndRegionTags() {
languageSubtagRegistry.split('%%').skip(1).map<Map<String, List<String>>>(_parseSection).toList(); languageSubtagRegistry.split('%%').skip(1).map<Map<String, List<String>>>(_parseSection).toList();
for (final Map<String, List<String>> section in sections) { for (final Map<String, List<String>> section in sections) {
assert(section.containsKey('Type'), section.toString()); 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') { if (type == 'language' || type == 'region' || type == 'script') {
assert(section.containsKey('Subtag') && section.containsKey('Description'), section.toString()); assert(section.containsKey('Subtag') && section.containsKey('Description'), section.toString());
final String subtag = section['Subtag'].single; final String subtag = section['Subtag']!.single;
String description = section['Description'].join(' '); String description = section['Description']!.join(' ');
if (description.startsWith('United ')) { if (description.startsWith('United ')) {
description = 'the $description'; description = 'the $description';
} }
...@@ -220,10 +218,10 @@ String describeLocale(String tag) { ...@@ -220,10 +218,10 @@ String describeLocale(String tag) {
final List<String> subtags = tag.split('_'); final List<String> subtags = tag.split('_');
assert(subtags.isNotEmpty); assert(subtags.isNotEmpty);
assert(_languages.containsKey(subtags[0])); assert(_languages.containsKey(subtags[0]));
final String language = _languages[subtags[0]]; final String language = _languages[subtags[0]]!;
String output = language; String output = language;
String region; String? region;
String script; String? script;
if (subtags.length == 2) { if (subtags.length == 2) {
region = _regions[subtags[1]]; region = _regions[subtags[1]];
script = _scripts[subtags[1]]; script = _scripts[subtags[1]];
...@@ -311,50 +309,50 @@ class LocalizationOptions { ...@@ -311,50 +309,50 @@ class LocalizationOptions {
/// The `--arb-dir` argument. /// The `--arb-dir` argument.
/// ///
/// The directory where all input localization files should reside. /// The directory where all input localization files should reside.
final Uri arbDirectory; final Uri? arbDirectory;
/// The `--template-arb-file` argument. /// The `--template-arb-file` argument.
/// ///
/// This URI is relative to [arbDirectory]. /// This URI is relative to [arbDirectory].
final Uri templateArbFile; final Uri? templateArbFile;
/// The `--output-localization-file` argument. /// The `--output-localization-file` argument.
/// ///
/// This URI is relative to [arbDirectory]. /// This URI is relative to [arbDirectory].
final Uri outputLocalizationsFile; final Uri? outputLocalizationsFile;
/// The `--untranslated-messages-file` argument. /// The `--untranslated-messages-file` argument.
/// ///
/// This URI is relative to [arbDirectory]. /// This URI is relative to [arbDirectory].
final Uri untranslatedMessagesFile; final Uri? untranslatedMessagesFile;
/// The `--header` argument. /// The `--header` argument.
/// ///
/// The header to prepend to the generated Dart localizations. /// The header to prepend to the generated Dart localizations.
final String header; final String? header;
/// The `--output-class` argument. /// The `--output-class` argument.
final String outputClass; final String? outputClass;
/// The `--output-dir` argument. /// The `--output-dir` argument.
/// ///
/// The directory where all output localization files should be generated. /// The directory where all output localization files should be generated.
final Uri outputDirectory; final Uri? outputDirectory;
/// The `--preferred-supported-locales` argument. /// The `--preferred-supported-locales` argument.
final List<String> preferredSupportedLocales; final List<String>? preferredSupportedLocales;
/// The `--header-file` argument. /// The `--header-file` argument.
/// ///
/// A file containing the header to prepend to the generated /// A file containing the header to prepend to the generated
/// Dart localizations. /// Dart localizations.
final Uri headerFile; final Uri? headerFile;
/// The `--use-deferred-loading` argument. /// The `--use-deferred-loading` argument.
/// ///
/// Whether to generate the Dart localization file with locales imported /// Whether to generate the Dart localization file with locales imported
/// as deferred. /// as deferred.
final bool deferredLoading; final bool? deferredLoading;
/// The `--synthetic-package` argument. /// The `--synthetic-package` argument.
/// ///
...@@ -375,8 +373,8 @@ class LocalizationOptions { ...@@ -375,8 +373,8 @@ class LocalizationOptions {
/// [LocalizationOptions] with all fields as `null` if the config file exists /// [LocalizationOptions] with all fields as `null` if the config file exists
/// but is empty. /// but is empty.
LocalizationOptions parseLocalizationsOptions({ LocalizationOptions parseLocalizationsOptions({
@required File file, required File file,
@required Logger logger, required Logger logger,
}) { }) {
final String contents = file.readAsStringSync(); final String contents = file.readAsStringSync();
if (contents.trim().isEmpty) { if (contents.trim().isEmpty) {
...@@ -387,26 +385,25 @@ LocalizationOptions parseLocalizationsOptions({ ...@@ -387,26 +385,25 @@ LocalizationOptions parseLocalizationsOptions({
logger.printError('Expected ${file.path} to contain a map, instead was $yamlNode'); logger.printError('Expected ${file.path} to contain a map, instead was $yamlNode');
throw Exception(); throw Exception();
} }
final YamlMap yamlMap = yamlNode as YamlMap;
return LocalizationOptions( return LocalizationOptions(
arbDirectory: _tryReadUri(yamlMap, 'arb-dir', logger), arbDirectory: _tryReadUri(yamlNode, 'arb-dir', logger),
templateArbFile: _tryReadUri(yamlMap, 'template-arb-file', logger), templateArbFile: _tryReadUri(yamlNode, 'template-arb-file', logger),
outputLocalizationsFile: _tryReadUri(yamlMap, 'output-localization-file', logger), outputLocalizationsFile: _tryReadUri(yamlNode, 'output-localization-file', logger),
untranslatedMessagesFile: _tryReadUri(yamlMap, 'untranslated-messages-file', logger), untranslatedMessagesFile: _tryReadUri(yamlNode, 'untranslated-messages-file', logger),
header: _tryReadString(yamlMap, 'header', logger), header: _tryReadString(yamlNode, 'header', logger),
outputClass: _tryReadString(yamlMap, 'output-class', logger), outputClass: _tryReadString(yamlNode, 'output-class', logger),
outputDirectory: _tryReadUri(yamlMap, 'output-dir', logger), outputDirectory: _tryReadUri(yamlNode, 'output-dir', logger),
preferredSupportedLocales: _tryReadStringList(yamlMap, 'preferred-supported-locales', logger), preferredSupportedLocales: _tryReadStringList(yamlNode, 'preferred-supported-locales', logger),
headerFile: _tryReadUri(yamlMap, 'header-file', logger), headerFile: _tryReadUri(yamlNode, 'header-file', logger),
deferredLoading: _tryReadBool(yamlMap, 'use-deferred-loading', logger), deferredLoading: _tryReadBool(yamlNode, 'use-deferred-loading', logger),
useSyntheticPackage: _tryReadBool(yamlMap, 'synthetic-package', logger) ?? true, useSyntheticPackage: _tryReadBool(yamlNode, 'synthetic-package', logger) ?? true,
areResourceAttributesRequired: _tryReadBool(yamlMap, 'required-resource-attributes', logger) ?? false, areResourceAttributesRequired: _tryReadBool(yamlNode, 'required-resource-attributes', logger) ?? false,
); );
} }
// Try to read a `bool` value or null from `yamlMap`, otherwise throw. // Try to read a `bool` value or null from `yamlMap`, otherwise throw.
bool _tryReadBool(YamlMap yamlMap, String key, Logger logger) { bool? _tryReadBool(YamlMap yamlMap, String key, Logger logger) {
final Object value = yamlMap[key]; final Object? value = yamlMap[key];
if (value == null) { if (value == null) {
return null; return null;
} }
...@@ -414,12 +411,12 @@ bool _tryReadBool(YamlMap yamlMap, String key, Logger logger) { ...@@ -414,12 +411,12 @@ bool _tryReadBool(YamlMap yamlMap, String key, Logger logger) {
logger.printError('Expected "$key" to have a bool value, instead was "$value"'); logger.printError('Expected "$key" to have a bool value, instead was "$value"');
throw Exception(); throw Exception();
} }
return value as bool; return value;
} }
// Try to read a `String` value or null from `yamlMap`, otherwise throw. // Try to read a `String` value or null from `yamlMap`, otherwise throw.
String _tryReadString(YamlMap yamlMap, String key, Logger logger) { String? _tryReadString(YamlMap yamlMap, String key, Logger logger) {
final Object value = yamlMap[key]; final Object? value = yamlMap[key];
if (value == null) { if (value == null) {
return null; return null;
} }
...@@ -427,11 +424,11 @@ String _tryReadString(YamlMap yamlMap, String key, Logger logger) { ...@@ -427,11 +424,11 @@ String _tryReadString(YamlMap yamlMap, String key, Logger logger) {
logger.printError('Expected "$key" to have a String value, instead was "$value"'); logger.printError('Expected "$key" to have a String value, instead was "$value"');
throw Exception(); throw Exception();
} }
return value as String; return value;
} }
List<String> _tryReadStringList(YamlMap yamlMap, String key, Logger logger) { List<String>? _tryReadStringList(YamlMap yamlMap, String key, Logger logger) {
final Object value = yamlMap[key]; final Object? value = yamlMap[key];
if (value == null) { if (value == null) {
return null; return null;
} }
...@@ -446,12 +443,12 @@ List<String> _tryReadStringList(YamlMap yamlMap, String key, Logger logger) { ...@@ -446,12 +443,12 @@ List<String> _tryReadStringList(YamlMap yamlMap, String key, Logger logger) {
} }
// Try to read a valid `Uri` or null from `yamlMap`, otherwise throw. // Try to read a valid `Uri` or null from `yamlMap`, otherwise throw.
Uri _tryReadUri(YamlMap yamlMap, String key, Logger logger) { Uri? _tryReadUri(YamlMap yamlMap, String key, Logger logger) {
final String value = _tryReadString(yamlMap, key, logger); final String? value = _tryReadString(yamlMap, key, logger);
if (value == null) { if (value == null) {
return null; return null;
} }
final Uri uri = Uri.tryParse(value); final Uri? uri = Uri.tryParse(value);
if (uri == null) { if (uri == null) {
logger.printError('"$value" must be a relative file URI'); logger.printError('"$value" must be a relative file URI');
} }
......
...@@ -19,7 +19,7 @@ import '../../../src/context.dart'; ...@@ -19,7 +19,7 @@ import '../../../src/context.dart';
void main() { void main() {
// Verifies that values are correctly passed through the localizations // Verifies that values are correctly passed through the localizations
// target, but does not validate them beyond the serialized data type. // target, but does not validate them beyond the serialized data type.
testUsingContext('generateLocalizations forwards arguments correctly', () async { testWithoutContext('generateLocalizations forwards arguments correctly', () async {
final FileSystem fileSystem = MemoryFileSystem.test(); final FileSystem fileSystem = MemoryFileSystem.test();
final Logger logger = BufferLogger.test(); final Logger logger = BufferLogger.test();
final Directory flutterProjectDirectory = fileSystem final Directory flutterProjectDirectory = fileSystem
...@@ -76,7 +76,7 @@ void main() { ...@@ -76,7 +76,7 @@ void main() {
verify(mockLocalizationsGenerator.writeOutputFiles(logger, isFromYaml: true)).called(1); verify(mockLocalizationsGenerator.writeOutputFiles(logger, isFromYaml: true)).called(1);
}); });
testUsingContext('generateLocalizations throws exception on missing flutter: generate: true flag', () async { testWithoutContext('generateLocalizations throws exception on missing flutter: generate: true flag', () async {
final FileSystem fileSystem = MemoryFileSystem.test(); final FileSystem fileSystem = MemoryFileSystem.test();
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final Directory arbDirectory = fileSystem.directory('arb') final Directory arbDirectory = fileSystem.directory('arb')
......
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