diff --git a/pkgs/messages/example/assets/testarb.arb.json b/pkgs/messages/example/assets/testarb.arb.json index 9a44323d..216f7666 100644 --- a/pkgs/messages/example/assets/testarb.arb.json +++ b/pkgs/messages/example/assets/testarb.arb.json @@ -1 +1 @@ -[0,"en","dr9Md951",1,null,["helloAndWelcome","Welcome von !",[8,0],[13,1]],["helloAndWelcome2","Welcome von !",[8,0],[13,1]],[6,"newMessages","test ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],[6,"newMessages2","test ",[4,0,"Two new Messages",{"male":"No new messages","female":"One new message"}]]] \ No newline at end of file +[0,"en","dr9Md951",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/assets/testarb_de.arb.json b/pkgs/messages/example/assets/testarb_de.arb.json index 70e189e6..e9f03283 100644 --- a/pkgs/messages/example/assets/testarb_de.arb.json +++ b/pkgs/messages/example/assets/testarb_de.arb.json @@ -1 +1 @@ -[0,"de","hbDN1MhX",1,null,["helloAndWelcome","Willkommen von ",[11,0],[16,1]],["helloAndWelcome2","Willkommen von 2",[11,0],[16,1]],[6,"newMessages","testde ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],["newMessages2","testdse is just a simple message"]] \ No newline at end of file +[0,"de","hbDN1MhX",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/assets/testarbctx2.arb.json b/pkgs/messages/example/assets/testarbctx2.arb.json index 5bd68e20..e9d8a8fc 100644 --- a/pkgs/messages/example/assets/testarbctx2.arb.json +++ b/pkgs/messages/example/assets/testarbctx2.arb.json @@ -1 +1 @@ -[0,"en","QrwRSsOy",1,null,["aboutMessage","About ",[6,0]],["helloAndWelcome","Welcome von <",[8,0],[13,1]],[6,"newMessages","test ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],[6,"newMessages2","test ",[4,0,"Two new Messages",{"male":"No new messages","female":"One new message"}]],["otherMsg","other"]] \ No newline at end of file +[0,"en","QrwRSsOy",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/assets/testarbctx2_fr.arb.json b/pkgs/messages/example/assets/testarbctx2_fr.arb.json index d3895436..49b0070e 100644 --- a/pkgs/messages/example/assets/testarbctx2_fr.arb.json +++ b/pkgs/messages/example/assets/testarbctx2_fr.arb.json @@ -1 +1 @@ -[0,"fr","390XWry3",1,null,["aboutMessage","Sur ",[4,0]],["helloAndWelcome","Welcome von <",[8,0],[13,1]],[6,"newMessages","test ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],[6,"newMessages2","test ",[4,0,"Two new Messages",{"male":"No new messages","female":"One new message"}]],["otherMsg","other"]] \ No newline at end of file +[0,"fr","390XWry3",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/bin/example.dart b/pkgs/messages/example/bin/example.dart index 0a1b0940..cde89b51 100644 --- a/pkgs/messages/example/bin/example.dart +++ b/pkgs/messages/example/bin/example.dart @@ -7,30 +7,26 @@ import 'dart:io'; import 'package:example/AboutPage_messages.g.dart'; +import 'package:example/HomePage_messages.g.dart'; Future main(List arguments) async { - final messages = AboutPageMessages( - (id) => File(id.split('/').skip(2).join('/')).readAsString(), - ); - // final index = AboutPageMessagesEnum.aboutMessage; + final messages = AboutPageMessages(_assetLoader); await messages.loadLocale('en'); print('AboutMessage en:'); print('\t${messages.aboutMessage('typesafe.en')}'); - ///To enable this, add `generateFindById: true` to the pubspec section - // print('\t${messages.getById('aboutMessage', ['get-by-id.en'])}'); - - ///To enable this, add `generateFindBy: enumerate` to the pubspec section - // print('\t${messages.getByEnum(index, ['get-by-index.en'])}'); - await messages.loadLocale('fr'); print('AboutMessage fr:'); print('\t${messages.aboutMessage('typesafe.fr')}'); - ///To enable this, add `generateFindById: true` to the pubspec section - // print('\t${messages.getById('aboutMessage', ['get-by-id.fr'])}'); + final messages2 = HomePageMessages(_assetLoader); + + await messages2.loadLocale('en'); - ///To enable this, add `generateFindBy: enumerate` to the pubspec section - // print('\t${messages.getByEnum(index, ['get-by-index.fr'])}'); + print('AboutMessage en:'); + print('\t${messages2.helloAndWelcome('Paul', 'Erdős')}'); } + +Future _assetLoader(String id) => + File(id.split('/').skip(2).join('/')).readAsString(); diff --git a/pkgs/messages/example/lib/AboutPage_en_empty.g.dart b/pkgs/messages/example/lib/AboutPage_en_empty.g.dart deleted file mode 100644 index 56705fe5..00000000 --- a/pkgs/messages/example/lib/AboutPage_en_empty.g.dart +++ /dev/null @@ -1,2 +0,0 @@ -// This is a helper file for deferred loading of the messages for locale en, -// generated by `dart run messages`. diff --git a/pkgs/messages/example/lib/AboutPage_fr_empty.g.dart b/pkgs/messages/example/lib/AboutPage_fr_empty.g.dart deleted file mode 100644 index 7b2fd73c..00000000 --- a/pkgs/messages/example/lib/AboutPage_fr_empty.g.dart +++ /dev/null @@ -1,2 +0,0 @@ -// This is a helper file for deferred loading of the messages for locale fr, -// generated by `dart run messages`. diff --git a/pkgs/messages/example/lib/AboutPage_messages.g.dart b/pkgs/messages/example/lib/AboutPage_messages.g.dart index d90d9be5..44109357 100644 --- a/pkgs/messages/example/lib/AboutPage_messages.g.dart +++ b/pkgs/messages/example/lib/AboutPage_messages.g.dart @@ -6,9 +6,6 @@ import 'package:intl/intl.dart'; import 'package:messages/messages_json.dart'; -import 'AboutPage_en_empty.g.dart' deferred as AboutPage_en_empty; -import 'AboutPage_fr_empty.g.dart' deferred as AboutPage_fr_empty; - class AboutPageMessages { AboutPageMessages(this._assetLoader); @@ -27,13 +24,6 @@ class AboutPageMessages { MessageList get _currentMessages => _messages[currentLocale]!; - String getById( - String id, [ - List args = const [], - ]) { - return _currentMessages.generateStringAtId(id, args); - } - static Iterable get knownLocales => _dataFiles.keys; Future loadLocale(String locale) async { @@ -43,12 +33,6 @@ class AboutPageMessages { if (dataFile == null) { throw ArgumentError('Locale $locale is not in $knownLocales'); } - if (locale == 'en') { - await AboutPage_en_empty.loadLibrary(); - } else if (locale == 'fr') { - await AboutPage_fr_empty.loadLibrary(); - } - final data = await _assetLoader(dataFile); final messageList = MessageListJson.fromString(data, _pluralSelector); if (messageList.preamble.hash != info?.$2) { diff --git a/pkgs/messages/example/lib/HomePage_de_empty.g.dart b/pkgs/messages/example/lib/HomePage_de_empty.g.dart deleted file mode 100644 index 0f40a982..00000000 --- a/pkgs/messages/example/lib/HomePage_de_empty.g.dart +++ /dev/null @@ -1,2 +0,0 @@ -// This is a helper file for deferred loading of the messages for locale de, -// generated by `dart run messages`. diff --git a/pkgs/messages/example/lib/HomePage_en_empty.g.dart b/pkgs/messages/example/lib/HomePage_en_empty.g.dart deleted file mode 100644 index 56705fe5..00000000 --- a/pkgs/messages/example/lib/HomePage_en_empty.g.dart +++ /dev/null @@ -1,2 +0,0 @@ -// This is a helper file for deferred loading of the messages for locale en, -// generated by `dart run messages`. diff --git a/pkgs/messages/example/lib/HomePage_messages.g.dart b/pkgs/messages/example/lib/HomePage_messages.g.dart index 261e05dd..742d6bf4 100644 --- a/pkgs/messages/example/lib/HomePage_messages.g.dart +++ b/pkgs/messages/example/lib/HomePage_messages.g.dart @@ -6,9 +6,6 @@ import 'package:intl/intl.dart'; import 'package:messages/messages_json.dart'; -import 'HomePage_de_empty.g.dart' deferred as HomePage_de_empty; -import 'HomePage_en_empty.g.dart' deferred as HomePage_en_empty; - class HomePageMessages { HomePageMessages(this._assetLoader); @@ -27,13 +24,6 @@ class HomePageMessages { MessageList get _currentMessages => _messages[currentLocale]!; - String getById( - String id, [ - List args = const [], - ]) { - return _currentMessages.generateStringAtId(id, args); - } - static Iterable get knownLocales => _dataFiles.keys; Future loadLocale(String locale) async { @@ -43,12 +33,6 @@ class HomePageMessages { if (dataFile == null) { throw ArgumentError('Locale $locale is not in $knownLocales'); } - if (locale == 'de') { - await HomePage_de_empty.loadLibrary(); - } else if (locale == 'en') { - await HomePage_en_empty.loadLibrary(); - } - final data = await _assetLoader(dataFile); final messageList = MessageListJson.fromString(data, _pluralSelector); if (messageList.preamble.hash != info?.$2) { diff --git a/pkgs/messages/lib/src/deserializer/deserializer_json.dart b/pkgs/messages/lib/src/deserializer/deserializer_json.dart index 98a56edf..0f059a3e 100644 --- a/pkgs/messages/lib/src/deserializer/deserializer_json.dart +++ b/pkgs/messages/lib/src/deserializer/deserializer_json.dart @@ -42,23 +42,15 @@ class JsonDeserializer extends Deserializer { Message getMessage(dynamic message, [bool isTopLevel = false]) { if (message is List) { - final typeOrId = message[0]; - int start; - String? id; - if (isTopLevel && preamble.hasIds) { - start = 2; - id = message[1] as String; - } else { - start = 1; - } - if (typeOrId == PluralMessage.type) { - return _forPlural(message, start, id); - } else if (typeOrId == SelectMessage.type) { - return _forSelect(message, start, id); - } else if (typeOrId == CombinedMessage.type) { - return _forCombined(message, start, id); - } else if (typeOrId is String) { - return _forString(message, start - 1, typeOrId); + final type = message[0]; + if (type == PluralMessage.type) { + return _forPlural(message); + } else if (type == SelectMessage.type) { + return _forSelect(message); + } else if (type == CombinedMessage.type) { + return _forCombined(message); + } else if (type is String) { + return _forString(message); } } else if (message is String) { return StringMessage(message); @@ -66,26 +58,26 @@ class JsonDeserializer extends Deserializer { throw ArgumentError(); } - StringMessage _forString(List message, int start, String? id) { - final value = message[start] as String; + StringMessage _forString(List message) { + final value = message[0] as String; final argPositions = <({int stringIndex, int argIndex})>[]; - for (var i = start + 1; i < message.length; i++) { + for (var i = 1; i < message.length; i++) { final pair = message[i] as List; final stringIndex = pair[0]; final argIndex = pair[1]; argPositions.add((stringIndex: stringIndex, argIndex: argIndex)); } - return StringMessage(value, argPositions: argPositions, id: id); + return StringMessage(value, argPositions: argPositions); } - PluralMessage _forPlural(List message, int start, String? id) { - final argIndex = message[start] as int; - final otherMessage = getMessage(message[start + 1]); + PluralMessage _forPlural(List message) { + final argIndex = message[1] as int; + final otherMessage = getMessage(message[2]); Message? fewMessage; Message? manyMessage; final numberCases = {}; final wordCases = {}; - final submessages = message[start + 2] as List; + final submessages = message[3] as List; for (var i = 0; i < submessages.length - 1; i += 2) { final msg = getMessage(submessages[i + 1]); final messageMarker = submessages[i]; @@ -108,25 +100,20 @@ class JsonDeserializer extends Deserializer { many: manyMessage, argIndex: argIndex, other: otherMessage, - id: id, ); } - SelectMessage _forSelect(List message, int start, String? id) { - final argIndex = message[start] as int; - final otherCase = getMessage(message[start + 1]); - final submessages = message[start + 2] as Map; + SelectMessage _forSelect(List message) { + final argIndex = message[1] as int; + final otherCase = getMessage(message[2]); + final submessages = message[3] as Map; final cases = submessages.map((caseName, caseMessage) => MapEntry( caseName as String, getMessage(caseMessage), )); - return SelectMessage(otherCase, cases, argIndex, id); + return SelectMessage(otherCase, cases, argIndex); } - CombinedMessage _forCombined(List message, int start, String? id) { - return CombinedMessage( - id, - message.skip(start).map(getMessage).toList(), - ); - } + CombinedMessage _forCombined(List message) => + CombinedMessage(message.skip(1).map(getMessage).toList()); } diff --git a/pkgs/messages/lib/src/message.dart b/pkgs/messages/lib/src/message.dart index 7890bea2..b37c375a 100644 --- a/pkgs/messages/lib/src/message.dart +++ b/pkgs/messages/lib/src/message.dart @@ -5,9 +5,7 @@ import 'plural_selector.dart'; sealed class Message { - final String? id; - - Message(this.id); + Message(); String generateString( List allArgs, { @@ -20,7 +18,7 @@ sealed class Message { final class CombinedMessage extends Message { final List messages; - CombinedMessage(super.id, this.messages); + CombinedMessage(this.messages); @override String generateString( @@ -49,8 +47,7 @@ final class StringMessage extends Message { /// This list is expected to be sorted by `argPositions.stringIndex` final List<({int stringIndex, int argIndex})> argPositions; - StringMessage(this.value, {this.argPositions = const [], String? id}) - : super(id); + StringMessage(this.value, {this.argPositions = const [], String? id}); static const int type = 1; @@ -97,7 +94,7 @@ final class PluralMessage extends Message { required this.other, required this.argIndex, String? id, - }) : super(id); + }); static const int type = 3; @@ -125,12 +122,12 @@ final class SelectMessage extends Message { final Message other; final Map cases; final int argIndex; + SelectMessage( this.other, this.cases, - this.argIndex, [ - super.id, - ]); + this.argIndex, + ); static const int type = 4; diff --git a/pkgs/messages/lib/src/message_format.dart b/pkgs/messages/lib/src/message_format.dart index 909d7a42..2f763ec4 100644 --- a/pkgs/messages/lib/src/message_format.dart +++ b/pkgs/messages/lib/src/message_format.dart @@ -23,9 +23,7 @@ abstract class Preamble { String get hash; - bool get hasIds; - - static int length = 4; + static int length = 3; } abstract class MessageList { @@ -33,8 +31,6 @@ abstract class MessageList { PluralSelector get pluralSelector; String generateStringAtIndex(int index, List args); - - String generateStringAtId(String id, List args); } sealed class PluralMarker { diff --git a/pkgs/messages/lib/src/message_list_json.dart b/pkgs/messages/lib/src/message_list_json.dart index 998ad831..a1e49ac2 100644 --- a/pkgs/messages/lib/src/message_list_json.dart +++ b/pkgs/messages/lib/src/message_list_json.dart @@ -13,12 +13,10 @@ class JsonPreamble extends Preamble { required int serializationVersion, required String locale, required String hash, - required bool hasIds, }) : _data = [ serializationVersion, locale, hash, - hasIds ? 1 : 0, ]; JsonPreamble.parse(this._data); @@ -33,9 +31,6 @@ class JsonPreamble extends Preamble { @override String get hash => _data[2] as String; - - @override - bool get hasIds => _data[3] == 1; } class MessageListJson extends MessageList { @@ -60,12 +55,6 @@ class MessageListJson extends MessageList { factory MessageListJson.fromString(String string, PluralSelector intl) => JsonDeserializer(string).deserialize(intl); - @override - String generateStringAtId(String id, List args) => messages - .where((element) => element.id == id) - .first - .generateString(args, locale: preamble.locale, pluralSelector: _selector); - @override String generateStringAtIndex(int index, List args) => messages[getIndex(index)].generateString(args, diff --git a/pkgs/messages/test/messagelist_json_test.dart b/pkgs/messages/test/messagelist_json_test.dart index d5d8023e..2f1fd831 100644 --- a/pkgs/messages/test/messagelist_json_test.dart +++ b/pkgs/messages/test/messagelist_json_test.dart @@ -34,7 +34,6 @@ void main() { serializationVersion: serializationVersion, locale: 'en_US', hash: 'hash', - hasIds: false, ), [ StringMessage('Hello World'), @@ -64,7 +63,6 @@ void main() { null, ); - expect(messageList.preamble.hasIds, false); expect(messageList.preamble.locale, 'en_US'); expect(messageList.generateStringAtIndex(0, []), 'Hello World'); expect(messageList.generateStringAtIndex(1, ['case1']), 'Case case1'); diff --git a/pkgs/messages_builder/lib/arb_parser.dart b/pkgs/messages_builder/lib/arb_parser.dart index a721b9f5..4ed5e9cf 100644 --- a/pkgs/messages_builder/lib/arb_parser.dart +++ b/pkgs/messages_builder/lib/arb_parser.dart @@ -12,20 +12,21 @@ import 'parameterized_message.dart'; import 'placeholder.dart'; class ArbParser { - final bool addName; - ArbParser([this.addName = false]); + ArbParser(); MessageFile parseMessageFile(Map arb) { final locale = arb['@@locale'] as String?; final context = arb['@@context'] as String?; final messages = arb.keys .where((key) => !key.startsWith('@')) - .map((key) => parseMessage( - arb[key] as String, - arb['@$key'] as Map?, - key, - '${context}_$locale', - )) + .map( + (key) => parseMessage( + arb[key] as String, + arb['@$key'] as Map?, + key, + '${context}_$locale', + ), + ) .toList(); messages.sort((a, b) => a.name.compareTo(b.name)); return MessageFile( @@ -48,24 +49,32 @@ class ArbParser { String name, String debugString, ) { - final message = MessageParser.parse( + final (message, arguments) = MessageParser.parse( debugString, messageContent, name, - addId: addName, ); + final meaning = metadata?['meaning'] as String?; + final description = metadata?['description'] as String?; + final placeholdersMap = metadata?['placeholders'] as Map?; - final placeholdersWithMetadata = placeholdersMap?.map( - (name, metadata) { - final type = (metadata as Map)['type'] as String?; - return MapEntry(name, Placeholder(name, type ?? 'String')); - }, - ) ?? + final placeholdersWithMetadata = placeholdersMap?.map((name, metadata) { + final type = (metadata as Map)['type'] as String?; + final example = metadata['example'] as String?; + return MapEntry(name, Placeholder(name, type ?? 'String', example)); + }) ?? {}; - final placeholders = message.placeholders - .map((p) => placeholdersWithMetadata[p.name] ?? p) - .toList(); - return ParameterizedMessage(message.message, message.name, placeholders); + return ParameterizedMessage( + message: message, + name: name, + meaning: meaning, + description: description, + placeholders: arguments + .map( + (name) => placeholdersWithMetadata[name] ?? Placeholder(name), + ) + .toList(), + ); } } diff --git a/pkgs/messages_builder/lib/builder.dart b/pkgs/messages_builder/lib/builder.dart index d9be524f..a4e7771b 100644 --- a/pkgs/messages_builder/lib/builder.dart +++ b/pkgs/messages_builder/lib/builder.dart @@ -15,6 +15,7 @@ import 'code_generation/code_generation.dart'; import 'generation_options.dart'; import 'located_message_file.dart'; import 'message_file.dart'; +import 'parameterized_message.dart'; class MessageCallingCodeGenerator { final GenerationOptions options; @@ -27,54 +28,93 @@ class MessageCallingCodeGenerator { Future build() async { final messageFiles = await _parseMessageFiles(); + final codeOutDirectory = options.generatedCodeFiles.path; + final deserialization = options.deserialization; + final packageName = options.packageName; + final pluralSelector = options.pluralSelector; + final header = options.header; + + final contextToCode = generateCode( + messageFiles: messageFiles, + deserialization: deserialization, + packageName: packageName, + pluralSelector: pluralSelector, + header: header, + ); + + final parentPath = Directory(codeOutDirectory); + for (final MapEntry(key: context, value: code) in contextToCode.entries) { + final mainFile = + File(path.join(parentPath.path, '${context}_messages.g.dart')); + await mainFile.create(recursive: true); + await mainFile.writeAsString(code); + } + } + /// Writes one code file per context. + static Map generateCode({ + required String packageName, + required List messageFiles, + DeserializationType deserialization = DeserializationType.web, + PluralSelectorType pluralSelector = PluralSelectorType.intl, + String header = '', + }) { final families = messageFiles .groupListsBy((messageFile) => getParentFile(messageFiles, messageFile)) .map((key, value) => MapEntry(key, value.sortedBy((messageFile) => messageFile.locale))); - var counter = 0; - + final contextToCode = {}; for (final MapEntry(key: parent, value: children) in families.entries) { final context = parent.file.context; printIncludeFilesNotification(context, children.map((f) => f.path)); - final dummyFilePaths = Map.fromEntries(children - .map((e) => e.locale) - .map((e) => MapEntry(e, [context, e, 'empty'].join('_')))); - - final library = ClassesGeneration( - options: options, + contextToCode[context!] = generateCodeForContext( context: context, - parent: parent, - children: children, - emptyFiles: dummyFilePaths, - ).generate(); - - final code = CodeGenerator( - options: options, - classes: library, - emptyFilePaths: dummyFilePaths.values, - ).generate(); - - final parentPath = Directory(options.generatedCodeFiles.path); - - final mainFile = File(path.join( - parentPath.path, '${context ?? 'm${counter++}'}_messages.g.dart')); - await mainFile.create(recursive: true); - await mainFile.writeAsString(code); - - for (final MapEntry(key: locale, value: emptyFilePath) - in dummyFilePaths.entries) { - final file = File(path.join(parentPath.path, '$emptyFilePath.g.dart')); - await file.create(); - await file.writeAsString(''' -// This is a helper file for deferred loading of the messages for locale $locale, -// generated by `dart run messages`. -'''); - } + initialLocale: parent.locale, + messages: parent.file.messages, + dataFiles: children.map((e) => ( + locale: e.locale, + path: e.namespacedPath(packageName), + hash: e.hash + )), + deserialization: deserialization, + pluralSelector: pluralSelector, + header: header, + ); } + return contextToCode; + } + + /// Generates the calling code for a single [context] and list of [messages]. + /// + /// Also references the [dataFiles], with their locale, path used as a key for + /// retrieval, and the hash to compare against the one stored in them. + static String generateCodeForContext({ + required String? context, + required String initialLocale, + required List messages, + required Iterable<({String locale, String path, String hash})> dataFiles, + DeserializationType deserialization = DeserializationType.web, + PluralSelectorType pluralSelector = PluralSelectorType.intl, + String header = '', + }) { + final library = ClassesGeneration( + context: context, + initialLocale: initialLocale, + messages: messages, + children: dataFiles, + deserialization: deserialization, + pluralSelectorType: pluralSelector, + ).generate(); + + return CodeGenerator( + classes: library, + header: header, + deserialization: deserialization, + pluralSelectorType: pluralSelector, + ).generate(); } Future> _parseMessageFiles() async => @@ -108,7 +148,7 @@ The files $filesInContext have no metadata, so it is not clear which one is the /// Display a notification to the user to include the newly generated files /// in their assets. - void printIncludeFilesNotification( + static void printIncludeFilesNotification( String? context, Iterable fileList, ) { @@ -126,5 +166,5 @@ Future parseMessageFile( ) async { final decoded = jsonDecode(arbFile) as Map; final arb = Map.castFrom(decoded); - return ArbParser(options.findById).parseMessageFile(arb); + return ArbParser().parseMessageFile(arb); } diff --git a/pkgs/messages_builder/lib/code_generation/class_generation.dart b/pkgs/messages_builder/lib/code_generation/class_generation.dart index 24f85b42..94dca17a 100644 --- a/pkgs/messages_builder/lib/code_generation/class_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/class_generation.dart @@ -4,12 +4,9 @@ import 'package:code_builder/code_builder.dart'; -import '../generation_options.dart'; import '../parameterized_message.dart'; -import 'generation.dart'; class ClassGeneration { - final GenerationOptions options; final List messages; final String? context; @@ -18,7 +15,6 @@ class ClassGeneration { final List methods; ClassGeneration( - this.options, this.messages, this.context, this.constructors, @@ -29,29 +25,15 @@ class ClassGeneration { String getClassName(String? context) => _toCamelCase('${context ?? ''}Messages'); - List generate() { - final classes = [ - Class( - (cb) => cb - ..name = getClassName(context) - ..constructors.addAll(constructors) - ..fields.addAll(fields) - ..methods.addAll(methods), - ), - ]; - if (options.indexType == IndexType.enumerate) { - classes.add(Enum((cb) => cb - ..name = enumName(context) - ..values.addAll(List.generate( - messages.length, - (index) => messages[index].nameIsDartConform - ? EnumValue( - (evb) => evb..name = messages[index].name, - ) - : null).whereType()))); - } - return classes; - } + List generate() => [ + Class( + (cb) => cb + ..name = getClassName(context) + ..constructors.addAll(constructors) + ..fields.addAll(fields) + ..methods.addAll(methods), + ), + ]; } String _toCamelCase(String input) => input diff --git a/pkgs/messages_builder/lib/code_generation/classes_generation.dart b/pkgs/messages_builder/lib/code_generation/classes_generation.dart index e1195d28..11b92fcb 100644 --- a/pkgs/messages_builder/lib/code_generation/classes_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/classes_generation.dart @@ -5,46 +5,47 @@ import 'package:code_builder/code_builder.dart'; import '../generation_options.dart'; -import '../located_message_file.dart'; +import '../parameterized_message.dart'; import 'class_generation.dart'; import 'constructor_generation.dart'; import 'field_generation.dart'; import 'method_generation.dart'; class ClassesGeneration { - final GenerationOptions options; final String? context; - final LocatedMessageFile parent; - final Iterable children; - final Map emptyFiles; + final String initialLocale; + final List messages; + final Iterable<({String locale, String path, String hash})> children; + + final DeserializationType deserialization; + final PluralSelectorType pluralSelectorType; ClassesGeneration({ - required this.options, required this.context, - required this.parent, + required this.initialLocale, + required this.messages, required this.children, - required this.emptyFiles, + required this.deserialization, + required this.pluralSelectorType, }); List generate() { - final constructors = ConstructorGeneration(options).generate(); + final constructors = ConstructorGeneration(pluralSelectorType).generate(); final fields = FieldGeneration( - options, children, - parent.locale, + initialLocale, + pluralSelectorType, ).generate(); final methods = MethodGeneration( - options, + deserialization, context, - parent.file.messages, - emptyFiles, + messages, ).generate(); final classes = ClassGeneration( - options, - parent.file.messages, + messages, context, constructors, fields, diff --git a/pkgs/messages_builder/lib/code_generation/code_generation.dart b/pkgs/messages_builder/lib/code_generation/code_generation.dart index 768eaaa8..b29becf1 100644 --- a/pkgs/messages_builder/lib/code_generation/code_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/code_generation.dart @@ -9,18 +9,24 @@ import '../generation_options.dart'; import 'import_generation.dart'; class CodeGenerator { - final GenerationOptions options; final List classes; - final Iterable emptyFilePaths; + + final PluralSelectorType pluralSelectorType; + final DeserializationType deserialization; + final String header; CodeGenerator({ - required this.options, required this.classes, - required this.emptyFilePaths, + required this.pluralSelectorType, + required this.deserialization, + required this.header, }); String generate() { - final imports = ImportGeneration(options, emptyFilePaths).generate(); + final imports = ImportGeneration( + pluralSelectorType, + deserialization, + ).generate(); final lib = Library( (p0) => p0 ..ignoreForFile.addAll([ @@ -28,12 +34,11 @@ class CodeGenerator { 'unused_import', 'library_prefixes', ]) - ..comments.add(options.header) + ..comments.add(header) ..directives.addAll(imports) ..body.addAll([ ...classes, - if (options.pluralSelector != PluralSelectorType.custom) - pluralSelector(), + if (pluralSelectorType != PluralSelectorType.custom) pluralSelector(), ]), ); final emitter = DartEmitter(orderDirectives: true); @@ -105,7 +110,7 @@ class CodeGenerator { ); Code pluralSelectorBody() { - return switch (options.pluralSelector) { + return switch (pluralSelectorType) { PluralSelectorType.intl => const Code(''' return Intl.pluralLogic( howMany, diff --git a/pkgs/messages_builder/lib/code_generation/constructor_generation.dart b/pkgs/messages_builder/lib/code_generation/constructor_generation.dart index 1358b64b..11efd44c 100644 --- a/pkgs/messages_builder/lib/code_generation/constructor_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/constructor_generation.dart @@ -7,9 +7,9 @@ import 'package:code_builder/code_builder.dart'; import '../generation_options.dart'; class ConstructorGeneration { - final GenerationOptions options; + final PluralSelectorType pluralSelectorType; - ConstructorGeneration(this.options); + ConstructorGeneration(this.pluralSelectorType); List generate() { final nativeConstructor = Constructor((cb) => cb @@ -19,7 +19,7 @@ class ConstructorGeneration { ..name = '_assetLoader' ..toThis = true, ), - if (options.pluralSelector == PluralSelectorType.custom) + if (pluralSelectorType == PluralSelectorType.custom) Parameter((pb) => pb ..name = 'pluralSelector' ..toThis = true), diff --git a/pkgs/messages_builder/lib/code_generation/field_generation.dart b/pkgs/messages_builder/lib/code_generation/field_generation.dart index 8be0410e..dd2577b3 100644 --- a/pkgs/messages_builder/lib/code_generation/field_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/field_generation.dart @@ -5,17 +5,17 @@ import 'package:code_builder/code_builder.dart'; import '../generation_options.dart'; -import '../located_message_file.dart'; class FieldGeneration { - final GenerationOptions options; - final Iterable messageFiles; + final Iterable<({String locale, String path, String hash})> messageFiles; final String initialLocale; + final PluralSelectorType pluralSelectorType; + FieldGeneration( - this.options, this.messageFiles, this.initialLocale, + this.pluralSelectorType, ); List generate() { @@ -43,10 +43,8 @@ class FieldGeneration { ); final dataFiles = Field( (fb) { - final paths = messageFiles - .map((e) => """ -'${e.locale}' : ('${e.namespacedPath(options.packageName)}', '${e.hash}')""") - .join(','); + final paths = messageFiles.map((e) => """ +'${e.locale}' : ('${e.path}', '${e.hash}')""").join(','); fb ..name = '_dataFiles' ..modifier = FieldModifier.constant @@ -65,7 +63,7 @@ class FieldGeneration { currentLocale, messages, dataFiles, - if (options.pluralSelector == PluralSelectorType.custom) pluralSelector, + if (pluralSelectorType == PluralSelectorType.custom) pluralSelector, ]; return fields; } diff --git a/pkgs/messages_builder/lib/code_generation/import_generation.dart b/pkgs/messages_builder/lib/code_generation/import_generation.dart index 56f2bf9a..8a8fdf9a 100644 --- a/pkgs/messages_builder/lib/code_generation/import_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/import_generation.dart @@ -7,18 +7,21 @@ import 'package:code_builder/code_builder.dart'; import '../generation_options.dart'; class ImportGeneration { - final GenerationOptions options; - final Iterable emptyFiles; + final PluralSelectorType pluralSelectorType; + final DeserializationType deserialization; - ImportGeneration(this.options, this.emptyFiles); + ImportGeneration( + this.pluralSelectorType, + this.deserialization, + ); List generate() { - final serializationImports = switch (options.deserialization) { + final serializationImports = switch (deserialization) { DeserializationType.web => [ Directive.import('package:messages/messages_json.dart') ], }; - final pluralImports = switch (options.pluralSelector) { + final pluralImports = switch (pluralSelectorType) { PluralSelectorType.intl => [Directive.import('package:intl/intl.dart')], PluralSelectorType.intl4x => [ Directive.import('package:intl4x/intl4x.dart') @@ -26,14 +29,9 @@ class ImportGeneration { PluralSelectorType.custom => [], }; - final deferredImports = emptyFiles.map((emptyFilePath) { - return Directive.importDeferredAs('$emptyFilePath.g.dart', emptyFilePath); - }); - return [ ...serializationImports, ...pluralImports, - ...deferredImports, ]; } } diff --git a/pkgs/messages_builder/lib/code_generation/method_generation.dart b/pkgs/messages_builder/lib/code_generation/method_generation.dart index d4ac85f6..a9203dee 100644 --- a/pkgs/messages_builder/lib/code_generation/method_generation.dart +++ b/pkgs/messages_builder/lib/code_generation/method_generation.dart @@ -6,15 +6,17 @@ import 'package:code_builder/code_builder.dart'; import '../generation_options.dart'; import '../parameterized_message.dart'; -import 'generation.dart'; class MethodGeneration { - final GenerationOptions options; + final DeserializationType deserialization; final String? context; final List messages; - final Map emptyFiles; - MethodGeneration(this.options, this.context, this.messages, this.emptyFiles); + MethodGeneration( + this.deserialization, + this.context, + this.messages, + ); Method? generateMessageCall(int index, ParameterizedMessage message) { if (!message.nameIsDartConform) { @@ -23,11 +25,7 @@ class MethodGeneration { final arguments = message.placeholders.map((placeholder) => placeholder.name).join(', '); - final indexStr = options.indexType == IndexType.enumerate - ? '${enumName(context)}.${message.name}.index' - : index.toString(); - final body = - '_currentMessages.generateStringAtIndex($indexStr, [$arguments])'; + final body = '_currentMessages.generateStringAtIndex($index, [$arguments])'; final methodType = message.placeholders.isEmpty ? MethodType.getter : null; return Method( (mb) => mb @@ -50,30 +48,17 @@ class MethodGeneration { List generate() { Iterable messageCalls; - if (options.messageCalls) { - messageCalls = List.generate( - messages.length, - (i) => generateMessageCall(i, messages[i]), - ).whereType(); - } else { - messageCalls = []; - } + messageCalls = List.generate( + messages.length, + (i) => generateMessageCall(i, messages[i]), + ).whereType(); final loadLocale = Method( (mb) { - final loading = switch (options.deserialization) { + final loading = switch (deserialization) { DeserializationType.web => ''' final data = await _assetLoader(dataFile); final messageList = MessageListJson.fromString(data, _pluralSelector);''', }; - final loadLibraries = emptyFiles.entries - .map( - (e) => ''' -if (locale == '${e.key}') { - await ${e.value}.loadLibrary(); -} -''', - ) - .join(' else '); mb ..name = 'loadLocale' ..requiredParameters.add(Parameter( @@ -89,7 +74,6 @@ if (locale == '${e.key}') { if (dataFile == null) { throw ArgumentError('Locale \$locale is not in \$knownLocales'); } - $loadLibraries $loading if (messageList.preamble.hash != info?.\$2) { throw ArgumentError(\'\'\' @@ -140,49 +124,9 @@ if (locale == '${e.key}') { ..body = const Code('_currentLocale') ..returns = const Reference('String'), ); - final getMessagebyId = Method((mb) => mb - ..name = 'getById' - ..requiredParameters.addAll([ - Parameter( - (pb) => pb - ..name = 'id' - ..type = const Reference('String'), - ) - ]) - ..optionalParameters.add(Parameter( - (pb) => pb - ..name = 'args' - ..type = const Reference('List') - ..defaultTo = const Code('const []'), - )) - ..body = - const Code('return _currentMessages.generateStringAtId(id, args);') - ..returns = const Reference('String')); - final findByEnum = Method((mb) => mb - ..name = 'getByEnum' - ..annotations - .add(const CodeExpression(Code("pragma('dart2js:noInline')"))) - ..requiredParameters.add(Parameter( - (pb) => pb - ..name = 'val' - ..type = Reference(enumName(context)), - )) - ..optionalParameters.add(Parameter( - (pb) => pb - ..name = 'args' - ..type = const Reference('List') - ..defaultTo = const Code('const []'), - )) - ..body = - const Code('_currentMessages.generateStringAtIndex(val.index, args)') - ..lambda = true - ..returns = const Reference('String')); - return [ getCurrentLocale, getCurrentMessages, - if (options.findById) getMessagebyId, - if (options.indexType == IndexType.enumerate) findByEnum, getKnownLocales, loadLocale, loadAllLocales, diff --git a/pkgs/messages_builder/lib/generation_options.dart b/pkgs/messages_builder/lib/generation_options.dart index 989ab478..b2e4f699 100644 --- a/pkgs/messages_builder/lib/generation_options.dart +++ b/pkgs/messages_builder/lib/generation_options.dart @@ -9,27 +9,6 @@ import 'package:yaml/yaml.dart'; /// Options for the message data file and code generation. class GenerationOptions { - /// Whether to generate named message calls. Example: - /// An arb file like this - /// ```json - /// { - /// "helloName": "Hello {name}" - /// } - /// ``` - /// leads to - /// ```dart - /// String helloName(String name) { - /// ``` - /// being generated. - final bool messageCalls; - - /// Whether to generate a method to fetch a message by its id. Leads to the - /// ids being stored in the data file. - final bool findById; - - /// How the messages should be indexed, either through `int`s or an `enum` - final IndexType indexType; - /// The data file serialization, either json or (TBD) binary. final SerializationType serialization; @@ -76,9 +55,6 @@ class GenerationOptions { GenerationOptions({ required this.serialization, required this.deserialization, - required this.messageCalls, - required this.findById, - required this.indexType, required this.header, required this.pluralSelector, required this.packageName, @@ -100,9 +76,6 @@ class GenerationOptions { final generationOptions = GenerationOptions( serialization: SerializationType.json, deserialization: DeserializationType.web, - messageCalls: (messagesOptions?[_generateMethodsKey] as bool?) ?? true, - findById: (messagesOptions?[_generateFindByIdKey] as bool?) ?? false, - indexType: _indexType(messagesOptions), header: messagesOptions?[_headerKey] as String? ?? 'Generated by package:messages_builder.', pluralSelector: _pluralSelector(messagesOptions), @@ -116,15 +89,6 @@ class GenerationOptions { return generationOptions; } - static IndexType _indexType(YamlMap? messagesOptions) { - final generateFindString = messagesOptions?[_generateFindByKey] as String?; - return generateFindString != null - ? IndexType.values - .where((type) => type.name == generateFindString) - .first - : IndexType.integer; - } - static PluralSelectorType _pluralSelector(YamlMap? messagesOptions) { final pluralSelectorString = messagesOptions?[_pluralSelectorKey] as String?; @@ -144,18 +108,6 @@ enum DeserializationType { web; } -/// How the indexing of the messages should be implemented. -enum IndexType { - /// No indexing. - none, - - /// Indexing via a collection of `static int`s. - integer, - - /// Indexing via an enum. - enumerate; -} - /// The origin of the algorithm for determining which plural case to use. enum PluralSelectorType { /// From `package:intl`. diff --git a/pkgs/messages_builder/lib/message_data_builder.dart b/pkgs/messages_builder/lib/message_data_builder.dart index aa392b3d..3d486b6a 100644 --- a/pkgs/messages_builder/lib/message_data_builder.dart +++ b/pkgs/messages_builder/lib/message_data_builder.dart @@ -43,7 +43,7 @@ class MessageDataFileBuilder { final arbFileContents = await File.fromUri(arbFileUri).readAsString(); final messageBundle = await parseMessageFile(arbFileContents, options); - final serializer = JsonSerializer(options.findById); + final serializer = JsonSerializer(); final data = _arbToData(messageBundle, arbFilePath, serializer); diff --git a/pkgs/messages_builder/lib/message_parser/message_parser.dart b/pkgs/messages_builder/lib/message_parser/message_parser.dart index 492ee025..ca40d454 100644 --- a/pkgs/messages_builder/lib/message_parser/message_parser.dart +++ b/pkgs/messages_builder/lib/message_parser/message_parser.dart @@ -4,43 +4,31 @@ import 'package:messages/messages.dart'; -import '../parameterized_message.dart'; -import '../placeholder.dart'; import 'icu_message_parser.dart'; import 'plural_parser.dart'; import 'select_parser.dart'; class MessageParser { - static ParameterizedMessage parse( + static (Message, List) parse( String debugString, String fileContents, - String name, { - bool addId = false, - }) { + String name, + ) { final node = Parser(name, debugString, fileContents).parse(); final arguments = []; - final message = - parseNode(node, arguments, name, addId) ?? StringMessage(''); - final placeholders = arguments.map(Placeholder.new).toList(); - return ParameterizedMessage(message, name, placeholders); + final message = parseNode(node, arguments, name) ?? StringMessage(''); + return (message, arguments); } - static Message? parseNode( - Node node, - List arguments, [ - String? name, - bool addId = false, - ]) { - final id = addId ? name : null; + static Message? parseNode(Node node, List arguments, [String? name]) { final submessages = []; - final placeholders = <({int argIndex, int afterStringMessage})>[]; for (var child in node.children) { switch (child.type) { case ST.string: - submessages.add(StringMessage(child.value!, id: id)); + submessages.add(StringMessage(child.value!)); break; case ST.pluralExpr: - submessages.add(PluralParser().parse(child, arguments, addId, name)); + submessages.add(PluralParser().parse(child, arguments)); break; case ST.placeholderExpr: final identifier = child.children @@ -49,51 +37,56 @@ class MessageParser { if (!arguments.contains(identifier)) { arguments.add(identifier); } - placeholders.add(( - argIndex: arguments.indexOf(identifier), - afterStringMessage: submessages.length, - )); + submessages.add( + StringMessage( + '', + argPositions: [ + (argIndex: arguments.indexOf(identifier), stringIndex: 0), + ], + ), + ); break; case ST.selectExpr: - submessages.add(SelectParser().parse(child, arguments, addId, name)); + submessages.add(SelectParser().parse(child, arguments)); break; default: break; } } - if (submessages.isEmpty && placeholders.isEmpty) { + if (submessages.isEmpty) { return null; - } else if (submessages.length == 1 && placeholders.isEmpty) { - return submessages.first; - } else if (submessages.every((message) => message is StringMessage)) { - return combineStringsAndPlaceholders( - submessages.whereType().toList(), - id, - placeholders, - ); - } else { - return CombinedMessage(id, submessages); } - } - - static StringMessage combineStringsAndPlaceholders( - List submessages, - String? id, - List<({int afterStringMessage, int argIndex})> placeholders, - ) { - final argPositions = <({int argIndex, int stringIndex})>[]; - final s = StringBuffer(); - for (var i = 0; i < submessages.length + 1; i++) { - placeholders - .where((element) => element.afterStringMessage == i) - .forEach((element) { - argPositions.add((argIndex: element.argIndex, stringIndex: s.length)); - }); - if (i < submessages.length) { - final submessage = submessages[i]; - s.write(submessage.value); + final fold = submessages.fold([], (messages, message) { + if (messages.isNotEmpty && + message is StringMessage && + messages.last is StringMessage) { + final last = messages.removeLast() as StringMessage; + return [...messages, combineStringMessages(last, message)]; + } else { + return [...messages, message]; } + }); + if (fold.length == 1) { + return fold.first; + } else { + return CombinedMessage(fold); } - return StringMessage(s.toString(), argPositions: argPositions, id: id); } + + static StringMessage combineStringMessages( + StringMessage message1, + StringMessage message2, + ) => + StringMessage( + message1.value + message2.value, + argPositions: [ + ...message1.argPositions, + ...message2.argPositions.map( + (e) => ( + argIndex: e.argIndex, + stringIndex: e.stringIndex + message1.value.length, + ), + ), + ], + ); } diff --git a/pkgs/messages_builder/lib/message_parser/select_parser.dart b/pkgs/messages_builder/lib/message_parser/select_parser.dart index b9fb8d8e..be6bba76 100644 --- a/pkgs/messages_builder/lib/message_parser/select_parser.dart +++ b/pkgs/messages_builder/lib/message_parser/select_parser.dart @@ -32,7 +32,6 @@ class SelectParser { cases.firstWhere((element) => element.key == 'other').value, caseMap, arguments.indexOf(identifier), - id, ); } } diff --git a/pkgs/messages_builder/lib/parameterized_message.dart b/pkgs/messages_builder/lib/parameterized_message.dart index 659aff2e..f4b63751 100644 --- a/pkgs/messages_builder/lib/parameterized_message.dart +++ b/pkgs/messages_builder/lib/parameterized_message.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:messages/messages.dart'; + import 'placeholder.dart'; /// A wrapper class around a [Message], adding its [placeholders] and a [name]. @@ -26,11 +27,19 @@ import 'placeholder.dart'; class ParameterizedMessage { final Message message; final String name; + final String? meaning; + final String? description; final List placeholders; static final RegExp _dartName = RegExp(r'^[a-zA-Z][a-zA-Z_0-9]*$'); - ParameterizedMessage(this.message, this.name, this.placeholders); + ParameterizedMessage({ + required this.message, + required this.name, + this.meaning, + this.description, + this.placeholders = const [], + }); bool get nameIsDartConform => _dartName.hasMatch(name); } diff --git a/pkgs/messages_builder/lib/placeholder.dart b/pkgs/messages_builder/lib/placeholder.dart index 0d5d1bbf..0ab93267 100644 --- a/pkgs/messages_builder/lib/placeholder.dart +++ b/pkgs/messages_builder/lib/placeholder.dart @@ -29,8 +29,9 @@ class Placeholder { final String name; final String? type; + final String? example; - Placeholder(this.name, [this.type]); + Placeholder(this.name, [this.type, this.example]); @override String toString() { diff --git a/pkgs/messages_builder/test/web_deserializer_native_test.dart b/pkgs/messages_builder/test/web_deserializer_native_test.dart index 461f36e3..8f51fc0c 100644 --- a/pkgs/messages_builder/test/web_deserializer_native_test.dart +++ b/pkgs/messages_builder/test/web_deserializer_native_test.dart @@ -37,7 +37,7 @@ Message intlPluralSelector( void main() { test('generateMessageFile from Object json', () { final message = StringMessage('Hello World'); - final message1 = ParameterizedMessage(message, 'helloWorld', []); + final message1 = ParameterizedMessage(message: message, name: 'helloWorld'); final messageList = [message1]; final buffer = JsonSerializer() .serialize('', '', messageList.map((e) => e.message).toList()) diff --git a/pkgs/messages_serializer/lib/src/serializer.dart b/pkgs/messages_serializer/lib/src/serializer.dart index 7e4d42b2..99dd0d58 100644 --- a/pkgs/messages_serializer/lib/src/serializer.dart +++ b/pkgs/messages_serializer/lib/src/serializer.dart @@ -11,9 +11,7 @@ class Serialization { } abstract class Serializer { - final bool writeIds; - - Serializer(this.writeIds); + Serializer(); String get extension; diff --git a/pkgs/messages_serializer/lib/src/serializer_json.dart b/pkgs/messages_serializer/lib/src/serializer_json.dart index ed8b1c32..1f6b35cf 100644 --- a/pkgs/messages_serializer/lib/src/serializer_json.dart +++ b/pkgs/messages_serializer/lib/src/serializer_json.dart @@ -11,7 +11,7 @@ import 'serializer.dart'; class JsonSerializer extends Serializer { final List result = []; - JsonSerializer([super.writeIds = false]); + JsonSerializer(); @override Serialization serialize( @@ -26,7 +26,6 @@ class JsonSerializer extends Serializer { serializationVersion: serializationVersion, locale: locale, hash: hash, - hasIds: writeIds, ); result.addAll(preamble.toJson()); @@ -80,11 +79,10 @@ class JsonSerializer extends Serializer { /// * List\ | a pair of position in the string - number of the placeholder Object encodeString(StringMessage message, bool isVisible) { final containsArgs = message.argPositions.isNotEmpty; - if ((message.id == null || isVisible == false) && !containsArgs) { + if (isVisible == false && !containsArgs) { return message.value; } final m = []; - addId(message, m, isVisible); m.add(message.value); if (containsArgs) { final positions = message.argPositions @@ -106,7 +104,6 @@ class JsonSerializer extends Serializer { List encodeSelect(SelectMessage message, bool isVisible) { final m = []; m.add(SelectMessage.type); - addId(message, m, isVisible); m.add(message.argIndex); m.add(encodeMessage(message.other)); final caseIndices = {}; @@ -129,7 +126,6 @@ class JsonSerializer extends Serializer { List encodePlural(PluralMessage message, bool isVisible) { final m = []; m.add(PluralMessage.type); - addId(message, m, isVisible); m.add(message.argIndex); m.add(encodeMessage(message.other)); final caseIndices = []; @@ -163,18 +159,12 @@ class JsonSerializer extends Serializer { List encodeCombined(CombinedMessage message, bool isVisible) { final m = []; m.add(CombinedMessage.type); - addId(message, m, isVisible); for (var submessage in message.messages) { m.add(encodeMessage(submessage)); } return m; } - /// Add a non-null ID iff `writeIds` is enabled - void addId(Message message, List m, bool isVisible) { - if (writeIds && message.id != null && isVisible) m.add(message.id!); - } - int addMessage(dynamic m) { result.add(m); return result.length - 1; diff --git a/pkgs/messages_serializer/test/messages_serializer_test.dart b/pkgs/messages_serializer/test/messages_serializer_test.dart index c184e91b..05c34943 100644 --- a/pkgs/messages_serializer/test/messages_serializer_test.dart +++ b/pkgs/messages_serializer/test/messages_serializer_test.dart @@ -32,7 +32,7 @@ Message intlPluralSelector( StringMessage stringMessage = StringMessage('Hello World', id: 'hello_world'); -CombinedMessage combinedMessage = CombinedMessage('combined', [ +CombinedMessage combinedMessage = CombinedMessage([ StringMessage('First '), StringMessage('Second'), ]); @@ -54,7 +54,6 @@ SelectMessage selectMessage = SelectMessage( 'case2': StringMessage('Case2'), }, 0, - 'selectMes', ); void main() { @@ -65,14 +64,10 @@ void main() { pluralMessage, selectMessage, ]; - final serialized = - JsonSerializer(true).serialize('hash', 'locale', messages); + final serialized = JsonSerializer().serialize('hash', 'locale', messages); final deserialize = JsonDeserializer(serialized.data).deserialize(intlPluralSelector); - expect( - deserialize.messages.map((e) => e.id), - orderedEquals(messages.map((e) => e.id)), - ); + compareMessages(deserialize.messages, messages); }); test('Serialize partially', () { @@ -83,13 +78,10 @@ void main() { selectMessage, ]; final serialized = - JsonSerializer(true).serialize('hash', 'locale', messages, [1, 3]); + JsonSerializer().serialize('hash', 'locale', messages, [1, 3]); final deserialize = JsonDeserializer(serialized.data).deserialize(intlPluralSelector); - expect( - deserialize.messages.map((e) => e.id), - orderedEquals([messages[1], messages[3]].map((e) => e.id)), - ); + compareMessages(deserialize.messages, [messages[1], messages[3]]); }); test('First serialize, then deserialize again', () { @@ -102,14 +94,10 @@ void main() { selectMessage, ] ]; - final params = [ - for (var writeId in [true, false]) - for (var messages in messageTypes) (writeId, messages) - ]; - for (final (writeId, messages) in params) { + for (final messages in messageTypes) { serializeThenDeserialize( messages, - JsonSerializer(writeId), + JsonSerializer(), JsonDeserializer.new, ); } diff --git a/pkgs/messages_shrinker/lib/messages_shrinker.dart b/pkgs/messages_shrinker/lib/messages_shrinker.dart index dea8b38e..91b08212 100644 --- a/pkgs/messages_shrinker/lib/messages_shrinker.dart +++ b/pkgs/messages_shrinker/lib/messages_shrinker.dart @@ -38,7 +38,7 @@ class MessageShrinker { 'just immediately reserialized, this selector will not be called.'); }, ); - final data = JsonSerializer(json.preamble.hasIds) + final data = JsonSerializer() .serialize( json.preamble.hash, json.preamble.locale, diff --git a/pkgs/messages_shrinker/test/testarb.json b/pkgs/messages_shrinker/test/testarb.json index 6676cce8..94491bb2 100644 --- a/pkgs/messages_shrinker/test/testarb.json +++ b/pkgs/messages_shrinker/test/testarb.json @@ -1 +1 @@ -[0,"","",0,null,["Welcome von <",[8,0],[13,1]],[6,"test ",[3,0,["test new messages",[5,0]],[2,"No new messages",4,"One new message",5,"Two new Messages"]]],[6,"test ",[4,0,["test new messages of type ",[5,0],[27,1]],{"male":"No new messages","female":"One new message"}]]] \ No newline at end of file +[0,"","",null,["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,["test new messages of type ",[5,0],[27,1]],{"male":"No new messages","female":"One new message"}]]] \ No newline at end of file