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
0963d725
Unverified
Commit
0963d725
authored
Nov 05, 2020
by
Shi-Hao Hong
Committed by
GitHub
Nov 05, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make resource attributes optional for simple cases (#68774)
parent
6688e63f
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
94 additions
and
28 deletions
+94
-28
localizations.dart
...ter_tools/lib/src/build_system/targets/localizations.dart
+9
-0
generate_localizations.dart
...lutter_tools/lib/src/commands/generate_localizations.dart
+10
-0
gen_l10n.dart
packages/flutter_tools/lib/src/localizations/gen_l10n.dart
+11
-1
gen_l10n_types.dart
...s/flutter_tools/lib/src/localizations/gen_l10n_types.dart
+48
-14
localizations_test.dart
...eneral.shard/build_system/targets/localizations_test.dart
+14
-12
generate_localizations_test.dart
...tools/test/general.shard/generate_localizations_test.dart
+2
-1
No files found.
packages/flutter_tools/lib/src/build_system/targets/localizations.dart
View file @
0963d725
...
...
@@ -61,6 +61,7 @@ void generateLocalizations({
headerFile:
options
?.
headerFile
?.
toFilePath
(),
useDeferredLoading:
options
.
deferredLoading
??
false
,
useSyntheticPackage:
options
.
useSyntheticPackage
??
true
,
areResourceAttributesRequired:
options
.
areResourceAttributesRequired
??
false
,
)
..
loadResources
()
..
writeOutputFiles
()
...
...
@@ -161,6 +162,7 @@ class LocalizationOptions {
this
.
headerFile
,
this
.
deferredLoading
,
this
.
useSyntheticPackage
=
true
,
this
.
areResourceAttributesRequired
=
false
,
})
:
assert
(
useSyntheticPackage
!=
null
);
/// The `--arb-dir` argument.
...
...
@@ -211,6 +213,12 @@ class LocalizationOptions {
/// Whether to generate the Dart localization files in a synthetic package
/// or in a custom directory.
final
bool
useSyntheticPackage
;
/// The `required-resource-attributes` argument.
///
/// Whether to require all resource ids to contain a corresponding
/// resource attribute.
final
bool
areResourceAttributesRequired
;
}
/// Parse the localizations configuration options from [file].
...
...
@@ -243,6 +251,7 @@ LocalizationOptions parseLocalizationsOptions({
headerFile:
_tryReadUri
(
yamlMap
,
'header-file'
,
logger
),
deferredLoading:
_tryReadBool
(
yamlMap
,
'use-deferred-loading'
,
logger
),
useSyntheticPackage:
_tryReadBool
(
yamlMap
,
'synthetic-package'
,
logger
)
??
true
,
areResourceAttributesRequired:
_tryReadBool
(
yamlMap
,
'required-resource-attributes'
,
logger
)
??
false
,
);
}
...
...
packages/flutter_tools/lib/src/commands/generate_localizations.dart
View file @
0963d725
...
...
@@ -150,6 +150,14 @@ class GenerateLocalizationsCommand extends FlutterCommand {
'
\n\n
'
'When null, the relative path to the present working directory will be used.'
);
argParser
.
addFlag
(
'required-resource-attributes'
,
help:
'Requires all resource ids to contain a corresponding resource attribute.
\n\n
'
'By default, simple messages will not require metadata, but it is highly '
'recommended as this provides context for the meaning of a message to '
'readers.
\n\n
'
'Resource attributes are still required for plural messages.'
);
}
final
FileSystem
_fileSystem
;
...
...
@@ -178,6 +186,7 @@ class GenerateLocalizationsCommand extends FlutterCommand {
final
String
inputsAndOutputsListPath
=
stringArg
(
'gen-inputs-and-outputs-list'
);
final
bool
useSyntheticPackage
=
boolArg
(
'synthetic-package'
);
final
String
projectPathString
=
stringArg
(
'project-dir'
);
final
bool
areResourceAttributesRequired
=
boolArg
(
'required-resource-attributes'
);
final
LocalizationsGenerator
localizationsGenerator
=
LocalizationsGenerator
(
_fileSystem
);
...
...
@@ -196,6 +205,7 @@ class GenerateLocalizationsCommand extends FlutterCommand {
inputsAndOutputsListPath:
inputsAndOutputsListPath
,
useSyntheticPackage:
useSyntheticPackage
,
projectPathString:
projectPathString
,
areResourceAttributesRequired:
areResourceAttributesRequired
,
)
..
loadResources
()
..
writeOutputFiles
()
...
...
packages/flutter_tools/lib/src/localizations/gen_l10n.dart
View file @
0963d725
...
...
@@ -526,6 +526,12 @@ class LocalizationsGenerator {
List
<
String
>
_inputFileList
;
List
<
String
>
_outputFileList
;
/// Whether or not resource attributes are required for each corresponding
/// resource id.
///
/// Resource attributes provide metadata about the message.
bool
_areResourceAttributesRequired
;
/// Initializes [inputDirectory], [outputDirectory], [templateArbFile],
/// [outputFile] and [className].
///
...
...
@@ -547,6 +553,7 @@ class LocalizationsGenerator {
String
inputsAndOutputsListPath
,
bool
useSyntheticPackage
=
true
,
String
projectPathString
,
bool
areResourceAttributesRequired
=
false
,
})
{
_useSyntheticPackage
=
useSyntheticPackage
;
setProjectDir
(
projectPathString
);
...
...
@@ -559,6 +566,7 @@ class LocalizationsGenerator {
_setUseDeferredLoading
(
useDeferredLoading
);
className
=
classNameString
;
_setInputsAndOutputsListFile
(
inputsAndOutputsListPath
);
_areResourceAttributesRequired
=
areResourceAttributesRequired
;
}
static
bool
_isNotReadable
(
FileStat
fileStat
)
{
...
...
@@ -793,7 +801,9 @@ class LocalizationsGenerator {
void
loadResources
()
{
final
AppResourceBundle
templateBundle
=
AppResourceBundle
(
templateArbFile
);
_templateArbLocale
=
templateBundle
.
locale
;
_allMessages
=
templateBundle
.
resourceIds
.
map
((
String
id
)
=>
Message
(
templateBundle
.
resources
,
id
));
_allMessages
=
templateBundle
.
resourceIds
.
map
((
String
id
)
=>
Message
(
templateBundle
.
resources
,
id
,
_areResourceAttributesRequired
,
));
for
(
final
String
resourceId
in
templateBundle
.
resourceIds
)
{
if
(!
_isValidGetterAndMethodName
(
resourceId
))
{
throw
L10nException
(
...
...
packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart
View file @
0963d725
...
...
@@ -270,12 +270,12 @@ class Placeholder {
// localized string to be shown for the template ARB file's locale.
// The docs for the Placeholder explain how placeholder entries are defined.
class
Message
{
Message
(
Map
<
String
,
dynamic
>
bundle
,
this
.
resourceId
)
Message
(
Map
<
String
,
dynamic
>
bundle
,
this
.
resourceId
,
bool
isResourceAttributeRequired
)
:
assert
(
bundle
!=
null
),
assert
(
resourceId
!=
null
&&
resourceId
.
isNotEmpty
),
value
=
_value
(
bundle
,
resourceId
),
description
=
_description
(
bundle
,
resourceId
),
placeholders
=
_placeholders
(
bundle
,
resourceId
),
description
=
_description
(
bundle
,
resourceId
,
isResourceAttributeRequired
),
placeholders
=
_placeholders
(
bundle
,
resourceId
,
isResourceAttributeRequired
),
_pluralMatch
=
_pluralRE
.
firstMatch
(
_value
(
bundle
,
resourceId
));
static
final
RegExp
_pluralRE
=
RegExp
(
r'\s*\{([\w\s,]*),\s*plural\s*,'
);
...
...
@@ -312,25 +312,51 @@ class Message {
return
bundle
[
resourceId
]
as
String
;
}
static
Map
<
String
,
dynamic
>
_attributes
(
Map
<
String
,
dynamic
>
bundle
,
String
resourceId
)
{
static
Map
<
String
,
dynamic
>
_attributes
(
Map
<
String
,
dynamic
>
bundle
,
String
resourceId
,
bool
isResourceAttributeRequired
,
)
{
final
dynamic
attributes
=
bundle
[
'@
$resourceId
'
];
if
(
attributes
==
null
)
{
throw
L10nException
(
'Resource attribute "@
$resourceId
" was not found. Please '
'ensure that each resource has a corresponding @resource.'
);
if
(
isResourceAttributeRequired
)
{
if
(
attributes
==
null
)
{
throw
L10nException
(
'Resource attribute "@
$resourceId
" was not found. Please '
'ensure that each resource has a corresponding @resource.'
);
}
}
if
(
attributes
is
!
Map
<
String
,
dynamic
>)
{
if
(
attributes
!=
null
&&
attributes
is
!
Map
<
String
,
dynamic
>)
{
throw
L10nException
(
'The resource attribute "@
$resourceId
" is not a properly formatted Map. '
'Ensure that it is a map with keys that are strings.'
);
}
final
RegExpMatch
pluralRegExp
=
_pluralRE
.
firstMatch
(
_value
(
bundle
,
resourceId
));
final
bool
isPlural
=
pluralRegExp
!=
null
&&
pluralRegExp
.
groupCount
==
1
;
if
(
attributes
==
null
&&
isPlural
)
{
throw
L10nException
(
'Resource attribute "@
$resourceId
" was not found. Please '
'ensure that plural resources have a corresponding @resource.'
);
}
return
attributes
as
Map
<
String
,
dynamic
>;
}
static
String
_description
(
Map
<
String
,
dynamic
>
bundle
,
String
resourceId
)
{
final
dynamic
value
=
_attributes
(
bundle
,
resourceId
)[
'description'
];
static
String
_description
(
Map
<
String
,
dynamic
>
bundle
,
String
resourceId
,
bool
isResourceAttributeRequired
,
)
{
final
Map
<
String
,
dynamic
>
resourceAttributes
=
_attributes
(
bundle
,
resourceId
,
isResourceAttributeRequired
);
if
(
resourceAttributes
==
null
)
{
return
null
;
}
final
dynamic
value
=
resourceAttributes
[
'description'
];
if
(
value
==
null
)
{
return
null
;
}
...
...
@@ -342,8 +368,16 @@ class Message {
return
value
as
String
;
}
static
List
<
Placeholder
>
_placeholders
(
Map
<
String
,
dynamic
>
bundle
,
String
resourceId
)
{
final
dynamic
value
=
_attributes
(
bundle
,
resourceId
)[
'placeholders'
];
static
List
<
Placeholder
>
_placeholders
(
Map
<
String
,
dynamic
>
bundle
,
String
resourceId
,
bool
isResourceAttributeRequired
,
)
{
final
Map
<
String
,
dynamic
>
resourceAttributes
=
_attributes
(
bundle
,
resourceId
,
isResourceAttributeRequired
);
if
(
resourceAttributes
==
null
)
{
return
<
Placeholder
>[];
}
final
dynamic
value
=
resourceAttributes
[
'placeholders'
];
if
(
value
==
null
)
{
return
<
Placeholder
>[];
}
...
...
packages/flutter_tools/test/general.shard/build_system/targets/localizations_test.dart
View file @
0963d725
...
...
@@ -39,6 +39,7 @@ void main() {
templateArbFile:
Uri
.
file
(
'example.arb'
),
untranslatedMessagesFile:
Uri
.
file
(
'untranslated'
),
useSyntheticPackage:
false
,
areResourceAttributesRequired:
true
,
);
final
LocalizationsGenerator
mockLocalizationsGenerator
=
MockLocalizationsGenerator
();
...
...
@@ -52,18 +53,19 @@ void main() {
verify
(
mockLocalizationsGenerator
.
initialize
(
inputPathString:
'arb'
,
outputPathString:
null
,
templateArbFileName:
'example.arb'
,
outputFileString:
'bar'
,
classNameString:
'Foo'
,
preferredSupportedLocale:
<
String
>[
'en_US'
],
headerString:
'HEADER'
,
headerFile:
'header'
,
useDeferredLoading:
true
,
inputsAndOutputsListPath:
'/'
,
useSyntheticPackage:
false
,
projectPathString:
'/'
,
inputPathString:
'arb'
,
outputPathString:
null
,
templateArbFileName:
'example.arb'
,
outputFileString:
'bar'
,
classNameString:
'Foo'
,
preferredSupportedLocale:
<
String
>[
'en_US'
],
headerString:
'HEADER'
,
headerFile:
'header'
,
useDeferredLoading:
true
,
inputsAndOutputsListPath:
'/'
,
useSyntheticPackage:
false
,
projectPathString:
'/'
,
areResourceAttributesRequired:
true
,
),
).
called
(
1
);
verify
(
mockLocalizationsGenerator
.
loadResources
()).
called
(
1
);
...
...
packages/flutter_tools/test/general.shard/generate_localizations_test.dart
View file @
0963d725
...
...
@@ -1587,7 +1587,7 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
},
);
test
(
'should throw when resource is missing resource attribute'
,
()
{
test
(
'should throw when resource is missing resource attribute
(isResourceAttributeRequired = true)
'
,
()
{
const
String
arbFileWithMissingResourceAttribute
=
'''
{
"title": "Stocks"
...
...
@@ -1605,6 +1605,7 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
templateArbFileName:
defaultTemplateArbFileName
,
outputFileString:
defaultOutputFileString
,
classNameString:
defaultClassNameString
,
areResourceAttributesRequired:
true
,
);
generator
.
loadResources
();
generator
.
writeOutputFiles
();
...
...
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