diff --git a/pkgs/messages/example_json/.gitignore b/pkgs/messages/example_json/.gitignore index 3c8a1572..ebc4c541 100644 --- a/pkgs/messages/example_json/.gitignore +++ b/pkgs/messages/example_json/.gitignore @@ -4,3 +4,4 @@ # Conventional directory for build output. build/ +bin/example/ \ No newline at end of file diff --git a/pkgs/messages/example_json/lib/testarb.arb b/pkgs/messages/example_json/assets/l10n/testarb.arb similarity index 100% rename from pkgs/messages/example_json/lib/testarb.arb rename to pkgs/messages/example_json/assets/l10n/testarb.arb diff --git a/pkgs/messages/example_json/lib/testarb_de.arb b/pkgs/messages/example_json/assets/l10n/testarb_de.arb similarity index 100% rename from pkgs/messages/example_json/lib/testarb_de.arb rename to pkgs/messages/example_json/assets/l10n/testarb_de.arb diff --git a/pkgs/messages/example_json/lib/testarbctx2.arb b/pkgs/messages/example_json/assets/l10n/testarbctx2.arb similarity index 100% rename from pkgs/messages/example_json/lib/testarbctx2.arb rename to pkgs/messages/example_json/assets/l10n/testarbctx2.arb diff --git a/pkgs/messages/example_json/lib/testarbctx2_fr.arb b/pkgs/messages/example_json/assets/l10n/testarbctx2_fr.arb similarity index 100% rename from pkgs/messages/example_json/lib/testarbctx2_fr.arb rename to pkgs/messages/example_json/assets/l10n/testarbctx2_fr.arb diff --git a/pkgs/messages/example_json/bin/example.dart b/pkgs/messages/example_json/bin/example.dart index f53bce4c..1b6b1318 100644 --- a/pkgs/messages/example_json/bin/example.dart +++ b/pkgs/messages/example_json/bin/example.dart @@ -4,13 +4,10 @@ // ignore_for_file: prefer_function_declarations_over_variables -import 'dart:io'; - -import 'package:example_json/testarbctx2.g.dart'; +import 'package:example_json/messages.g.dart'; Future main(List arguments) async { - final messages = - AboutPageMessages((String id) async => File(id).readAsString()); + final messages = AboutPageMessages(); // final index = AboutPageMessagesEnum.aboutMessage; await messages.loadLocale('en'); diff --git a/pkgs/messages/example_json/hook/build.dart b/pkgs/messages/example_json/hook/build.dart new file mode 100644 index 00000000..64261254 --- /dev/null +++ b/pkgs/messages/example_json/hook/build.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:messages_builder/hook.dart'; +import 'package:native_assets_cli/native_assets_cli.dart'; + +void main(List args) { + build(args, (config, output) async { + // final builder = MessagesDataBuilder.fromFiles( + // [ + // 'assets/l10n/testarb.arb', + // 'assets/l10n/testarb_de.arb', + // 'assets/l10n/testarbctx2.arb', + // 'assets/l10n/testarbctx2_fr.arb', + // ], + // ); + final builder = MessagesDataBuilder.fromFolder('assets/l10n/'); + + await builder.run(config: config, output: output, logger: null); + }); +} diff --git a/pkgs/messages/example_json/lib/l10n.messages b/pkgs/messages/example_json/lib/l10n.messages new file mode 100644 index 00000000..e69de29b diff --git a/pkgs/messages/example_json/lib/messages.g.dart b/pkgs/messages/example_json/lib/messages.g.dart new file mode 100644 index 00000000..1ebaa48c --- /dev/null +++ b/pkgs/messages/example_json/lib/messages.g.dart @@ -0,0 +1,153 @@ +// Generated by package:messages_builder. + +import 'dart:ffi'; + +import 'package:intl4x/intl4x.dart'; +import 'package:messages/messages_json.dart'; + +class AboutPageMessages { + AboutPageMessages(); + + String _currentLocale = 'en'; + + final Map _messages = {}; + + static const _dataFiles = { + 'fr': ('package:example_json/assets/l10n/testarbctx2_fr.json', 'EyPjEJJU'), + 'en': ('package:example_json/assets/l10n/testarbctx2.json', 'QrwRSsOy') + }; + + String get currentLocale => _currentLocale; + + MessageList get _currentMessages => _messages[currentLocale]!; + + static Iterable get knownLocales => _dataFiles.keys; + + Future loadLocale(String locale) async { + if (!_messages.containsKey(locale)) { + final info = _dataFiles[locale]; + final carb = info?.$1; + if (carb == null) { + throw ArgumentError('Locale $locale is not in $knownLocales'); + } + final data = await AssetBundle.loadString(carb); + final messageList = MessageListJson.fromString(data, _pluralSelector); + if (messageList.preamble.hash != info?.$2) { + throw ArgumentError(''' + Messages file for locale $locale has different hash "${messageList.preamble.hash}" than generated code "${info?.$2}".'''); + } + _messages[locale] = messageList; + } + _currentLocale = locale; + } + + void loadAllLocales() { + for (final locale in knownLocales) { + loadLocale(locale); + } + } + + String aboutMessage(String websitename) => + _currentMessages.generateStringAtIndex(0, [websitename]); + + String helloAndWelcome( + String firstName, + int lastName, + ) => + _currentMessages.generateStringAtIndex(1, [firstName, lastName]); + + String newMessages(int newMessages) => + _currentMessages.generateStringAtIndex(2, [newMessages]); + + String newMessages2( + String gender, + int newVar, + ) => + _currentMessages.generateStringAtIndex(3, [gender, newVar]); + + String get otherMsg => _currentMessages.generateStringAtIndex(4, []); +} + +class HomePageMessages { + HomePageMessages(); + + String _currentLocale = 'en'; + + final Map _messages = {}; + + static const _dataFiles = { + 'de': ('package:example_json/assets/l10n/testarb_de.json', 'hbDN1MhX'), + 'en': ('package:example_json/assets/l10n/testarb.json', 'dr9Md951') + }; + + String get currentLocale => _currentLocale; + + MessageList get _currentMessages => _messages[currentLocale]!; + + static Iterable get knownLocales => _dataFiles.keys; + + Future loadLocale(String locale) async { + if (!_messages.containsKey(locale)) { + final info = _dataFiles[locale]; + final carb = info?.$1; + if (carb == null) { + throw ArgumentError('Locale $locale is not in $knownLocales'); + } + final data = await AssetBundle.loadString(carb); + final messageList = MessageListJson.fromString(data, _pluralSelector); + if (messageList.preamble.hash != info?.$2) { + throw ArgumentError(''' + Messages file for locale $locale has different hash "${messageList.preamble.hash}" than generated code "${info?.$2}".'''); + } + _messages[locale] = messageList; + } + _currentLocale = locale; + } + + void loadAllLocales() { + for (final locale in knownLocales) { + loadLocale(locale); + } + } + + String helloAndWelcome( + String firstName, + String lastName, + ) => + _currentMessages.generateStringAtIndex(0, [firstName, lastName]); + + String helloAndWelcome2( + String firstName, + String lastName, + ) => + _currentMessages.generateStringAtIndex(1, [firstName, lastName]); + + String newMessages(int newMessages) => + _currentMessages.generateStringAtIndex(2, [newMessages]); + + String newMessages2( + String gender, + int newVar, + ) => + _currentMessages.generateStringAtIndex(3, [gender, newVar]); +} + +Message _pluralSelector( + num howMany, + String locale, { + required Message other, + Message? few, + Message? many, + Map? numberCases, + Map? wordCases, +}) { + Message getCase(int i) => numberCases?[i] ?? wordCases?[i] ?? other; + return switch (Intl(locale: Locale.parse(locale)).plural().select(howMany)) { + PluralCategory.zero => getCase(0), + PluralCategory.one => getCase(1), + PluralCategory.two => getCase(2), + PluralCategory.few => few ?? other, + PluralCategory.many => many ?? other, + PluralCategory.other => other, + }; +} diff --git a/pkgs/messages/example_json/lib/testarb.g.dart b/pkgs/messages/example_json/lib/testarb.g.dart deleted file mode 100644 index f35050f6..00000000 --- a/pkgs/messages/example_json/lib/testarb.g.dart +++ /dev/null @@ -1,90 +0,0 @@ -// Generated by package:messages_builder. - -import 'package:intl4x/intl4x.dart'; -import 'package:messages/messages_json.dart'; - -class HomePageMessages { - HomePageMessages(this._fileLoader); - - final Future Function(String id) _fileLoader; - - String _currentLocale = 'en'; - - final Map _messages = {}; - - static const _dataFiles = { - 'de': ('lib/testarb_de.json', 'hbDN1MhX'), - 'en': ('lib/testarb.json', 'dr9Md951') - }; - - String get currentLocale => _currentLocale; - - MessageList get _currentMessages => _messages[currentLocale]!; - - static Iterable get knownLocales => _dataFiles.keys; - - Future loadLocale(String locale) async { - if (!_messages.containsKey(locale)) { - final info = _dataFiles[locale]; - final carb = info?.$1; - if (carb == null) { - throw ArgumentError('Locale $locale is not in $knownLocales'); - } - final data = await _fileLoader(carb); - final messageList = MessageListJson.fromString(data, pluralSelector); - if (messageList.preamble.hash != info?.$2) { - throw ArgumentError(''' - Messages file for locale $locale has different hash "${messageList.preamble.hash}" than generated code "${info?.$2}".'''); - } - _messages[locale] = messageList; - } - _currentLocale = locale; - } - - void loadAllLocales() { - for (final locale in knownLocales) { - loadLocale(locale); - } - } - - Message pluralSelector( - num howMany, { - required Message other, - Message? few, - Message? many, - Map? numberCases, - Map? wordCases, - }) { - Message getCase(int i) => numberCases?[i] ?? wordCases?[i] ?? other; - return switch ( - Intl(locale: Locale.parse(currentLocale)).plural().select(howMany)) { - PluralCategory.zero => getCase(0), - PluralCategory.one => getCase(1), - PluralCategory.two => getCase(2), - PluralCategory.few => few ?? other, - PluralCategory.many => many ?? other, - PluralCategory.other => other, - }; - } - - String helloAndWelcome( - String firstName, - String lastName, - ) => - _currentMessages.generateStringAtIndex(0, [firstName, lastName]); - - String helloAndWelcome2( - String firstName, - String lastName, - ) => - _currentMessages.generateStringAtIndex(1, [firstName, lastName]); - - String newMessages(int newMessages) => - _currentMessages.generateStringAtIndex(2, [newMessages]); - - String newMessages2( - String gender, - int newVar, - ) => - _currentMessages.generateStringAtIndex(3, [gender, newVar]); -} diff --git a/pkgs/messages/example_json/lib/testarb.json b/pkgs/messages/example_json/lib/testarb.json deleted file mode 100644 index d46d15af..00000000 --- a/pkgs/messages/example_json/lib/testarb.json +++ /dev/null @@ -1 +0,0 @@ -[0,"en","dr9Md951",0,null,["Welcome von !",[8,0],[13,1]],["Welcome von !",[8,0],[13,1]],[6,"test ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],[6,"test ",[4,0,"Two new Messages",{"male":"No new messages","female":"One new message"}]]] \ No newline at end of file diff --git a/pkgs/messages/example_json/lib/testarb_de.json b/pkgs/messages/example_json/lib/testarb_de.json deleted file mode 100644 index 8480d165..00000000 --- a/pkgs/messages/example_json/lib/testarb_de.json +++ /dev/null @@ -1 +0,0 @@ -[0,"de","hbDN1MhX",0,null,["Willkommen von ",[11,0],[16,1]],["Willkommen von 2",[11,0],[16,1]],[6,"testde ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],"testdse is just a simple message"] \ No newline at end of file diff --git a/pkgs/messages/example_json/lib/testarbctx2.g.dart b/pkgs/messages/example_json/lib/testarbctx2.g.dart deleted file mode 100644 index 55aa20f5..00000000 --- a/pkgs/messages/example_json/lib/testarbctx2.g.dart +++ /dev/null @@ -1,89 +0,0 @@ -// Generated by package:messages_builder. - -import 'package:intl4x/intl4x.dart'; -import 'package:messages/messages_json.dart'; - -class AboutPageMessages { - AboutPageMessages(this._fileLoader); - - final Future Function(String id) _fileLoader; - - String _currentLocale = 'en'; - - final Map _messages = {}; - - static const _dataFiles = { - 'fr': ('lib/testarbctx2_fr.json', 'EyPjEJJU'), - 'en': ('lib/testarbctx2.json', 'QrwRSsOy') - }; - - String get currentLocale => _currentLocale; - - MessageList get _currentMessages => _messages[currentLocale]!; - - static Iterable get knownLocales => _dataFiles.keys; - - Future loadLocale(String locale) async { - if (!_messages.containsKey(locale)) { - final info = _dataFiles[locale]; - final carb = info?.$1; - if (carb == null) { - throw ArgumentError('Locale $locale is not in $knownLocales'); - } - final data = await _fileLoader(carb); - final messageList = MessageListJson.fromString(data, pluralSelector); - if (messageList.preamble.hash != info?.$2) { - throw ArgumentError(''' - Messages file for locale $locale has different hash "${messageList.preamble.hash}" than generated code "${info?.$2}".'''); - } - _messages[locale] = messageList; - } - _currentLocale = locale; - } - - void loadAllLocales() { - for (final locale in knownLocales) { - loadLocale(locale); - } - } - - Message pluralSelector( - num howMany, { - required Message other, - Message? few, - Message? many, - Map? numberCases, - Map? wordCases, - }) { - Message getCase(int i) => numberCases?[i] ?? wordCases?[i] ?? other; - return switch ( - Intl(locale: Locale.parse(currentLocale)).plural().select(howMany)) { - PluralCategory.zero => getCase(0), - PluralCategory.one => getCase(1), - PluralCategory.two => getCase(2), - PluralCategory.few => few ?? other, - PluralCategory.many => many ?? other, - PluralCategory.other => other, - }; - } - - String aboutMessage(String websitename) => - _currentMessages.generateStringAtIndex(0, [websitename]); - - String helloAndWelcome( - String firstName, - int lastName, - ) => - _currentMessages.generateStringAtIndex(1, [firstName, lastName]); - - String newMessages(int newMessages) => - _currentMessages.generateStringAtIndex(2, [newMessages]); - - String newMessages2( - String gender, - int newVar, - ) => - _currentMessages.generateStringAtIndex(3, [gender, newVar]); - - String get otherMsg => _currentMessages.generateStringAtIndex(4, []); -} diff --git a/pkgs/messages/example_json/lib/testarbctx2.json b/pkgs/messages/example_json/lib/testarbctx2.json deleted file mode 100644 index a56c79c5..00000000 --- a/pkgs/messages/example_json/lib/testarbctx2.json +++ /dev/null @@ -1 +0,0 @@ -[0,"en","QrwRSsOy",0,null,["About ",[6,0]],["Welcome von <",[8,0],[13,1]],[6,"test ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],[6,"test ",[4,0,"Two new Messages",{"male":"No new messages","female":"One new message"}]],"other"] \ No newline at end of file diff --git a/pkgs/messages/example_json/lib/testarbctx2_fr.json b/pkgs/messages/example_json/lib/testarbctx2_fr.json deleted file mode 100644 index 61b6c08f..00000000 --- a/pkgs/messages/example_json/lib/testarbctx2_fr.json +++ /dev/null @@ -1 +0,0 @@ -[0,"fr","EyPjEJJU",0,null,["Sur ",[4,0]],["Welcome von <",[8,0],[13,1]],[6,"test ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],[6,"test ",[4,0,"Two new Messages",{"male":"No new messages","female":"One new message"}]],"other"] \ No newline at end of file diff --git a/pkgs/messages/example_json/pubspec.yaml b/pkgs/messages/example_json/pubspec.yaml index 827ea85a..5b5f489d 100644 --- a/pkgs/messages/example_json/pubspec.yaml +++ b/pkgs/messages/example_json/pubspec.yaml @@ -6,16 +6,19 @@ environment: sdk: ^3.0.0 dependencies: - intl4x: ^0.7.0 + intl4x: + path: ../../intl4x messages: ^0.2.0 + native_assets_cli: ^0.6.0 dev_dependencies: build_daemon: ^4.0.0 build_runner: ^2.3.3 - build_web_compilers: ^3.2.7 - dart_flutter_team_lints: ^1.0.0 - lints: ^2.0.0 - messages_builder: ^0.2.0 + build_web_compilers: ^4.0.10 + dart_flutter_team_lints: ^3.1.0 + lints: ^4.0.0 + messages_builder: + path: ../../messages_builder path: ^1.8.3 test: ^1.16.0 diff --git a/pkgs/messages/lib/src/message.dart b/pkgs/messages/lib/src/message.dart index 54adec19..7890bea2 100644 --- a/pkgs/messages/lib/src/message.dart +++ b/pkgs/messages/lib/src/message.dart @@ -110,6 +110,7 @@ final class PluralMessage extends Message { }) { return pluralSelector( allArgs[argIndex] as num, + locale!, numberCases: numberCases, wordCases: wordCases, few: few, diff --git a/pkgs/messages/lib/src/plural_selector.dart b/pkgs/messages/lib/src/plural_selector.dart index 5d6899bc..6676ae64 100644 --- a/pkgs/messages/lib/src/plural_selector.dart +++ b/pkgs/messages/lib/src/plural_selector.dart @@ -5,7 +5,8 @@ import 'message.dart'; typedef PluralSelector = Message Function( - num howMany, { + num howMany, + String locale, { Map? numberCases, Map? wordCases, Message? few, diff --git a/pkgs/messages/pubspec.yaml b/pkgs/messages/pubspec.yaml index 82e3b90e..75eb2b46 100644 --- a/pkgs/messages/pubspec.yaml +++ b/pkgs/messages/pubspec.yaml @@ -9,6 +9,9 @@ environment: dependencies: collection: ^1.17.1 intl: ^0.18.0 + logging: ^1.2.0 + native_assets_cli: ^0.6.0 + path: ^1.9.0 dev_dependencies: dart_flutter_team_lints: ^2.1.1 diff --git a/pkgs/messages/test/messagelist_json_test.dart b/pkgs/messages/test/messagelist_json_test.dart index ab291453..d5d8023e 100644 --- a/pkgs/messages/test/messagelist_json_test.dart +++ b/pkgs/messages/test/messagelist_json_test.dart @@ -7,13 +7,13 @@ import 'package:messages/messages_json.dart'; import 'package:test/test.dart'; Message intlPluralSelector( - num howMany, { + num howMany, + String locale, { Map? numberCases, Map? wordCases, Message? few, Message? many, required Message other, - String? locale, }) { return old_intl.Intl.pluralLogic( howMany, diff --git a/pkgs/messages_builder/build.yaml b/pkgs/messages_builder/build.yaml index 38ac91d8..13de16e9 100644 --- a/pkgs/messages_builder/build.yaml +++ b/pkgs/messages_builder/build.yaml @@ -3,6 +3,9 @@ builders: copyBuilder: import: "package:messages_builder/builder.dart" builder_factories: ["messagesBuilder"] - build_extensions: {'.arb': ['.g.dart', '.json'], '^pubspec.yaml': []} + build_extensions: + { + "l10n.messages": ["messages.g.dart"], + } build_to: source - auto_apply: root_package \ No newline at end of file + auto_apply: root_package diff --git a/pkgs/messages_builder/lib/arb_parser.dart b/pkgs/messages_builder/lib/arb_parser.dart index 0646efc3..0d8aba1e 100644 --- a/pkgs/messages_builder/lib/arb_parser.dart +++ b/pkgs/messages_builder/lib/arb_parser.dart @@ -4,7 +4,6 @@ import 'dart:convert'; -import 'package:build/build.dart'; import 'package:crypto/crypto.dart'; import 'message_parser/message_parser.dart'; @@ -14,11 +13,7 @@ class ArbParser { final bool addName; ArbParser([this.addName = false]); - MessagesWithMetadata parseMessageFile( - Map arb, - AssetId assetId, [ - String inferredLocale = 'en_US', - ]) { + MessagesWithMetadata parseMessageFile(Map arb) { final locale = arb['@@locale'] as String?; final context = arb['@@context'] as String?; final referencePath = arb['@@x-reference'] as String?; @@ -30,12 +25,11 @@ class ArbParser { final messages = messagesWithKeys.map((e) => e.$2).toList(); return MessagesWithMetadata( messages, - locale ?? inferredLocale, + locale, context, referencePath, getHash(arb), arb.keys.any((key) => key.startsWith('@') && !key.startsWith('@@')), - assetId, ); } diff --git a/pkgs/messages_builder/lib/builder.dart b/pkgs/messages_builder/lib/builder.dart index f18435a3..a3bfca9c 100644 --- a/pkgs/messages_builder/lib/builder.dart +++ b/pkgs/messages_builder/lib/builder.dart @@ -4,16 +4,16 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:typed_data'; import 'package:build/build.dart'; +import 'package:code_builder/code_builder.dart'; import 'package:collection/collection.dart'; import 'package:glob/glob.dart'; -import 'package:messages_serializer/messages_serializer.dart'; import 'package:path/path.dart' as path; import 'arb_parser.dart'; import 'code_generation/code.dart'; +import 'code_generation/library_generation.dart'; import 'generation_options.dart'; import 'message_with_metadata.dart'; @@ -27,48 +27,60 @@ class MessagesBuilder implements Builder { @override Map> get buildExtensions => { - '.arb': ['.g.dart', '.json'], - '^pubspec.yaml': [], + 'l10n.messages': ['messages.g.dart'], }; @override Future build(BuildStep buildStep) async { - final generationOptions = await GenerationOptions.fromPubspec(buildStep); + final s = await GenerationOptions.getPubspecFrom(buildStep); + final generationOptions = await GenerationOptions.fromPubspec(s); await BuildStepGenerator(buildStep, generationOptions).build(); } } class BuildStepGenerator { final BuildStep buildStep; - AssetId get inputId => buildStep.inputId; final GenerationOptions options; BuildStepGenerator(this.buildStep, this.options); - Serializer get serializer => getSerializer(options); - Future build() async { final allMessageFiles = await getParsedMessageFiles(); - final inputMessageFile = allMessageFiles - .singleWhere((messageFile) => messageFile.assetId == inputId); - final parentFile = getParentFile(allMessageFiles, inputMessageFile); - - final reducedMessageFile = reduce(parentFile, inputMessageFile); - - await writeDataFile(reducedMessageFile); - if (parentFile.assetId == inputId) { - await writeDartLibrary(allMessageFiles, reducedMessageFile); + final libraries = []; + for (final input in allMessageFiles) { + final parentFile = getParentFile(allMessageFiles, input); + final reducedMessageFile = + scrub(input.$2, parentFile.$2.messages.map((e) => e.name).toList()); + if (parentFile.$1 == input.$1) { + final library = await writeDartLibrary( + allMessageFiles, + reducedMessageFile, + ); + libraries.add(library); + } + } + if (libraries.isNotEmpty) { + final code = CodeGenerator( + options: options, + libraries: libraries, + ).generate(); + + await buildStep.writeAsString( + AssetId( + buildStep.inputId.package, + buildStep.inputId.path + .replaceFirst('l10n.messages', 'messages.g.dart')), + code, + ); } } /// Only keep the messages which are in the parent file, as only those will /// get a generated method to embed them in code. - MessagesWithMetadata reduce( - MessagesWithMetadata parentFile, + MessagesWithMetadata scrub( MessagesWithMetadata inputMessageFile, + List messageNames, ) { - final messageNames = parentFile.messages.map((e) => e.name).toList(); - final messages = inputMessageFile.messages .where((message) => messageNames.contains(message.name)) .toList() @@ -80,68 +92,55 @@ class BuildStepGenerator { /// Generates the Dart library which extracts the messages from their file /// format and makes the available to the user in a way specified through the /// `GenerationOptions`. - Future writeDartLibrary( - List assetList, + Future writeDartLibrary( + List<(AssetId, MessagesWithMetadata)> assetList, MessagesWithMetadata messageList, ) async { - final resourcesInContext = - assetList.where((resource) => resource.context == messageList.context); + final resourcesInContext = assetList + .where((resource) => resource.$2.context == messageList.context); final localeToResourceInfo = Map.fromEntries(resourcesInContext.map((resource) => MapEntry( - resource.locale, + resource.$2.locale ?? inferLocale(resource.$1.path) ?? 'en_US', ( - path: resource.assetId.changeExtension('.json').path, - hasch: resource.hash, + id: 'package:${buildStep.inputId.package}/${resource.$1.changeExtension('.json').path}', + hasch: resource.$2.hash, ), ))); printIncludeFilesNotification(messageList.context, localeToResourceInfo); - final libraryCode = CodeGenerator( + return LibraryGeneration( options, - messageList, + messageList.context, + messageList.locale!, + messageList.messages, localeToResourceInfo, ).generate(); - - await buildStep.writeAsString( - inputId.changeExtension('.g.dart'), - libraryCode, - ); - } - - Serializer getSerializer(GenerationOptions generationOptions) { - return JsonSerializer(generationOptions.findById); } - Future> getParsedMessageFiles() async => - buildStep.findAssets(Glob('**.arb')).asyncMap(parseMessageFile).toList(); + Future> getParsedMessageFiles() async => + buildStep + .findAssets(Glob('**.arb')) + .asyncMap((assetId) async => ( + assetId, + await parseMessageFile(await getArbfile(assetId), options) + )) + .toList(); - Future parseMessageFile(AssetId assetId) async { + Future getArbfile(AssetId assetId) async { final arbFile = await buildStep.readAsString(assetId); - final decoded = jsonDecode(arbFile) as Map; - final arb = Map.castFrom(decoded); - final inferredLocale = path - .basenameWithoutExtension(assetId.path) - .split('_') - .skip(1) - .join('_'); - final messageList = ArbParser(options.findById).parseMessageFile( - arb, - assetId, - inferredLocale, - ); - return messageList; + return arbFile; } /// Either get the referenced parent file, or try to infer which it might be. - static MessagesWithMetadata getParentFile( - List arbResources, - MessagesWithMetadata arb, + static (AssetId, MessagesWithMetadata) getParentFile( + List<(AssetId, MessagesWithMetadata)> arbResources, + (AssetId, MessagesWithMetadata) arb, ) { /// If the reference file is explicitly named, return that. - if (arb.referencePath != null) { + if (arb.$2.referencePath != null) { final reference = arbResources - .where((element) => element.assetId.path == arb.referencePath) + .where((element) => element.$1.path == arb.$2.referencePath) .firstOrNull; if (reference != null) { return reference; @@ -150,7 +149,7 @@ class BuildStepGenerator { /// If the current file is a reference for others, return the current file. final references = arbResources - .where((resource) => resource.referencePath == arb.assetId.path); + .where((resource) => resource.$2.referencePath == arb.$1.path); if (references.contains(arb)) { return arb; } @@ -158,9 +157,9 @@ class BuildStepGenerator { /// Try to infer by looking at which files contain metadata, which is a sign /// they might be the references for others in the same context. final contextLeads = - arbResources.groupListsBy((resource) => resource.context); - final contextWithMetadata = contextLeads[arb.context]! - .firstWhereOrNull((element) => element.hasMetadata); + arbResources.groupListsBy((resource) => resource.$2.context); + final contextWithMetadata = contextLeads[arb.$2.context]! + .firstWhereOrNull((element) => element.$2.hasMetadata); if (contextWithMetadata != null) { return contextWithMetadata; } @@ -168,41 +167,36 @@ class BuildStepGenerator { return arb; } - /// This writes the file containing the messages, which can be either a binary - /// `.carb` file or a JSON file, depending on the serializer. - /// - /// This message data file must be shipped with the application, it is - /// unpacked at runtime so that the messages can be read from it. - /// - /// Returns the list of indices of the messages which are visible to the user. - Future writeDataFile(MessagesWithMetadata messages) async { - final serialization = serializer.serialize( - messages.hash, - messages.locale, - messages.messages.map((e) => e.message).toList(), - ); - final carbFile = messages.assetId.changeExtension('.json'); - final data = serialization.data; - if (data is Uint8List) { - await buildStep.writeAsBytes(carbFile, data); - } else if (data is String) { - await buildStep.writeAsString(carbFile, data); - } - } - /// Display a notification to the user to include the newly generated files /// in their assets. void printIncludeFilesNotification( String? context, - Map localeToResource, + Map localeToResource, ) { var contextMessage = 'The'; if (context != null) { contextMessage = 'For the messages in $context, the'; } final fileList = - localeToResource.entries.map((e) => '\t${e.value.path}').join('\n'); + localeToResource.entries.map((e) => '\t${e.value.id}').join('\n'); print( '''$contextMessage following files need to be declared in your assets:\n$fileList'''); } } + +Future parseMessageFile( + String arbFile, + GenerationOptions options, +) async { + final decoded = jsonDecode(arbFile) as Map; + final arb = Map.castFrom(decoded); + return ArbParser(options.findById).parseMessageFile(arb); +} + +String? inferLocale(String localPath) { + final skip = path.basenameWithoutExtension(localPath).split('_').skip(1); + if (skip.isEmpty) { + return null; + } + return skip.join('_'); +} diff --git a/pkgs/messages_builder/lib/code_generation/class_generation.dart b/pkgs/messages_builder/lib/code_generation/class_generation.dart index 4b63f5cc..a55c6896 100644 --- a/pkgs/messages_builder/lib/code_generation/class_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/class_generation.dart @@ -8,7 +8,7 @@ import '../generation_options.dart'; import '../message_with_metadata.dart'; import 'generation.dart'; -class ClassGeneration extends Generation { +class ClassGeneration { final GenerationOptions options; final List messages; final String? context; @@ -28,7 +28,6 @@ class ClassGeneration extends Generation { String getClassName(String? context) => '${context ?? ''}Messages'; - @override List generate() { final classes = [ Class( diff --git a/pkgs/messages_builder/lib/code_generation/code.dart b/pkgs/messages_builder/lib/code_generation/code.dart index 439d3d54..e6e6aacb 100644 --- a/pkgs/messages_builder/lib/code_generation/code.dart +++ b/pkgs/messages_builder/lib/code_generation/code.dart @@ -6,37 +6,123 @@ import 'package:code_builder/code_builder.dart'; import 'package:dart_style/dart_style.dart'; import '../generation_options.dart'; -import '../message_with_metadata.dart'; -import 'library_generation.dart'; +import 'import_generation.dart'; class CodeGenerator { final GenerationOptions options; - final String? context; - final String locale; - final List messages; - final Map localeToResourceInfo; - - CodeGenerator( - this.options, - MessagesWithMetadata messageListWithMetadata, - this.localeToResourceInfo, - ) : context = messageListWithMetadata.context, - locale = messageListWithMetadata.locale, - messages = messageListWithMetadata.messages; + final List libraries; + + CodeGenerator({required this.options, required this.libraries}); String generate() { - final libs = LibraryGeneration( - options, - context, - locale, - messages, - localeToResourceInfo, - ).generate(); + final imports = ImportGeneration(options).generate(); - assert(libs.isNotEmpty); + final lib = libraries.reduce((value, element) => Library( + (p0) => p0 + ..comments.add(options.header) + ..directives.addAll(imports) + ..body.addAll([ + ...value.body, + ...element.body, + if (options.pluralSelector != PluralSelectorType.custom) + pluralSelector(), + ]), + )); final emitter = DartEmitter(orderDirectives: true); - final source = '${libs.first.accept(emitter)}'; - return DartFormatter().format(source); + final source = '${lib.accept(emitter)}'; + final code = DartFormatter().format(source); + return code; + } + + // Message Function(num, + // String locale, + // {Message? few, + // String? locale, + // Message? many, + // Map? numberCases, + // required Message other, + // Map? wordCases}) intl; + Method pluralSelector() => Method( + (mb) => mb + ..name = '_pluralSelector' + ..returns = const Reference('Message') + ..requiredParameters.addAll([ + Parameter( + (pb) => pb + ..name = 'howMany' + ..type = const Reference('num') + ..named = false, + ), + Parameter( + (pb) => pb + ..name = 'locale' + ..type = const Reference('String') + ..named = false, + ), + ]) + ..optionalParameters.addAll([ + Parameter( + (pb) => pb + ..name = 'other' + ..type = const Reference('Message') + ..required = true + ..named = true, + ), + Parameter( + (pb) => pb + ..name = 'few' + ..type = const Reference('Message?') + ..named = true, + ), + Parameter( + (pb) => pb + ..name = 'many' + ..type = const Reference('Message?') + ..named = true, + ), + Parameter( + (pb) => pb + ..name = 'numberCases' + ..type = const Reference('Map?') + ..named = true, + ), + Parameter( + (pb) => pb + ..name = 'wordCases' + ..type = const Reference('Map?') + ..named = true, + ), + ]) + ..body = pluralSelectorBody(), + ); + + Code pluralSelectorBody() { + return switch (options.pluralSelector) { + PluralSelectorType.intl => const Code(''' +return Intl.pluralLogic( + howMany, + few: few, + many: many, + zero: numberCases?[0] ?? wordCases?[0], + one: numberCases?[1] ?? wordCases?[1], + two: numberCases?[2] ?? wordCases?[2], + other: other, + locale: currentLocale, + ); + '''), + PluralSelectorType.intl4x => const Code(''' + Message getCase(int i) => numberCases?[i] ?? wordCases?[i] ?? other; + return switch (Intl(locale: Locale.parse(locale)).plural().select(howMany)) { + PluralCategory.zero => getCase(0), + PluralCategory.one => getCase(1), + PluralCategory.two => getCase(2), + PluralCategory.few => few ?? other, + PluralCategory.many => many ?? other, + PluralCategory.other => other, + }; + '''), + PluralSelectorType.custom => throw ArgumentError(), + }; } } diff --git a/pkgs/messages_builder/lib/code_generation/constructor_generation.dart b/pkgs/messages_builder/lib/code_generation/constructor_generation.dart index 936ef667..a4a9c9e3 100644 --- a/pkgs/messages_builder/lib/code_generation/constructor_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/constructor_generation.dart @@ -5,22 +5,15 @@ import 'package:code_builder/code_builder.dart'; import '../generation_options.dart'; -import 'generation.dart'; -class ConstructorGeneration extends Generation { +class ConstructorGeneration { final GenerationOptions options; ConstructorGeneration(this.options); - @override List generate() { final nativeConstructor = Constructor((cb) => cb ..requiredParameters.addAll([ - Parameter( - (pb) => pb - ..name = '_fileLoader' - ..toThis = true, - ), if (options.pluralSelector == PluralSelectorType.custom) Parameter((pb) => pb ..name = 'pluralSelector' diff --git a/pkgs/messages_builder/lib/code_generation/field_generation.dart b/pkgs/messages_builder/lib/code_generation/field_generation.dart index a6d28f67..084ad79a 100644 --- a/pkgs/messages_builder/lib/code_generation/field_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/field_generation.dart @@ -5,11 +5,10 @@ import 'package:code_builder/code_builder.dart'; import '../generation_options.dart'; -import 'generation.dart'; -class FieldGeneration extends Generation { +class FieldGeneration { final GenerationOptions options; - final Map localeToResourceInfo; + final Map localeToResourceInfo; final String locale; FieldGeneration( @@ -18,17 +17,7 @@ class FieldGeneration extends Generation { this.locale, ); - @override List generate() { - final loadingStrategy = Field( - (fb) { - final returnType = const Reference('Future').symbol; - fb - ..name = '_fileLoader' - ..modifier = FieldModifier.final$ - ..type = Reference('$returnType Function(String id)'); - }, - ); final currentLocale = Field( (fb) => fb ..type = const Reference('String') @@ -45,7 +34,7 @@ class FieldGeneration extends Generation { final dataFiles = Field( (fb) { final paths = localeToResourceInfo.entries - .map((e) => "'${e.key}' : ('${e.value.path}', '${e.value.hasch}')") + .map((e) => "'${e.key}' : ('${e.value.id}', '${e.value.hasch}')") .join(','); fb ..name = '_dataFiles' @@ -61,7 +50,6 @@ class FieldGeneration extends Generation { '''Message Function(num howMany, {Map? numberCases, Map? wordCases, Message? few, Message? many, Message other, String? locale})'''), ); final fields = [ - loadingStrategy, currentLocale, messages, dataFiles, diff --git a/pkgs/messages_builder/lib/code_generation/generation.dart b/pkgs/messages_builder/lib/code_generation/generation.dart index e6bdcef7..1f8dcbce 100644 --- a/pkgs/messages_builder/lib/code_generation/generation.dart +++ b/pkgs/messages_builder/lib/code_generation/generation.dart @@ -2,10 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -abstract class Generation { - List generate(); -} - String enumName(String? context) => '${context ?? ''}MessagesEnum'; String getDataFileName(String e) => e.split('.').first; diff --git a/pkgs/messages_builder/lib/code_generation/import_generation.dart b/pkgs/messages_builder/lib/code_generation/import_generation.dart index 79ee4e52..b616b5c8 100644 --- a/pkgs/messages_builder/lib/code_generation/import_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/import_generation.dart @@ -5,14 +5,12 @@ import 'package:code_builder/code_builder.dart'; import '../generation_options.dart'; -import 'generation.dart'; -class ImportGeneration extends Generation { +class ImportGeneration { final GenerationOptions options; ImportGeneration(this.options); - @override List generate() { final serializationImports = switch (options.deserialization) { DeserializationType.web => [ @@ -26,6 +24,10 @@ class ImportGeneration extends Generation { ], PluralSelectorType.custom => [], }; - return [...serializationImports, ...pluralImports]; + return [ + ...serializationImports, + ...pluralImports, + Directive.import('dart:ffi'), + ]; } } diff --git a/pkgs/messages_builder/lib/code_generation/library_generation.dart b/pkgs/messages_builder/lib/code_generation/library_generation.dart index 4af39339..32c44d30 100644 --- a/pkgs/messages_builder/lib/code_generation/library_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/library_generation.dart @@ -9,16 +9,14 @@ import '../message_with_metadata.dart'; import 'class_generation.dart'; import 'constructor_generation.dart'; import 'field_generation.dart'; -import 'generation.dart'; -import 'import_generation.dart'; import 'method_generation.dart'; -class LibraryGeneration extends Generation { +class LibraryGeneration { final GenerationOptions options; final String? context; final String locale; final List messages; - final Map localeToResourceInfo; + final Map localeToResourceInfo; LibraryGeneration( this.options, @@ -28,9 +26,7 @@ class LibraryGeneration extends Generation { this.localeToResourceInfo, ); - @override - List generate() { - final imports = ImportGeneration(options).generate(); + Library generate() { final constructors = ConstructorGeneration(options).generate(); final fields = FieldGeneration( @@ -54,11 +50,6 @@ class LibraryGeneration extends Generation { methods, ).generate(); - return [ - Library((b) => b - ..comments.add(options.header) - ..directives.addAll(imports) - ..body.addAll(classes)) - ]; + return Library((b) => b..body.addAll(classes)); } } diff --git a/pkgs/messages_builder/lib/code_generation/method_generation.dart b/pkgs/messages_builder/lib/code_generation/method_generation.dart index c2438f71..be6f5892 100644 --- a/pkgs/messages_builder/lib/code_generation/method_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/method_generation.dart @@ -8,7 +8,7 @@ import '../generation_options.dart'; import '../message_with_metadata.dart'; import 'generation.dart'; -class MethodGeneration extends Generation { +class MethodGeneration { final GenerationOptions options; final String? context; final List messages; @@ -47,7 +47,6 @@ class MethodGeneration extends Generation { ); } - @override List generate() { Iterable messageCalls; if (options.messageCalls) { @@ -62,8 +61,8 @@ class MethodGeneration extends Generation { (mb) { final loading = switch (options.deserialization) { DeserializationType.web => ''' - final data = await _fileLoader(carb); - final messageList = MessageListJson.fromString(data, pluralSelector);''', + final data = await AssetBundle.loadString(carb); + final messageList = MessageListJson.fromString(data, _pluralSelector);''', }; mb ..name = 'loadLocale' @@ -166,60 +165,6 @@ class MethodGeneration extends Generation { const Code('_currentMessages.generateStringAtIndex(val.index, args)') ..lambda = true ..returns = const Reference('String')); - // Message Function(num, - // {Message? few, - // String? locale, - // Message? many, - // Map? numberCases, - // required Message other, - // Map? wordCases}) intl; - Method pluralSelector() => Method( - (mb) => mb - ..name = 'pluralSelector' - ..returns = const Reference('Message') - ..requiredParameters.addAll([ - Parameter( - (pb) => pb - ..name = 'howMany' - ..type = const Reference('num') - ..named = false, - ), - ]) - ..optionalParameters.addAll([ - Parameter( - (pb) => pb - ..name = 'other' - ..type = const Reference('Message') - ..required = true - ..named = true, - ), - Parameter( - (pb) => pb - ..name = 'few' - ..type = const Reference('Message?') - ..named = true, - ), - Parameter( - (pb) => pb - ..name = 'many' - ..type = const Reference('Message?') - ..named = true, - ), - Parameter( - (pb) => pb - ..name = 'numberCases' - ..type = const Reference('Map?') - ..named = true, - ), - Parameter( - (pb) => pb - ..name = 'wordCases' - ..type = const Reference('Map?') - ..named = true, - ), - ]) - ..body = pluralSelectorBody(), - ); return [ getCurrentLocale, @@ -229,37 +174,7 @@ class MethodGeneration extends Generation { getKnownLocales, loadLocale, loadAllLocales, - if (options.pluralSelector != PluralSelectorType.custom) pluralSelector(), ...messageCalls, ]; } - - Code pluralSelectorBody() { - return switch (options.pluralSelector) { - PluralSelectorType.intl => const Code(''' -return Intl.pluralLogic( - howMany, - few: few, - many: many, - zero: numberCases?[0] ?? wordCases?[0], - one: numberCases?[1] ?? wordCases?[1], - two: numberCases?[2] ?? wordCases?[2], - other: other, - locale: currentLocale, - ); - '''), - PluralSelectorType.intl4x => const Code(''' -Message getCase(int i) => numberCases?[i] ?? wordCases?[i] ?? other; - return switch (Intl(locale: Locale.parse(currentLocale)).plural().select(howMany)) { - PluralCategory.zero => getCase(0), - PluralCategory.one => getCase(1), - PluralCategory.two => getCase(2), - PluralCategory.few => few ?? other, - PluralCategory.many => many ?? other, - PluralCategory.other => other, - }; - '''), - PluralSelectorType.custom => throw ArgumentError(), - }; - } } diff --git a/pkgs/messages_builder/lib/generation_options.dart b/pkgs/messages_builder/lib/generation_options.dart index 6573b3fe..15943807 100644 --- a/pkgs/messages_builder/lib/generation_options.dart +++ b/pkgs/messages_builder/lib/generation_options.dart @@ -52,9 +52,7 @@ class GenerationOptions { required this.pluralSelector, }); - static Future fromPubspec(BuildStep buildStep) async { - final pubspecId = await buildStep.findAssets(Glob('pubspec.yaml')).first; - final pubspecData = await buildStep.readAsString(pubspecId); + static Future fromPubspec(String pubspecData) async { final pubspec = loadYaml(pubspecData) as YamlMap; final packageOptions = pubspec['package_options'] as YamlMap?; final messagesOptions = packageOptions?['messages_builder'] as YamlMap?; @@ -71,6 +69,12 @@ class GenerationOptions { return generationOptions; } + static Future getPubspecFrom(BuildStep buildStep) async { + final pubspecId = await buildStep.findAssets(Glob('pubspec.yaml')).first; + final pubspecData = await buildStep.readAsString(pubspecId); + return pubspecData; + } + static IndexType _indexType(YamlMap? messagesOptions) { final generateFindString = messagesOptions?['generateFindBy'] as String?; return generateFindString != null diff --git a/pkgs/messages_builder/lib/hook.dart b/pkgs/messages_builder/lib/hook.dart new file mode 100644 index 00000000..3633cfce --- /dev/null +++ b/pkgs/messages_builder/lib/hook.dart @@ -0,0 +1,120 @@ +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:logging/logging.dart'; +import 'package:messages_serializer/messages_serializer.dart'; +import 'package:native_assets_cli/native_assets_cli.dart'; +import 'package:path/path.dart' as p; + +import 'builder.dart'; +import 'generation_options.dart'; +import 'message_with_metadata.dart'; + +Future _generationOptions(BuildConfig config) async { + final packageRoot = config.packageRoot; + final pubspecUri = packageRoot.resolve('pubspec.yaml'); + final file = File.fromUri(pubspecUri); + return GenerationOptions.fromPubspec(await file.readAsString()); +} + +class MessagesDataBuilder { + final Future> Function(BuildConfig config) arbFiles; + + //TODO allow arbs from other locations than package root subfolders + MessagesDataBuilder.fromFiles(List relativePaths) + : arbFiles = ((config) async => relativePaths); + + MessagesDataBuilder.fromFolder(String relativePath) + : arbFiles = ((config) => + Directory(config.packageRoot.resolve(relativePath).path) + .list() + .where((file) => file is File) + .map((file) => file.path) + .where((path) => p.extension(path) == '.arb') + .map((path) => p.relative(path, from: config.packageRoot.path)) + .toList()); + + Future run({ + required BuildConfig config, + required BuildOutput output, + required Logger? logger, + }) async { + final files = await arbFiles(config); + for (final arbFilePath in files) { + if (p.isAbsolute(arbFilePath)) { + throw ArgumentError('Paths for .arb files must be relative to the' + ' package root ${config.packageRoot}, but $arbFilePath is' + ' absolute.'); + } + final arbFileUri = config.packageRoot.resolve(arbFilePath); + final arbFileContents = await File.fromUri(arbFileUri).readAsString(); + final generationOptions = await _generationOptions(config); + final messageBundle = await parseMessageFile( + arbFileContents, + generationOptions, + ); + + final serializer = _buildSerializer(generationOptions); + + final data = _arbToDataFile( + messageBundle, + arbFilePath, + serializer, + ); + + final assetName = _assetName( + p.relative(arbFileUri.path, from: config.packageRoot.path), + serializer.extension, + ); + final file = await _createAssetFile(assetName, config); + + await _writeDataToFile(data, file); + + output.addAsset(DataAsset( + package: config.packageName, + name: assetName, + file: file.uri, + )); + + output.addDependency(arbFileUri); + } + output.addDependency(config.packageRoot.resolve('hook/build.dart')); + } + + String _arbToDataFile(MessagesWithMetadata messageBundle, String arbFilePath, + Serializer serializer) => + serializer + .serialize( + messageBundle.hash, + messageBundle.locale ?? inferLocale(arbFilePath) ?? 'en_US', + messageBundle.messages.map((e) => e.message).toList(), + ) + .data; + + String _assetName(String relativePath, String extension) { + final dataFile = p.setExtension(relativePath, extension); + return dataFile; + } + + Serializer _buildSerializer(GenerationOptions generationOptions) => + JsonSerializer(generationOptions.findById); + + Future _createAssetFile(String dataFile, BuildConfig config) async { + final outputDirectory = + Directory.fromUri(config.outputDirectory.resolve(config.packageName)); + final file = File.fromUri(outputDirectory.uri.resolve(dataFile)); + await file.create(recursive: true); + return file; + } + + Future _writeDataToFile( + T data, + File file, + ) async { + if (data is Uint8List) { + await file.writeAsBytes(data); + } else if (data is String) { + await file.writeAsString(data); + } + } +} diff --git a/pkgs/messages_builder/lib/message_with_metadata.dart b/pkgs/messages_builder/lib/message_with_metadata.dart index 7547b75d..1518153d 100644 --- a/pkgs/messages_builder/lib/message_with_metadata.dart +++ b/pkgs/messages_builder/lib/message_with_metadata.dart @@ -19,12 +19,11 @@ class MessageWithMetadata { class MessagesWithMetadata { final List messages; - final String locale; + final String? locale; final String? context; final String? referencePath; final String hash; final bool hasMetadata; - final AssetId assetId; MessagesWithMetadata( this.messages, @@ -33,7 +32,6 @@ class MessagesWithMetadata { this.referencePath, this.hash, this.hasMetadata, - this.assetId, ); MessagesWithMetadata copyWith({ @@ -52,7 +50,6 @@ class MessagesWithMetadata { referencePath ?? this.referencePath, hash ?? this.hash, hasMetadata ?? this.hasMetadata, - assetId ?? this.assetId, ); } } diff --git a/pkgs/messages_builder/pubspec.yaml b/pkgs/messages_builder/pubspec.yaml index e200f41e..bece2329 100644 --- a/pkgs/messages_builder/pubspec.yaml +++ b/pkgs/messages_builder/pubspec.yaml @@ -14,8 +14,10 @@ dependencies: dart_style: ^2.2.4 glob: ^2.1.1 intl: ^0.18.0 + logging: ^1.2.0 messages: ^0.2.0 messages_serializer: ^0.2.0 + native_assets_cli: ^0.6.0 path: ^1.8.2 yaml: ^3.1.1 diff --git a/pkgs/messages_builder/test/web_deserializer_native_test.dart b/pkgs/messages_builder/test/web_deserializer_native_test.dart index e93fa824..6f5b9898 100644 --- a/pkgs/messages_builder/test/web_deserializer_native_test.dart +++ b/pkgs/messages_builder/test/web_deserializer_native_test.dart @@ -4,7 +4,6 @@ import 'dart:convert'; -import 'package:build/src/asset/id.dart'; import 'package:intl/intl.dart' as old_intl; import 'package:messages/messages_json.dart'; import 'package:messages_builder/arb_parser.dart'; @@ -15,13 +14,13 @@ import 'package:test/test.dart'; import 'testarb.arb.dart'; Message intlPluralSelector( - num howMany, { + num howMany, + String locale, { Map? numberCases, Map? wordCases, Message? few, Message? many, required Message other, - String? locale, }) { return old_intl.Intl.pluralLogic( howMany, @@ -36,7 +35,6 @@ Message intlPluralSelector( } void main() { - final uniqueKey = AssetId('package', 'path'); test('generateMessageFile from Object json', () { final message = StringMessage('Hello World'); final message1 = MessageWithMetadata(message, [], 'helloWorld'); @@ -54,7 +52,7 @@ void main() { '@@locale': 'en', 'helloWorld': 'Hello World' }; - final parsed = ArbParser().parseMessageFile(arb, uniqueKey); + final parsed = ArbParser().parseMessageFile(arb); final buffer = JsonSerializer() .serialize('', '', parsed.messages.map((e) => e.message).toList()) .data; @@ -67,7 +65,7 @@ void main() { '@@locale': 'en', 'helloWorld': 'Hello {name}' }; - final parsed = ArbParser().parseMessageFile(arb, uniqueKey); + final parsed = ArbParser().parseMessageFile(arb); final buffer = JsonSerializer() .serialize('', '', parsed.messages.map((e) => e.message).toList()) .data; @@ -84,7 +82,7 @@ void main() { '@@locale': 'en', 'helloWorld': '{greeting}{space}{name}' }; - final parsed = ArbParser().parseMessageFile(arb, uniqueKey); + final parsed = ArbParser().parseMessageFile(arb); final buffer = JsonSerializer() .serialize('', '', parsed.messages.map((e) => e.message).toList()) .data; @@ -103,7 +101,7 @@ void main() { test('generateMessageFile from complex arb JSON', () { final arb = jsonDecode(arbFile) as Map; - final parsed = ArbParser().parseMessageFile(arb, uniqueKey); + final parsed = ArbParser().parseMessageFile(arb); final buffer = JsonSerializer() .serialize('', '', parsed.messages.map((e) => e.message).toList()) .data; diff --git a/pkgs/messages_serializer/lib/src/serializer.dart b/pkgs/messages_serializer/lib/src/serializer.dart index ba45321f..7e4d42b2 100644 --- a/pkgs/messages_serializer/lib/src/serializer.dart +++ b/pkgs/messages_serializer/lib/src/serializer.dart @@ -15,6 +15,8 @@ abstract class Serializer { Serializer(this.writeIds); + String get extension; + Serialization serialize( String hash, String locale, diff --git a/pkgs/messages_serializer/lib/src/serializer_json.dart b/pkgs/messages_serializer/lib/src/serializer_json.dart index a1bb1a5a..ed8b1c32 100644 --- a/pkgs/messages_serializer/lib/src/serializer_json.dart +++ b/pkgs/messages_serializer/lib/src/serializer_json.dart @@ -179,4 +179,7 @@ class JsonSerializer extends Serializer { result.add(m); return result.length - 1; } + + @override + String get extension => '.json'; } diff --git a/pkgs/messages_serializer/test/messages_serializer_test.dart b/pkgs/messages_serializer/test/messages_serializer_test.dart index b9ebee90..c184e91b 100644 --- a/pkgs/messages_serializer/test/messages_serializer_test.dart +++ b/pkgs/messages_serializer/test/messages_serializer_test.dart @@ -10,13 +10,13 @@ import 'package:messages_serializer/messages_serializer.dart'; import 'package:test/test.dart'; Message intlPluralSelector( - num howMany, { + num howMany, + String locale, { Map? numberCases, Map? wordCases, Message? few, Message? many, required Message other, - String? locale, }) { return old_intl.Intl.pluralLogic( howMany, diff --git a/submodules/icu4x b/submodules/icu4x index 9b905e2f..fb38fc8d 160000 --- a/submodules/icu4x +++ b/submodules/icu4x @@ -1 +1 @@ -Subproject commit 9b905e2f1e85453e39c0eb23e68145f7d4aa8553 +Subproject commit fb38fc8d01a5c181de6eca523dedf28bc74fd1e9