diff --git a/CHANGELOG.md b/CHANGELOG.md index c8795e1..41edf2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 0.12.0 - 2021-05-24 +- [bs-react-intl-ppx](https://github.com/ahrefs/bs-react-intl-ppx) support added + ## 0.11.0 - 2021-05-17 - Repo renamed to `rescript-react-intl-extractor` and moved to the cca-io organization. diff --git a/README.md b/README.md index 51e3e5d..b90666b 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,13 @@ You also can pass descriptions to the records with: let foo = [@intl.description "Hello description"] {id: "message.hello", defaultMessage: "Hello"}; ``` +3. within [intl-ppx](https://github.com/ahrefs/bs-react-intl-ppx) + +```reason +let hello = [%intl "hello"] +let world = [%intl {msg: "world", desc: "Some description"}] +``` + ## Building and Testing The ReScript parser is included as a git submodule. Therefore, after checking out the sources, first run @@ -151,6 +158,7 @@ Run the tests: [rescript]: https://rescript-lang.org/ [reason]: https://reasonml.github.io [rescript-react-intl]: https://github.com/cca-io/rescript-react-intl +[bs-react-intl-ppx]: https://github.com/ahrefs/bs-react-intl-ppx [react-intl]: https://github.com/yahoo/react-intl [releases page]: https://github.com/cca-io/rescript-react-intl-extractor/releases [esy]: https://esy.sh diff --git a/bin/Version.re b/bin/Version.re index 0d27f2d..ba7c53c 100644 --- a/bin/Version.re +++ b/bin/Version.re @@ -1,3 +1,3 @@ // *** GENERATED BY "yarn setVersion" *** -let version = "0.11.0 (ReScript bd995ff)"; +let version = "0.12.0 (ReScript bd995ff)"; diff --git a/lib/ExtractionIterator.re b/lib/ExtractionIterator.re index 9e7b5aa..d46734b 100644 --- a/lib/ExtractionIterator.re +++ b/lib/ExtractionIterator.re @@ -38,6 +38,44 @@ let extractMessageFromRecord = (~description=?, callback, fields) => { Message.fromStringMap(~description?, map) |> Option.iter(callback); }; +let extractMessageFromExtension = (callback, item) => { + // TODO share this function with intl ppx + let makeId = (~description="", message) => message ++ "|" ++ description |> Digest.string |> Digest.to_hex; + + switch (item) { + | PStr([{pstr_desc: Pstr_eval({pexp_desc: Pexp_constant(Pconst_string(defaultMessage, _)), _}, _), _}]) => + let id = defaultMessage |> makeId; + callback(Message.{id, defaultMessage, description: None}); + | PStr([ + { + pstr_desc: + Pstr_eval( + { + pexp_desc: + Pexp_record( + [ + ({txt: Lident("msg"), _}, {pexp_desc: Pexp_constant(Pconst_string(defaultMessage, _)), _}), + ({txt: Lident("desc"), _}, {pexp_desc: Pexp_constant(Pconst_string(description, _)), _}), + ] | + [ + ({txt: Lident("desc"), _}, {pexp_desc: Pexp_constant(Pconst_string(description, _)), _}), + ({txt: Lident("msg"), _}, {pexp_desc: Pexp_constant(Pconst_string(defaultMessage, _)), _}), + ], + None, + ), + _, + }, + _, + ), + _, + }, + ]) => + let id = defaultMessage |> makeId(~description); + callback(Message.{id, defaultMessage, description: Some(description)}); + | _ => () + }; +}; + let hasIntlAttribute = (items: structure) => items |> List.exists(item => @@ -111,6 +149,18 @@ let getIterator = callback => { | {pexp_desc: Pexp_apply({pexp_desc: Pexp_ident({txt, _})}, labels)} when matchesFormattedMessage(txt) => extractMessageFromLabels(callback, labels) + // Match [%intl "message"] + // [%intl.s "message"] + // [%intl.el "message"] + // [%intl {msg: "message", desc: "description}] + // [%intl.s {msg: "message", desc: "description}] + // [%intl.el {msg: "message", desc: "description}] + // [%intl {desc: "description", msg: "message"}] + // [%intl.s {desc: "description", msg: "message"}] + // [%intl.el { desc: "description", msg: "message"}] + | {pexp_desc: Pexp_extension(({txt: "intl" | "intl.s" | "intl.el"}, item)), _} => + extractMessageFromExtension(callback, item) + | _ => () }; diff --git a/package.json b/package.json index 7de8f45..2f98463 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rescript-react-intl-extractor", - "version": "0.11.0", + "version": "0.12.0", "description": "Message extractor for rescript-react-intl", "author": "Christoph Knittel ", "license": "MIT", diff --git a/test/__snapshots__/IntlPpx.0d7c125f.0.snapshot b/test/__snapshots__/IntlPpx.0d7c125f.0.snapshot new file mode 100644 index 0000000..98f32cb --- /dev/null +++ b/test/__snapshots__/IntlPpx.0d7c125f.0.snapshot @@ -0,0 +1,87 @@ +IntlPpx › full +[ + { + \"id\": \"07ef8ec9f2dd894c45b447292d527f4a\", + \"defaultMessage\": \"This is message 5.2.2\" + }, + { + \"id\": \"09644115fd7f4e0803e5300442acaa3f\", + \"defaultMessage\": \"This is message 5.2.9\", + \"description\": \"This is description for message 5.2.9\" + }, + { + \"id\": \"50c182276f426aaed9bb73e932749c12\", + \"defaultMessage\": \"This is message 5.1.1\" + }, + { + \"id\": \"517ecc8330114017ce1fa3358b0e19fb\", + \"defaultMessage\": \"This is message 5.2.7\", + \"description\": \"This is description for message 5.2.7\" + }, + { + \"id\": \"617b406e8ce2d6117eb79e480b7db916\", + \"defaultMessage\": \"This is message 5.1.6\", + \"description\": \"This is description for message 5.1.6\" + }, + { + \"id\": \"705ebca03144cedde0772b42454db9bc\", + \"defaultMessage\": \"This is message 5.1.2\" + }, + { + \"id\": \"82d39a35baed93572eb9d3e2f31d9549\", + \"defaultMessage\": \"This is message 5.1.7\", + \"description\": \"This is description for message 5.1.7\" + }, + { + \"id\": \"9bd72b86b4707b49e954679611f24389\", + \"defaultMessage\": \"This is message 5.1.9\", + \"description\": \"This is description for message 5.1.9\" + }, + { + \"id\": \"aa90db9568631794111be2c0dbf3f290\", + \"defaultMessage\": \"This is message 5.2.4\", + \"description\": \"This is description for message 5.2.4\" + }, + { + \"id\": \"b5efe6bdb050410f0182c3e2b74b7add\", + \"defaultMessage\": \"This is message 5.2.5\", + \"description\": \"This is description for message 5.2.5\" + }, + { + \"id\": \"bbd2f42ed446c470db8326dd1ea169fe\", + \"defaultMessage\": \"This is message 5.2.1\" + }, + { + \"id\": \"c26daf229e5a13904d33004e1e48fa87\", + \"defaultMessage\": \"This is message 5.2.3\" + }, + { + \"id\": \"d48a62aec72f3b16408aacff820de2de\", + \"defaultMessage\": \"This is message 5.1.3\" + }, + { + \"id\": \"da572261a2f0bc6550f8701e35aa0d13\", + \"defaultMessage\": \"This is message 5.2.6\", + \"description\": \"This is description for message 5.2.6\" + }, + { + \"id\": \"dec09d01d1cf004612cef6f2dc4c81e3\", + \"defaultMessage\": \"This is message 5.1.4\", + \"description\": \"This is description for message 5.1.4\" + }, + { + \"id\": \"deeb9aaca5b6be205f113483625b19e2\", + \"defaultMessage\": \"This is message 5.1.8\", + \"description\": \"This is description for message 5.1.8\" + }, + { + \"id\": \"e4a34c50454eec2a66088d7a5e7f00d5\", + \"defaultMessage\": \"This is message 5.2.8\", + \"description\": \"This is description for message 5.2.8\" + }, + { + \"id\": \"fc63eab6a84654a8a5d05d83f165db1e\", + \"defaultMessage\": \"This is message 5.1.5\", + \"description\": \"This is description for message 5.1.5\" + } +] diff --git a/test/lib/Tests.re b/test/lib/Tests.re index 5f88158..185d29b 100644 --- a/test/lib/Tests.re +++ b/test/lib/Tests.re @@ -60,3 +60,10 @@ describe("ReScript", ({test}) => { expect.string(json).toMatchSnapshot(); }) }); + +describe("IntlPpx", ({test}) => { + test("full", ({expect}) => { + let json = extractAndGetJson(["testData/test5"]); + expect.string(json).toMatchSnapshot(); + }) +}); diff --git a/testData/test5/Test_5_1.re b/testData/test5/Test_5_1.re new file mode 100644 index 0000000..0a9ef9f --- /dev/null +++ b/testData/test5/Test_5_1.re @@ -0,0 +1,9 @@ +let msg51 = [%intl "This is message 5.1.1"] +let msg52 = [%intl.s "This is message 5.1.2"] +let msg53 = [%intl.el "This is message 5.1.3"] +let msg54 = [%intl {msg: "This is message 5.1.4", desc: "This is description for message 5.1.4"}] +let msg55 = [%intl.s {msg: "This is message 5.1.5", desc: "This is description for message 5.1.5"}] +let msg56 = [%intl.el {msg: "This is message 5.1.6", desc: "This is description for message 5.1.6"}] +let msg57 = [%intl {desc: "This is description for message 5.1.7", msg: "This is message 5.1.7"}] +let msg58 = [%intl.s {desc: "This is description for message 5.1.8", msg: "This is message 5.1.8"}] +let msg59 = [%intl.el {desc: "This is description for message 5.1.9", msg: "This is message 5.1.9"}] diff --git a/testData/test5/Test_5_2.res b/testData/test5/Test_5_2.res new file mode 100644 index 0000000..0ae9f4b --- /dev/null +++ b/testData/test5/Test_5_2.res @@ -0,0 +1,9 @@ +let msg51 = %intl("This is message 5.2.1") +let msg52 = %intl.s("This is message 5.2.2") +let msg53 = %intl.el("This is message 5.2.3") +let msg54 = %intl({msg: "This is message 5.2.4", desc: "This is description for message 5.2.4"}) +let msg55 = %intl.s({msg: "This is message 5.2.5", desc: "This is description for message 5.2.5"}) +let msg56 = %intl.el({msg: "This is message 5.2.6", desc: "This is description for message 5.2.6"}) +let msg57 = %intl({desc: "This is description for message 5.2.7", msg: "This is message 5.2.7"}) +let msg58 = %intl.s({desc: "This is description for message 5.2.8", msg: "This is message 5.2.8"}) +let msg59 = %intl.el({desc: "This is description for message 5.2.9", msg: "This is message 5.2.9"})