Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
134aa8e9
Unverified
Commit
134aa8e9
authored
Mar 30, 2021
by
Shi-Hao Hong
Committed by
GitHub
Mar 30, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[gen-l10n] Add `nullable-getter` flag (#79263)
parent
cf6d4a35
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
116 additions
and
3 deletions
+116
-3
generate_localizations.dart
...lutter_tools/lib/src/commands/generate_localizations.dart
+13
-0
gen_l10n.dart
packages/flutter_tools/lib/src/localizations/gen_l10n.dart
+10
-1
gen_l10n_templates.dart
...utter_tools/lib/src/localizations/gen_l10n_templates.dart
+2
-2
localizations_utils.dart
...tter_tools/lib/src/localizations/localizations_utils.dart
+7
-0
localizations_test.dart
...eneral.shard/build_system/targets/localizations_test.dart
+8
-0
generate_localizations_test.dart
...tools/test/general.shard/generate_localizations_test.dart
+76
-0
No files found.
packages/flutter_tools/lib/src/commands/generate_localizations.dart
View file @
134aa8e9
...
...
@@ -172,6 +172,17 @@ class GenerateLocalizationsCommand extends FlutterCommand {
'
\n
'
'Resource attributes are still required for plural messages.'
);
argParser
.
addFlag
(
'nullable-getter'
,
help:
'Whether or not the localizations class getter is nullable.
\n
'
'
\n
'
'By default, this value is set to true so that '
'Localizations.of(context) returns a nullable value '
'for backwards compatibility. If this value is set to true, then '
'a null check is performed on the returned value of '
'Localizations.of(context), removing the need for null checking in '
'user code.'
);
}
final
FileSystem
_fileSystem
;
...
...
@@ -220,6 +231,7 @@ class GenerateLocalizationsCommand extends FlutterCommand {
final
bool
useSyntheticPackage
=
boolArg
(
'synthetic-package'
);
final
String
projectPathString
=
stringArg
(
'project-dir'
);
final
bool
areResourceAttributesRequired
=
boolArg
(
'required-resource-attributes'
);
final
bool
usesNullableGetter
=
boolArg
(
'nullable-getter'
);
final
LocalizationsGenerator
localizationsGenerator
=
LocalizationsGenerator
(
_fileSystem
);
...
...
@@ -242,6 +254,7 @@ class GenerateLocalizationsCommand extends FlutterCommand {
projectPathString:
projectPathString
,
areResourceAttributesRequired:
areResourceAttributesRequired
,
untranslatedMessagesFile:
untranslatedMessagesFile
,
usesNullableGetter:
usesNullableGetter
,
)
..
loadResources
()
..
writeOutputFiles
(
_logger
);
...
...
packages/flutter_tools/lib/src/localizations/gen_l10n.dart
View file @
134aa8e9
...
...
@@ -66,6 +66,7 @@ void generateLocalizations({
useSyntheticPackage:
options
.
useSyntheticPackage
??
true
,
areResourceAttributesRequired:
options
.
areResourceAttributesRequired
??
false
,
untranslatedMessagesFile:
options
?.
untranslatedMessagesFile
?.
toFilePath
(),
usesNullableGetter:
options
?.
usesNullableGetter
??
true
,
)
..
loadResources
()
..
writeOutputFiles
(
logger
,
isFromYaml:
true
);
...
...
@@ -545,6 +546,10 @@ class LocalizationsGenerator {
AppResourceBundleCollection
_allBundles
;
LocaleInfo
_templateArbLocale
;
bool
_useSyntheticPackage
=
true
;
// Used to decide if the generated code is nullable or not
// (whether AppLocalizations? or AppLocalizations is returned from
// `static {name}Localizations{?} of (BuildContext context))`
bool
_usesNullableGetter
=
true
;
/// The directory that contains the project's arb files, as well as the
/// header file, if specified.
...
...
@@ -689,8 +694,10 @@ class LocalizationsGenerator {
String
projectPathString
,
bool
areResourceAttributesRequired
=
false
,
String
untranslatedMessagesFile
,
bool
usesNullableGetter
=
true
,
})
{
_useSyntheticPackage
=
useSyntheticPackage
;
_usesNullableGetter
=
usesNullableGetter
;
setProjectDir
(
projectPathString
);
setInputDirectory
(
inputPathString
);
setOutputDirectory
(
outputPathString
??
inputPathString
);
...
...
@@ -1162,7 +1169,9 @@ class LocalizationsGenerator {
.
replaceAll
(
'@(supportedLanguageCodes)'
,
supportedLanguageCodes
.
join
(
', '
))
.
replaceAll
(
'@(messageClassImports)'
,
sortedClassImports
.
join
(
'
\n
'
))
.
replaceAll
(
'@(delegateClass)'
,
delegateClass
)
.
replaceAll
(
'@(requiresIntlImport)'
,
_containsPluralMessage
()
?
"import 'package:intl/intl.dart' as intl;"
:
''
);
.
replaceAll
(
'@(requiresIntlImport)'
,
_containsPluralMessage
()
?
"import 'package:intl/intl.dart' as intl;"
:
''
)
.
replaceAll
(
'@(canBeNullable)'
,
_usesNullableGetter
?
'?'
:
''
)
.
replaceAll
(
'@(needsNullCheck)'
,
_usesNullableGetter
?
''
:
'!'
);
}
bool
_containsPluralMessage
()
=>
_allMessages
.
any
((
Message
message
)
=>
message
.
isPlural
);
...
...
packages/flutter_tools/lib/src/localizations/gen_l10n_templates.dart
View file @
134aa8e9
...
...
@@ -77,8 +77,8 @@ abstract class @(class) {
// ignore: unused_field
final
String
localeName
;
static
@
(
class
)
?
of
(
BuildContext
context
)
{
return
Localizations
.
of
<
@
(
class
)>(
context
,
@
(
class
));
static
@
(
class
)
@(
canBeNullable
)
of
(
BuildContext
context
)
{
return
Localizations
.
of
<
@
(
class
)>(
context
,
@
(
class
))
@(
needsNullCheck
)
;
}
static
const
LocalizationsDelegate
<
@
(
class
)>
delegate
=
_
@
(
class
)
Delegate
();
...
...
packages/flutter_tools/lib/src/localizations/localizations_utils.dart
View file @
134aa8e9
...
...
@@ -304,6 +304,7 @@ class LocalizationOptions {
this
.
deferredLoading
,
this
.
useSyntheticPackage
=
true
,
this
.
areResourceAttributesRequired
=
false
,
this
.
usesNullableGetter
=
true
,
})
:
assert
(
useSyntheticPackage
!=
null
);
/// The `--arb-dir` argument.
...
...
@@ -365,6 +366,11 @@ class LocalizationOptions {
/// Whether to require all resource ids to contain a corresponding
/// resource attribute.
final
bool
areResourceAttributesRequired
;
/// The `nullable-getter` argument.
///
/// Whether or not the localizations class getter is nullable.
final
bool
usesNullableGetter
;
}
/// Parse the localizations configuration options from [file].
...
...
@@ -398,6 +404,7 @@ LocalizationOptions parseLocalizationsOptions({
deferredLoading:
_tryReadBool
(
yamlNode
,
'use-deferred-loading'
,
logger
),
useSyntheticPackage:
_tryReadBool
(
yamlNode
,
'synthetic-package'
,
logger
)
??
true
,
areResourceAttributesRequired:
_tryReadBool
(
yamlNode
,
'required-resource-attributes'
,
logger
)
??
false
,
usesNullableGetter:
_tryReadBool
(
yamlNode
,
'nullable-getter'
,
logger
)
??
true
,
);
}
...
...
packages/flutter_tools/test/general.shard/build_system/targets/localizations_test.dart
View file @
134aa8e9
...
...
@@ -44,6 +44,7 @@ void main() {
untranslatedMessagesFile:
Uri
.
file
(
'untranslated'
),
useSyntheticPackage:
false
,
areResourceAttributesRequired:
true
,
usesNullableGetter:
false
,
);
final
LocalizationsGenerator
mockLocalizationsGenerator
=
MockLocalizationsGenerator
();
...
...
@@ -70,6 +71,7 @@ void main() {
projectPathString:
'/'
,
areResourceAttributesRequired:
true
,
untranslatedMessagesFile:
'untranslated'
,
usesNullableGetter:
false
,
),
).
called
(
1
);
verify
(
mockLocalizationsGenerator
.
loadResources
()).
called
(
1
);
...
...
@@ -151,6 +153,9 @@ header-file: header
header: HEADER
use-deferred-loading: true
preferred-supported-locales: en_US
synthetic-package: false
required-resource-attributes: false
nullable-getter: false
'''
);
final
LocalizationOptions
options
=
parseLocalizationsOptions
(
...
...
@@ -167,6 +172,9 @@ preferred-supported-locales: en_US
expect
(
options
.
header
,
'HEADER'
);
expect
(
options
.
deferredLoading
,
true
);
expect
(
options
.
preferredSupportedLocales
,
<
String
>[
'en_US'
]);
expect
(
options
.
useSyntheticPackage
,
false
);
expect
(
options
.
areResourceAttributesRequired
,
false
);
expect
(
options
.
usesNullableGetter
,
false
);
});
testWithoutContext
(
'parseLocalizationsOptions handles preferredSupportedLocales as list'
,
()
async
{
...
...
packages/flutter_tools/test/general.shard/generate_localizations_test.dart
View file @
134aa8e9
...
...
@@ -800,6 +800,82 @@ void main() {
},
);
testUsingContext
(
'generates nullable localizations class getter via static `of` method '
'by default'
,
()
{
_standardFlutterDirectoryL10nSetup
(
fs
);
LocalizationsGenerator
generator
;
try
{
generator
=
LocalizationsGenerator
(
fs
);
generator
..
initialize
(
inputPathString:
defaultL10nPathString
,
outputPathString:
fs
.
path
.
join
(
'lib'
,
'l10n'
,
'output'
),
templateArbFileName:
defaultTemplateArbFileName
,
outputFileString:
defaultOutputFileString
,
classNameString:
defaultClassNameString
,
useSyntheticPackage:
false
,
)
..
loadResources
()
..
writeOutputFiles
(
BufferLogger
.
test
());
}
on
L10nException
catch
(
e
)
{
fail
(
'Generating output should not fail:
\n
${e.message}
'
);
}
final
Directory
outputDirectory
=
fs
.
directory
(
'lib'
).
childDirectory
(
'l10n'
).
childDirectory
(
'output'
);
expect
(
outputDirectory
.
existsSync
(),
isTrue
);
expect
(
outputDirectory
.
childFile
(
'output-localization-file.dart'
).
existsSync
(),
isTrue
);
expect
(
outputDirectory
.
childFile
(
'output-localization-file.dart'
).
readAsStringSync
(),
contains
(
'static AppLocalizations? of(BuildContext context)'
),
);
expect
(
outputDirectory
.
childFile
(
'output-localization-file.dart'
).
readAsStringSync
(),
contains
(
'return Localizations.of<AppLocalizations>(context, AppLocalizations);'
),
);
},
);
testUsingContext
(
'can generate non-nullable localizations class getter via static `of` method '
,
()
{
_standardFlutterDirectoryL10nSetup
(
fs
);
LocalizationsGenerator
generator
;
try
{
generator
=
LocalizationsGenerator
(
fs
);
generator
..
initialize
(
inputPathString:
defaultL10nPathString
,
outputPathString:
fs
.
path
.
join
(
'lib'
,
'l10n'
,
'output'
),
templateArbFileName:
defaultTemplateArbFileName
,
outputFileString:
defaultOutputFileString
,
classNameString:
defaultClassNameString
,
useSyntheticPackage:
false
,
usesNullableGetter:
false
,
)
..
loadResources
()
..
writeOutputFiles
(
BufferLogger
.
test
());
}
on
L10nException
catch
(
e
)
{
fail
(
'Generating output should not fail:
\n
${e.message}
'
);
}
final
Directory
outputDirectory
=
fs
.
directory
(
'lib'
).
childDirectory
(
'l10n'
).
childDirectory
(
'output'
);
expect
(
outputDirectory
.
existsSync
(),
isTrue
);
expect
(
outputDirectory
.
childFile
(
'output-localization-file.dart'
).
existsSync
(),
isTrue
);
expect
(
outputDirectory
.
childFile
(
'output-localization-file.dart'
).
readAsStringSync
(),
contains
(
'static AppLocalizations of(BuildContext context)'
),
);
expect
(
outputDirectory
.
childFile
(
'output-localization-file.dart'
).
readAsStringSync
(),
contains
(
'return Localizations.of<AppLocalizations>(context, AppLocalizations)!;'
),
);
},
);
testUsingContext
(
'creates list of inputs and outputs when file path is specified'
,
()
{
_standardFlutterDirectoryL10nSetup
(
fs
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment