33
44#include " unicode/utypes.h"
55
6+ #if !UCONFIG_NO_NORMALIZATION
7+
68#if !UCONFIG_NO_FORMATTING
79
810#if !UCONFIG_NO_MF2
1113#include " unicode/messageformat2_data_model.h"
1214#include " unicode/messageformat2_formattable.h"
1315#include " unicode/messageformat2.h"
16+ #include " unicode/normalizer2.h"
1417#include " unicode/unistr.h"
1518#include " messageformat2_allocation.h"
19+ #include " messageformat2_checker.h"
1620#include " messageformat2_evaluation.h"
1721#include " messageformat2_macros.h"
1822
@@ -37,7 +41,7 @@ static Formattable evalLiteral(const Literal& lit) {
3741 // The fallback for a variable name is itself.
3842 UnicodeString str (DOLLAR);
3943 str += var;
40- const Formattable* val = context.getGlobal (var, errorCode);
44+ const Formattable* val = context.getGlobal (* this , var, errorCode);
4145 if (U_SUCCESS (errorCode)) {
4246 return (FormattedPlaceholder (*val, str));
4347 }
@@ -52,9 +56,9 @@ static Formattable evalLiteral(const Literal& lit) {
5256}
5357
5458[[nodiscard]] FormattedPlaceholder MessageFormatter::formatOperand (const Environment& env,
55- const Operand& rand,
56- MessageContext& context,
57- UErrorCode &status) const {
59+ const Operand& rand,
60+ MessageContext& context,
61+ UErrorCode &status) const {
5862 if (U_FAILURE (status)) {
5963 return {};
6064 }
@@ -71,15 +75,19 @@ static Formattable evalLiteral(const Literal& lit) {
7175 // Eager vs. lazy evaluation is an open issue:
7276 // see https://github.com/unicode-org/message-format-wg/issues/299
7377
78+ // NFC-normalize the variable name. See
79+ // https://github.com/unicode-org/message-format-wg/blob/main/spec/syntax.md#names-and-identifiers
80+ const VariableName normalized = normalizeNFC (var);
81+
7482 // Look up the variable in the environment
75- if (env.has (var )) {
83+ if (env.has (normalized )) {
7684 // `var` is a local -- look it up
77- const Closure& rhs = env.lookup (var );
85+ const Closure& rhs = env.lookup (normalized );
7886 // Format the expression using the environment from the closure
7987 return formatExpression (rhs.getEnv (), rhs.getExpr (), context, status);
8088 }
8189 // Variable wasn't found in locals -- check if it's global
82- FormattedPlaceholder result = evalArgument (var , context, status);
90+ FormattedPlaceholder result = evalArgument (normalized , context, status);
8391 if (status == U_ILLEGAL_ARGUMENT_ERROR) {
8492 status = U_ZERO_ERROR;
8593 // Unbound variable -- set a resolution error
@@ -761,6 +769,7 @@ void MessageFormatter::formatSelectors(MessageContext& context, const Environmen
761769UnicodeString MessageFormatter::formatToString (const MessageArguments& arguments, UErrorCode &status) {
762770 EMPTY_ON_ERROR (status);
763771
772+
764773 // Create a new environment that will store closures for all local variables
765774 Environment* env = Environment::create (status);
766775 // Create a new context with the given arguments and the `errors` structure
@@ -813,12 +822,14 @@ void MessageFormatter::check(MessageContext& context, const Environment& localEn
813822
814823 // Check that variable is in scope
815824 const VariableName& var = rand.asVariable ();
825+ UnicodeString normalized = normalizeNFC (var);
826+
816827 // Check local scope
817- if (localEnv.has (var )) {
828+ if (localEnv.has (normalized )) {
818829 return ;
819830 }
820831 // Check global scope
821- context.getGlobal (var , status);
832+ context.getGlobal (* this , normalized , status);
822833 if (status == U_ILLEGAL_ARGUMENT_ERROR) {
823834 status = U_ZERO_ERROR;
824835 context.getErrors ().setUnresolvedVariable (var, status);
@@ -855,7 +866,10 @@ void MessageFormatter::checkDeclarations(MessageContext& context, Environment*&
855866 // memoizing the value of localEnv up to this point
856867
857868 // Add the LHS to the environment for checking the next declaration
858- env = Environment::create (decl.getVariable (), Closure (rhs, *env), env, status);
869+ env = Environment::create (normalizeNFC (decl.getVariable ()),
870+ Closure (rhs, *env),
871+ env,
872+ status);
859873 CHECK_ERROR (status);
860874 }
861875}
@@ -866,3 +880,5 @@ U_NAMESPACE_END
866880#endif /* #if !UCONFIG_NO_MF2 */
867881
868882#endif /* #if !UCONFIG_NO_FORMATTING */
883+
884+ #endif /* #if !UCONFIG_NO_NORMALIZATION */
0 commit comments