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
4451ffca
Unverified
Commit
4451ffca
authored
Apr 09, 2020
by
Per Classon
Committed by
GitHub
Apr 09, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add option for deferred loading to gen_l10n (#53824)
parent
0d459f23
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
309 additions
and
54 deletions
+309
-54
gen_l10n.dart
dev/tools/localization/bin/gen_l10n.dart
+20
-0
gen_l10n.dart
dev/tools/localization/gen_l10n.dart
+130
-31
gen_l10n_templates.dart
dev/tools/localization/gen_l10n_templates.dart
+56
-21
gen_l10n_test.dart
dev/tools/test/localization/gen_l10n_test.dart
+83
-0
gen_l10n_test.dart
...s/flutter_tools/test/integration.shard/gen_l10n_test.dart
+20
-2
No files found.
dev/tools/localization/bin/gen_l10n.dart
View file @
4451ffca
...
...
@@ -81,6 +81,24 @@ void main(List<String> arguments) {
'Alternatively, see the `header` option to pass in a string '
'for a simpler header.'
);
parser
.
addFlag
(
'use-deferred-loading'
,
defaultsTo:
false
,
help:
'Whether to generate the Dart localization file with locales imported'
' as deferred, allowing for lazy loading of each locale in Flutter web.
\n
'
'
\n
'
'This can reduce a web app’s initial startup time by decreasing the '
'size of the JavaScript bundle. When this flag is set to true, the '
'messages for a particular locale are only downloaded and loaded by the '
'Flutter app as they are needed. For projects with a lot of different '
'locales and many localization strings, it can be an performance '
'improvement to have deferred loading. For projects with a small number '
'of locales, the difference is negligible, and might slow down the start '
'up compared to bundling the localizations with the rest of the '
'application.
\n\n
'
'Note that this flag does not affect other platforms such as mobile or '
'desktop.'
,
);
final
argslib
.
ArgResults
results
=
parser
.
parse
(
arguments
);
if
(
results
[
'help'
]
==
true
)
{
...
...
@@ -98,6 +116,7 @@ void main(List<String> arguments) {
final
String
preferredSupportedLocaleString
=
results
[
'preferred-supported-locales'
]
as
String
;
final
String
headerString
=
results
[
'header'
]
as
String
;
final
String
headerFile
=
results
[
'header-file'
]
as
String
;
final
bool
useDeferredLoading
=
results
[
'use-deferred-loading'
]
as
bool
;
const
local
.
LocalFileSystem
fs
=
local
.
LocalFileSystem
();
final
LocalizationsGenerator
localizationsGenerator
=
LocalizationsGenerator
(
fs
);
...
...
@@ -112,6 +131,7 @@ void main(List<String> arguments) {
preferredSupportedLocaleString:
preferredSupportedLocaleString
,
headerString:
headerString
,
headerFile:
headerFile
,
useDeferredLoading:
useDeferredLoading
,
)
..
loadResources
()
..
writeOutputFile
()
...
...
dev/tools/localization/gen_l10n.dart
View file @
4451ffca
This diff is collapsed.
Click to expand it.
dev/tools/localization/gen_l10n_templates.dart
View file @
4451ffca
...
...
@@ -6,6 +6,7 @@ const String fileTemplate = '''
@(header)
import '
dart:
async
';
// ignore: unused_import
import '
package:
flutter
/
foundation
.
dart
';
import '
package:
flutter
/
widgets
.
dart
';
import '
package:
flutter_localizations
/
flutter_localizations
.
dart
';
...
...
@@ -104,26 +105,7 @@ abstract class @(class) {
@
(
methods
)}
class
_
@
(
class
)
Delegate
extends
LocalizationsDelegate
<
@
(
class
)>
{
const
_
@
(
class
)
Delegate
();
@override
Future
<
@
(
class
)>
load
(
Locale
locale
)
{
return
SynchronousFuture
<
@
(
class
)>(@(
lookupName
)(
locale
));
}
@override
bool
isSupported
(
Locale
locale
)
=>
<
String
>[
@
(
supportedLanguageCodes
)].
contains
(
locale
.
languageCode
);
@override
bool
shouldReload
(
_
@
(
class
)
Delegate
old
)
=>
false
;
}
@
(
class
)
@(
lookupName
)(
Locale
locale
)
{
@
(
lookupBody
)
assert
(
false
,
'@(class).delegate failed to load unsupported locale "
\
$locale
"'
);
return
null
;
}
@
(
delegateClass
)
''';
const String numberFormatTemplate = '''
...
...
@@ -205,14 +187,67 @@ const String baseClassMethodTemplate = '''
String
@
(
name
)(
@
(
parameters
));
''';
// DELEGATE CLASS TEMPLATES
const String delegateClassTemplate = '''
class
_
@
(
class
)
Delegate
extends
LocalizationsDelegate
<
@
(
class
)>
{
const
_
@
(
class
)
Delegate
();
@override
Future
<
@
(
class
)>
load
(
Locale
locale
)
{
@
(
loadBody
)
}
@override
bool
isSupported
(
Locale
locale
)
=>
<
String
>[
@
(
supportedLanguageCodes
)].
contains
(
locale
.
languageCode
);
@override
bool
shouldReload
(
_
@
(
class
)
Delegate
old
)
=>
false
;
}
@
(
lookupFunction
)
''';
const String loadBodyTemplate = '''
return
SynchronousFuture
<
@
(
class
)>(@(
lookupName
)(
locale
));
''';
const String loadBodyDeferredLoadingTemplate = '''
return
@
(
lookupName
)(
locale
);
''';
// DELEGATE LOOKUP TEMPLATES
const String lookupFunctionTemplate = '''
@
(
class
)
@(
lookupName
)(
Locale
locale
)
{
@
(
lookupBody
)
assert
(
false
,
'@(class).delegate failed to load unsupported locale "
\
$locale
"'
);
return
null
;
}
''';
const String lookupFunctionDeferredLoadingTemplate = '''
/// Lazy load the library for web, on other platforms we return the
/// localizations synchronously.
Future
<
@
(
class
)>
_loadLibraryForWeb
(
Future
<
dynamic
>
Function
()
loadLibrary
,
@
(
class
)
Function
()
localizationClosure
,
)
{
if
(
kIsWeb
)
{
return
loadLibrary
().
then
((
dynamic
_
)
=>
localizationClosure
());
}
else
{
return
SynchronousFuture
<
@
(
class
)>(
localizationClosure
());
}
}
Future
<
@
(
class
)>
@(
lookupName
)(
Locale
locale
)
{
@
(
lookupBody
)
assert
(
false
,
'@(class).delegate failed to load unsupported locale "
\
$locale
"'
);
return
null
;
}
''';
const String lookupBodyTemplate = '''
@
(
lookupAllCodesSpecified
)
@
(
lookupScriptCodeSpecified
)
@
(
lookupCountryCodeSpecified
)
@
(
lookupLanguageCodeSpecified
)
''';
const String switchClauseTemplate = '''
case
'@(case)'
:
return
@
(
class
)();''';
const String switchClauseTemplate = '''
case
'@(case)'
:
return
@
(
localeClass
)();
''';
const String switchClauseDeferredLoadingTemplate = '''
case
'@(case)'
:
return
_loadLibraryForWeb
(
@
(
library
).
loadLibrary
,
()
=>
@
(
library
).
@
(
localeClass
)());
''';
const String nestedSwitchTemplate = '''
case
'@(languageCode)'
:
{
switch
(
locale
.
@
(
code
))
{
...
...
dev/tools/test/localization/gen_l10n_test.dart
View file @
4451ffca
...
...
@@ -380,6 +380,28 @@ void main() {
fail
(
'Setting headerFile that does not exist should fail'
);
});
test
(
'setting useDefferedLoading to null should fail'
,
()
{
_standardFlutterDirectoryL10nSetup
(
fs
);
LocalizationsGenerator
generator
;
try
{
generator
=
LocalizationsGenerator
(
fs
);
generator
.
initialize
(
l10nDirectoryPath:
defaultArbPathString
,
templateArbFileName:
defaultTemplateArbFileName
,
outputFileString:
defaultOutputFileString
,
classNameString:
defaultClassNameString
,
headerString:
'/// Sample header'
,
useDeferredLoading:
null
,
);
}
on
L10nException
catch
(
e
)
{
expect
(
e
.
message
,
contains
(
'useDeferredLoading argument cannot be null.'
));
return
;
}
fail
(
'Setting useDefferedLoading to null should fail'
);
});
group
(
'loadResources'
,
()
{
test
(
'correctly initializes supportedLocales and supportedLanguageCodes properties'
,
()
{
_standardFlutterDirectoryL10nSetup
(
fs
);
...
...
@@ -792,6 +814,67 @@ void main() {
expect
(
englishLocalizationsFile
,
contains
(
'class AppLocalizationsEn extends AppLocalizations'
));
});
test
(
'language imports are sorted when preferredSupportedLocaleString is given'
,
()
{
fs
.
currentDirectory
.
childDirectory
(
'lib'
).
childDirectory
(
'l10n'
)..
createSync
(
recursive:
true
)
..
childFile
(
defaultTemplateArbFileName
).
writeAsStringSync
(
singleMessageArbFileString
)
..
childFile
(
'app_zh.arb'
).
writeAsStringSync
(
singleZhMessageArbFileString
)
..
childFile
(
'app_es.arb'
).
writeAsStringSync
(
singleEsMessageArbFileString
);
const
String
preferredSupportedLocaleString
=
'["zh"]'
;
final
LocalizationsGenerator
generator
=
LocalizationsGenerator
(
fs
);
try
{
generator
.
initialize
(
l10nDirectoryPath:
defaultArbPathString
,
templateArbFileName:
defaultTemplateArbFileName
,
outputFileString:
defaultOutputFileString
,
classNameString:
defaultClassNameString
,
preferredSupportedLocaleString:
preferredSupportedLocaleString
,
);
generator
.
loadResources
();
generator
.
writeOutputFile
();
}
on
Exception
catch
(
e
)
{
fail
(
'Generating output files should not fail:
$e
'
);
}
final
String
localizationsFile
=
fs
.
file
(
path
.
join
(
'lib'
,
'l10n'
,
defaultOutputFileString
),
).
readAsStringSync
();
expect
(
localizationsFile
,
contains
(
'''
import '
$
{
defaultOutputFileString
}
_en
.
dart
';
import '
$
{
defaultOutputFileString
}
_es
.
dart
';
import '
$
{
defaultOutputFileString
}
_zh
.
dart
';
'''
));
});
test
(
'imports are deferred when useDeferredImports are set'
,
()
{
fs
.
currentDirectory
.
childDirectory
(
'lib'
).
childDirectory
(
'l10n'
)..
createSync
(
recursive:
true
)
..
childFile
(
defaultTemplateArbFileName
).
writeAsStringSync
(
singleMessageArbFileString
);
final
LocalizationsGenerator
generator
=
LocalizationsGenerator
(
fs
);
try
{
generator
.
initialize
(
l10nDirectoryPath:
defaultArbPathString
,
templateArbFileName:
defaultTemplateArbFileName
,
outputFileString:
defaultOutputFileString
,
classNameString:
defaultClassNameString
,
useDeferredLoading:
true
,
);
generator
.
loadResources
();
generator
.
writeOutputFile
();
}
on
Exception
catch
(
e
)
{
fail
(
'Generating output files should not fail:
$e
'
);
}
final
String
localizationsFile
=
fs
.
file
(
path
.
join
(
'lib'
,
'l10n'
,
defaultOutputFileString
),
).
readAsStringSync
();
expect
(
localizationsFile
,
contains
(
'''
import '
$
{
defaultOutputFileString
}
_en
.
dart
' deferred as
${defaultOutputFileString}
_en;
'''
));
});
group
(
'DateTime tests'
,
()
{
test
(
'throws an exception when improperly formatted date is passed in'
,
()
{
const
String
singleDateMessageArbFileString
=
'''
...
...
packages/flutter_tools/test/integration.shard/gen_l10n_test.dart
View file @
4451ffca
...
...
@@ -48,7 +48,7 @@ void main() {
}
}
test
(
'generated l10n classes produce expected localized strings'
,
()
async
{
void
setUpAndRunGenL10n
({
List
<
String
>
args
})
{
// Get the intl packages before running gen_l10n.
final
String
flutterBin
=
globals
.
platform
.
isWindows
?
'flutter.bat'
:
'flutter'
;
final
String
flutterPath
=
globals
.
fs
.
path
.
join
(
getFlutterRoot
(),
'bin'
,
flutterBin
);
...
...
@@ -58,8 +58,10 @@ void main() {
final
String
genL10nPath
=
globals
.
fs
.
path
.
join
(
getFlutterRoot
(),
'dev'
,
'tools'
,
'localization'
,
'bin'
,
'gen_l10n.dart'
);
final
String
dartBin
=
globals
.
platform
.
isWindows
?
'dart.exe'
:
'dart'
;
final
String
dartPath
=
globals
.
fs
.
path
.
join
(
getFlutterRoot
(),
'bin'
,
'cache'
,
'dart-sdk'
,
'bin'
,
dartBin
);
runCommand
(<
String
>[
dartPath
,
genL10nPath
]);
runCommand
(<
String
>[
dartPath
,
genL10nPath
,
args
?.
join
(
' '
)]);
}
Future
<
StringBuffer
>
runApp
()
async
{
// Run the app defined in GenL10nProject.main and wait for it to
// send '#l10n END' to its stdout.
final
Completer
<
void
>
l10nEnd
=
Completer
<
void
>();
...
...
@@ -75,6 +77,10 @@ void main() {
await
_flutter
.
run
();
await
l10nEnd
.
future
;
await
subscription
.
cancel
();
return
stdout
;
}
void
expectOutput
(
StringBuffer
stdout
)
{
expect
(
stdout
.
toString
(),
'#l10n 0 (--- supportedLocales tests ---)
\n
'
'#l10n 1 (supportedLocales[0]: languageCode: en, countryCode: null, scriptCode: null)
\n
'
...
...
@@ -133,5 +139,17 @@ void main() {
'#l10n 54 (Flutter is "amazing", times 2!)
\n
'
'#l10n END
\n
'
);
}
test
(
'generated l10n classes produce expected localized strings'
,
()
async
{
setUpAndRunGenL10n
();
final
StringBuffer
stdout
=
await
runApp
();
expectOutput
(
stdout
);
});
test
(
'generated l10n classes produce expected localized strings with deferred loading'
,
()
async
{
setUpAndRunGenL10n
(
args:
<
String
>[
'--use-deferred-loading'
]);
final
StringBuffer
stdout
=
await
runApp
();
expectOutput
(
stdout
);
});
}
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