From 2e2805df9aebc2b5e7e860e25f5de1bd44859258 Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Wed, 16 May 2018 22:46:40 +0000 Subject: [PATCH] ICU-13697 Renaming numparse_unisets.h to static_unicode_sets.h and refactoring to guarantee safety in no-data builds. X-SVN-Rev: 41389 --- icu4c/source/common/Makefile.in | 2 +- icu4c/source/common/common.vcxproj | 4 +- icu4c/source/common/common.vcxproj.filters | 4 +- icu4c/source/common/common_uwp.vcxproj | 4 +- ...se_unisets.cpp => static_unicode_sets.cpp} | 59 ++++++++++++------ ...mparse_unisets.h => static_unicode_sets.h} | 51 ++++++++++++---- icu4c/source/common/ucurr.cpp | 3 +- icu4c/source/i18n/numparse_decimal.cpp | 6 +- icu4c/source/i18n/numparse_impl.cpp | 2 +- icu4c/source/i18n/numparse_scientific.cpp | 2 +- icu4c/source/i18n/numparse_symbols.h | 2 +- icu4c/source/i18n/numparse_validators.cpp | 2 +- icu4c/source/i18n/numparse_validators.h | 2 +- .../source/i18n/scientificnumberformatter.cpp | 2 +- icu4c/source/test/intltest/Makefile.in | 5 +- icu4c/source/test/intltest/intltest.cpp | 16 +++-- icu4c/source/test/intltest/intltest.h | 6 +- icu4c/source/test/intltest/intltest.vcxproj | 4 +- .../test/intltest/intltest.vcxproj.filters | 6 +- icu4c/source/test/intltest/itutil.cpp | 11 +++- icu4c/source/test/intltest/numbertest.h | 18 +----- .../source/test/intltest/numbertest_parse.cpp | 4 +- ...st_unisets.cpp => static_unisets_test.cpp} | 44 +++++++++++--- ...taticCache.java => StaticUnicodeSets.java} | 60 +++++++++++++++---- .../icu/impl/number/parse/DecimalMatcher.java | 11 ++-- .../impl/number/parse/IgnorablesMatcher.java | 5 +- .../impl/number/parse/InfinityMatcher.java | 3 +- .../impl/number/parse/MinusSignMatcher.java | 3 +- .../icu/impl/number/parse/PercentMatcher.java | 3 +- .../impl/number/parse/PermilleMatcher.java | 3 +- .../impl/number/parse/PlusSignMatcher.java | 3 +- .../impl/number/parse/ScientificMatcher.java | 5 +- .../icu/impl/number/parse/SymbolMatcher.java | 5 +- .../icu/text/ScientificNumberFormatter.java | 6 +- .../core/src/com/ibm/icu/util/Currency.java | 6 +- .../dev/test/number/ExhaustiveNumberTest.java | 4 +- .../number/UnicodeSetStaticCacheTest.java | 24 -------- .../dev/test/util/StaticUnicodeSetsTest.java | 33 ++++++++++ 38 files changed, 282 insertions(+), 151 deletions(-) rename icu4c/source/common/{numparse_unisets.cpp => static_unicode_sets.cpp} (81%) rename icu4c/source/common/{numparse_unisets.h => static_unicode_sets.h} (56%) rename icu4c/source/test/intltest/{numbertest_unisets.cpp => static_unisets_test.cpp} (68%) rename icu4j/main/classes/core/src/com/ibm/icu/impl/{number/parse/UnicodeSetStaticCache.java => StaticUnicodeSets.java} (79%) delete mode 100644 icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/UnicodeSetStaticCacheTest.java create mode 100644 icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/StaticUnicodeSetsTest.java diff --git a/icu4c/source/common/Makefile.in b/icu4c/source/common/Makefile.in index 2025b85ee11..391ef28a282 100644 --- a/icu4c/source/common/Makefile.in +++ b/icu4c/source/common/Makefile.in @@ -112,7 +112,7 @@ ulist.o uloc_tag.o icudataver.o icuplug.o listformatter.o ulistformatter.o \ sharedobject.o simpleformatter.o unifiedcache.o uloc_keytype.o \ ubiditransform.o \ pluralmap.o \ -numparse_unisets.o +static_unicode_sets.o ## Header files to install HEADERS = $(srcdir)/unicode/*.h diff --git a/icu4c/source/common/common.vcxproj b/icu4c/source/common/common.vcxproj index f08bb065c59..d1e13a79d53 100644 --- a/icu4c/source/common/common.vcxproj +++ b/icu4c/source/common/common.vcxproj @@ -334,7 +334,7 @@ - + @@ -440,7 +440,7 @@ - + diff --git a/icu4c/source/common/common.vcxproj.filters b/icu4c/source/common/common.vcxproj.filters index 3731c33d1f5..20863f138ce 100644 --- a/icu4c/source/common/common.vcxproj.filters +++ b/icu4c/source/common/common.vcxproj.filters @@ -607,7 +607,7 @@ bidi - + formatting @@ -939,7 +939,7 @@ bidi - + formatting diff --git a/icu4c/source/common/common_uwp.vcxproj b/icu4c/source/common/common_uwp.vcxproj index edddabe11c5..f9d2d9e4af9 100644 --- a/icu4c/source/common/common_uwp.vcxproj +++ b/icu4c/source/common/common_uwp.vcxproj @@ -459,7 +459,7 @@ - + @@ -566,7 +566,7 @@ - + diff --git a/icu4c/source/common/numparse_unisets.cpp b/icu4c/source/common/static_unicode_sets.cpp similarity index 81% rename from icu4c/source/common/numparse_unisets.cpp rename to icu4c/source/common/static_unicode_sets.cpp index 5f052354d09..9e731f5781e 100644 --- a/icu4c/source/common/numparse_unisets.cpp +++ b/icu4c/source/common/static_unicode_sets.cpp @@ -9,7 +9,7 @@ // Helpful in toString methods and elsewhere. #define UNISTR_FROM_STRING_EXPLICIT -#include "numparse_unisets.h" +#include "static_unicode_sets.h" #include "umutex.h" #include "ucln_cmn.h" #include "unicode/uniset.h" @@ -18,22 +18,35 @@ #include "uassert.h" using namespace icu; -using namespace icu::numparse; -using namespace icu::numparse::impl; -using namespace icu::numparse::impl::unisets; +using namespace icu::unisets; namespace { -static UnicodeSet* gUnicodeSets[COUNT] = {}; +UnicodeSet* gUnicodeSets[COUNT] = {}; + +// Save the empty instance in static memory to have well-defined behavior if a +// regular UnicodeSet cannot be allocated. +char gEmptyUnicodeSet[sizeof(UnicodeSet)]; + +// Whether the gEmptyUnicodeSet is initialized and ready to use. +UBool gEmptyUnicodeSetInitialized = FALSE; + +inline UnicodeSet* getImpl(Key key) { + UnicodeSet* candidate = gUnicodeSets[key]; + if (candidate == nullptr) { + return reinterpret_cast(gEmptyUnicodeSet); + } + return candidate; +} UnicodeSet* computeUnion(Key k1, Key k2) { UnicodeSet* result = new UnicodeSet(); if (result == nullptr) { return nullptr; } - result->addAll(*gUnicodeSets[k1]); - result->addAll(*gUnicodeSets[k2]); + result->addAll(*getImpl(k1)); + result->addAll(*getImpl(k2)); result->freeze(); return result; } @@ -43,9 +56,9 @@ UnicodeSet* computeUnion(Key k1, Key k2, Key k3) { if (result == nullptr) { return nullptr; } - result->addAll(*gUnicodeSets[k1]); - result->addAll(*gUnicodeSets[k2]); - result->addAll(*gUnicodeSets[k3]); + result->addAll(*getImpl(k1)); + result->addAll(*getImpl(k2)); + result->addAll(*getImpl(k3)); result->freeze(); return result; } @@ -104,6 +117,10 @@ class ParseDataSink : public ResourceSink { icu::UInitOnce gNumberParseUniSetsInitOnce = U_INITONCE_INITIALIZER; UBool U_CALLCONV cleanupNumberParseUniSets() { + if (gEmptyUnicodeSetInitialized) { + reinterpret_cast(gEmptyUnicodeSet)->~UnicodeSet(); + gEmptyUnicodeSetInitialized = FALSE; + } for (int32_t i = 0; i < COUNT; i++) { delete gUnicodeSets[i]; gUnicodeSets[i] = nullptr; @@ -115,7 +132,10 @@ UBool U_CALLCONV cleanupNumberParseUniSets() { void U_CALLCONV initNumberParseUniSets(UErrorCode& status) { ucln_common_registerCleanup(UCLN_COMMON_NUMPARSE_UNISETS, cleanupNumberParseUniSets); - gUnicodeSets[EMPTY] = new UnicodeSet(); + // Initialize the empty instance for well-defined fallback behavior + new(gEmptyUnicodeSet) UnicodeSet(); + reinterpret_cast(gEmptyUnicodeSet)->freeze(); + gEmptyUnicodeSetInitialized = TRUE; // These sets were decided after discussion with icu-design@. See tickets #13084 and #13309. // Zs+TAB is "horizontal whitespace" according to UTS #18 (blank property). @@ -129,7 +149,7 @@ void U_CALLCONV initNumberParseUniSets(UErrorCode& status) { ures_getAllItemsWithFallback(rb.getAlias(), "parse", sink, status); if (U_FAILURE(status)) { return; } - // TODO: Should there be fallback behavior if for some reason these sets didn't get populated? + // NOTE: It is OK for these assertions to fail if there was a no-data build. U_ASSERT(gUnicodeSets[COMMA] != nullptr); U_ASSERT(gUnicodeSets[STRICT_COMMA] != nullptr); U_ASSERT(gUnicodeSets[PERIOD] != nullptr); @@ -158,8 +178,10 @@ void U_CALLCONV initNumberParseUniSets(UErrorCode& status) { gUnicodeSets[DIGITS_OR_ALL_SEPARATORS] = computeUnion(DIGITS, ALL_SEPARATORS); gUnicodeSets[DIGITS_OR_STRICT_ALL_SEPARATORS] = computeUnion(DIGITS, STRICT_ALL_SEPARATORS); - for (int32_t i = 0; i < COUNT; i++) { - gUnicodeSets[i]->freeze(); + for (auto* uniset : gUnicodeSets) { + if (uniset != nullptr) { + uniset->freeze(); + } } } @@ -169,14 +191,13 @@ const UnicodeSet* unisets::get(Key key) { UErrorCode localStatus = U_ZERO_ERROR; umtx_initOnce(gNumberParseUniSetsInitOnce, &initNumberParseUniSets, localStatus); if (U_FAILURE(localStatus)) { - // TODO: This returns non-null in Java, and callers assume that. - return nullptr; + return reinterpret_cast(gEmptyUnicodeSet); } - return gUnicodeSets[key]; + return getImpl(key); } Key unisets::chooseFrom(UnicodeString str, Key key1) { - return get(key1)->contains(str) ? key1 : COUNT; + return get(key1)->contains(str) ? key1 : NONE; } Key unisets::chooseFrom(UnicodeString str, Key key1, Key key2) { @@ -193,7 +214,7 @@ Key unisets::chooseFrom(UnicodeString str, Key key1, Key key2) { // } else if (get(YEN_SIGN)->contains(str)) { // return YEN_SIGN; // } else { -// return COUNT; +// return NONE; // } //} diff --git a/icu4c/source/common/numparse_unisets.h b/icu4c/source/common/static_unicode_sets.h similarity index 56% rename from icu4c/source/common/numparse_unisets.h rename to icu4c/source/common/static_unicode_sets.h index 5a93b834524..5f18b3217ea 100644 --- a/icu4c/source/common/numparse_unisets.h +++ b/icu4c/source/common/static_unicode_sets.h @@ -6,18 +6,20 @@ #include "unicode/utypes.h" #if !UCONFIG_NO_FORMATTING -#ifndef __NUMPARSE_UNISETS_H__ -#define __NUMPARSE_UNISETS_H__ +#ifndef __STATIC_UNICODE_SETS_H__ +#define __STATIC_UNICODE_SETS_H__ #include "unicode/uniset.h" #include "unicode/unistr.h" -U_NAMESPACE_BEGIN namespace numparse { -namespace impl { +U_NAMESPACE_BEGIN namespace unisets { enum Key { - EMPTY, + // NONE is used to indicate null in chooseFrom(). + // EMPTY is used to get an empty UnicodeSet. + NONE = -1, + EMPTY = 0, // Ignorables DEFAULT_IGNORABLES, @@ -57,17 +59,44 @@ enum Key { DIGITS_OR_ALL_SEPARATORS, DIGITS_OR_STRICT_ALL_SEPARATORS, - // The number of elements in the enum. Also used to indicate null. + // The number of elements in the enum. COUNT }; -// Exported as U_COMMON_API for ucurr.cpp +/** + * Gets the static-allocated UnicodeSet according to the provided key. The + * pointer will be deleted during u_cleanup(); the caller should NOT delete it. + * + * Exported as U_COMMON_API for ucurr.cpp + * + * @param key The desired UnicodeSet according to the enum in this file. + * @return The requested UnicodeSet. Guaranteed to be frozen and non-null, but + * may be empty if an error occurred during data loading. + */ U_COMMON_API const UnicodeSet* get(Key key); -// Exported as U_COMMON_API for numparse_decimal.cpp +/** + * Checks if the UnicodeSet given by key1 contains the given string. + * + * Exported as U_COMMON_API for numparse_decimal.cpp + * + * @param str The string to check. + * @param key1 The set to check. + * @return key1 if the set contains str, or NONE if not. + */ U_COMMON_API Key chooseFrom(UnicodeString str, Key key1); -// Exported as U_COMMON_API for numparse_decimal.cpp +/** + * Checks if the UnicodeSet given by either key1 or key2 contains the string. + * + * Exported as U_COMMON_API for numparse_decimal.cpp + * + * @param str The string to check. + * @param key1 The first set to check. + * @param key2 The second set to check. + * @return key1 if that set contains str; key2 if that set contains str; or + * NONE if neither set contains str. + */ U_COMMON_API Key chooseFrom(UnicodeString str, Key key1, Key key2); // Unused in C++: @@ -84,9 +113,7 @@ static const struct { }; } // namespace unisets -} // namespace impl -} // namespace numparse U_NAMESPACE_END -#endif //__NUMPARSE_UNISETS_H__ +#endif //__STATIC_UNICODE_SETS_H__ #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/icu4c/source/common/ucurr.cpp b/icu4c/source/common/ucurr.cpp index 1fd02ec30b5..53431cbb625 100644 --- a/icu4c/source/common/ucurr.cpp +++ b/icu4c/source/common/ucurr.cpp @@ -23,7 +23,7 @@ #include "charstr.h" #include "cmemory.h" #include "cstring.h" -#include "numparse_unisets.h" +#include "static_unicode_sets.h" #include "uassert.h" #include "umutex.h" #include "ucln_cmn.h" @@ -2201,7 +2201,6 @@ static void U_CALLCONV initIsoCodes(UErrorCode &status) { } static void populateCurrSymbolsEquiv(icu::Hashtable *hash, UErrorCode &status) { - using namespace icu::numparse::impl; if (U_FAILURE(status)) { return; } for (auto& entry : unisets::kCurrencyEntries) { UnicodeString exemplar(entry.exemplar); diff --git a/icu4c/source/i18n/numparse_decimal.cpp b/icu4c/source/i18n/numparse_decimal.cpp index 68b4d325704..a8d63c3f91e 100644 --- a/icu4c/source/i18n/numparse_decimal.cpp +++ b/icu4c/source/i18n/numparse_decimal.cpp @@ -11,7 +11,7 @@ #include "numparse_types.h" #include "numparse_decimal.h" -#include "numparse_unisets.h" +#include "static_unicode_sets.h" #include "numparse_utils.h" #include "unicode/uchar.h" #include "putilimp.h" @@ -41,7 +41,7 @@ DecimalMatcher::DecimalMatcher(const DecimalFormatSymbols& symbols, const Groupe decimalSeparator, strictSeparators ? unisets::STRICT_COMMA : unisets::COMMA, strictSeparators ? unisets::STRICT_PERIOD : unisets::PERIOD); - if (decimalKey != unisets::COUNT) { + if (decimalKey >= 0) { decimalUniSet = unisets::get(decimalKey); } else { auto* set = new UnicodeSet(); @@ -51,7 +51,7 @@ DecimalMatcher::DecimalMatcher(const DecimalFormatSymbols& symbols, const Groupe fLocalDecimalUniSet.adoptInstead(set); } - if (groupingKey != unisets::COUNT && decimalKey != unisets::COUNT) { + if (groupingKey >= 0 && decimalKey >= 0) { // Everything is available in the static cache separatorSet = groupingUniSet; leadSet = unisets::get( diff --git a/icu4c/source/i18n/numparse_impl.cpp b/icu4c/source/i18n/numparse_impl.cpp index 79f02cdfa8c..cda6715c036 100644 --- a/icu4c/source/i18n/numparse_impl.cpp +++ b/icu4c/source/i18n/numparse_impl.cpp @@ -21,7 +21,7 @@ #include "unicode/numberformatter.h" #include "cstr.h" #include "number_mapper.h" -#include "numparse_unisets.h" +#include "static_unicode_sets.h" using namespace icu; using namespace icu::number; diff --git a/icu4c/source/i18n/numparse_scientific.cpp b/icu4c/source/i18n/numparse_scientific.cpp index 8fed94f41da..3950392bf26 100644 --- a/icu4c/source/i18n/numparse_scientific.cpp +++ b/icu4c/source/i18n/numparse_scientific.cpp @@ -11,7 +11,7 @@ #include "numparse_types.h" #include "numparse_scientific.h" -#include "numparse_unisets.h" +#include "static_unicode_sets.h" using namespace icu; using namespace icu::numparse; diff --git a/icu4c/source/i18n/numparse_symbols.h b/icu4c/source/i18n/numparse_symbols.h index df87de69f18..8912ee95b0d 100644 --- a/icu4c/source/i18n/numparse_symbols.h +++ b/icu4c/source/i18n/numparse_symbols.h @@ -9,7 +9,7 @@ #include "numparse_types.h" #include "unicode/uniset.h" -#include "numparse_unisets.h" +#include "static_unicode_sets.h" U_NAMESPACE_BEGIN namespace numparse { namespace impl { diff --git a/icu4c/source/i18n/numparse_validators.cpp b/icu4c/source/i18n/numparse_validators.cpp index 4fbe07e087c..62622ae976b 100644 --- a/icu4c/source/i18n/numparse_validators.cpp +++ b/icu4c/source/i18n/numparse_validators.cpp @@ -11,7 +11,7 @@ #include "numparse_types.h" #include "numparse_validators.h" -#include "numparse_unisets.h" +#include "static_unicode_sets.h" using namespace icu; using namespace icu::numparse; diff --git a/icu4c/source/i18n/numparse_validators.h b/icu4c/source/i18n/numparse_validators.h index cf989d57579..f6768938c1e 100644 --- a/icu4c/source/i18n/numparse_validators.h +++ b/icu4c/source/i18n/numparse_validators.h @@ -8,7 +8,7 @@ #define __SOURCE_NUMPARSE_VALIDATORS_H__ #include "numparse_types.h" -#include "numparse_unisets.h" +#include "static_unicode_sets.h" U_NAMESPACE_BEGIN namespace numparse { namespace impl { diff --git a/icu4c/source/i18n/scientificnumberformatter.cpp b/icu4c/source/i18n/scientificnumberformatter.cpp index a63f15f6fb6..03d98dd6e10 100644 --- a/icu4c/source/i18n/scientificnumberformatter.cpp +++ b/icu4c/source/i18n/scientificnumberformatter.cpp @@ -16,7 +16,7 @@ #include "unicode/utf16.h" #include "unicode/uniset.h" #include "unicode/decimfmt.h" -#include "numparse_unisets.h" +#include "static_unicode_sets.h" U_NAMESPACE_BEGIN diff --git a/icu4c/source/test/intltest/Makefile.in b/icu4c/source/test/intltest/Makefile.in index 55d1fb21421..22fe37b299d 100644 --- a/icu4c/source/test/intltest/Makefile.in +++ b/icu4c/source/test/intltest/Makefile.in @@ -64,8 +64,9 @@ scientificnumberformattertest.o datadrivennumberformattestsuite.o \ numberformattesttuple.o pluralmaptest.o \ numbertest_affixutils.o numbertest_api.o numbertest_decimalquantity.o \ numbertest_modifiers.o numbertest_patternmodifier.o numbertest_patternstring.o \ -numbertest_stringbuilder.o numbertest_stringsegment.o numbertest_unisets.o \ -numbertest_parse.o numbertest_doubleconversion.o numbertest_skeletons.o +numbertest_stringbuilder.o numbertest_stringsegment.o \ +numbertest_parse.o numbertest_doubleconversion.o numbertest_skeletons.o \ +static_unisets_test.o DEPS = $(OBJECTS:.o=.d) diff --git a/icu4c/source/test/intltest/intltest.cpp b/icu4c/source/test/intltest/intltest.cpp index 47b220afad7..e85ba87fca8 100644 --- a/icu4c/source/test/intltest/intltest.cpp +++ b/icu4c/source/test/intltest/intltest.cpp @@ -1901,9 +1901,13 @@ UBool IntlTest::assertTrue(const char* message, UBool condition, UBool quiet, UB return condition; } -UBool IntlTest::assertFalse(const char* message, UBool condition, UBool quiet) { +UBool IntlTest::assertFalse(const char* message, UBool condition, UBool quiet, UBool possibleDataError) { if (condition) { - errln("FAIL: assertFalse() failed: %s", message); + if (possibleDataError) { + dataerrln("FAIL: assertTrue() failed: %s", message); + } else { + errln("FAIL: assertTrue() failed: %s", message); + } } else if (!quiet) { logln("Ok: %s", message); } @@ -2111,12 +2115,12 @@ static const char* extractToAssertBuf(const UnicodeString& message) { return ASSERT_BUF; } -UBool IntlTest::assertTrue(const UnicodeString& message, UBool condition, UBool quiet) { - return assertTrue(extractToAssertBuf(message), condition, quiet); +UBool IntlTest::assertTrue(const UnicodeString& message, UBool condition, UBool quiet, UBool possibleDataError) { + return assertTrue(extractToAssertBuf(message), condition, quiet, possibleDataError); } -UBool IntlTest::assertFalse(const UnicodeString& message, UBool condition, UBool quiet) { - return assertFalse(extractToAssertBuf(message), condition, quiet); +UBool IntlTest::assertFalse(const UnicodeString& message, UBool condition, UBool quiet, UBool possibleDataError) { + return assertFalse(extractToAssertBuf(message), condition, quiet, possibleDataError); } UBool IntlTest::assertSuccess(const UnicodeString& message, UErrorCode ec) { diff --git a/icu4c/source/test/intltest/intltest.h b/icu4c/source/test/intltest/intltest.h index 5d4b661f392..ee3c88324d2 100644 --- a/icu4c/source/test/intltest/intltest.h +++ b/icu4c/source/test/intltest/intltest.h @@ -282,7 +282,7 @@ public: /* JUnit-like assertions. Each returns TRUE if it succeeds. */ UBool assertTrue(const char* message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE, const char *file=NULL, int line=0); - UBool assertFalse(const char* message, UBool condition, UBool quiet=FALSE); + UBool assertFalse(const char* message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE); /** * @param possibleDataError - if TRUE, use dataerrln instead of errcheckln on failure * @return TRUE on success, FALSE on failure. @@ -303,8 +303,8 @@ public: UBool assertEquals(const UnicodeString& message, const Formattable& expected, const Formattable& actual); #endif - UBool assertTrue(const UnicodeString& message, UBool condition, UBool quiet=FALSE); - UBool assertFalse(const UnicodeString& message, UBool condition, UBool quiet=FALSE); + UBool assertTrue(const UnicodeString& message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE); + UBool assertFalse(const UnicodeString& message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE); UBool assertSuccess(const UnicodeString& message, UErrorCode ec); UBool assertEquals(const UnicodeString& message, const UnicodeString& expected, const UnicodeString& actual, UBool possibleDataError=FALSE); diff --git a/icu4c/source/test/intltest/intltest.vcxproj b/icu4c/source/test/intltest/intltest.vcxproj index 8dda453125e..22bff31edda 100644 --- a/icu4c/source/test/intltest/intltest.vcxproj +++ b/icu4c/source/test/intltest/intltest.vcxproj @@ -253,7 +253,6 @@ - @@ -270,8 +269,9 @@ - + + diff --git a/icu4c/source/test/intltest/intltest.vcxproj.filters b/icu4c/source/test/intltest/intltest.vcxproj.filters index 2e54fee0920..863bc67bdc4 100644 --- a/icu4c/source/test/intltest/intltest.vcxproj.filters +++ b/icu4c/source/test/intltest/intltest.vcxproj.filters @@ -280,9 +280,6 @@ formatting - - formatting - formatting @@ -328,6 +325,9 @@ formatting + + formatting + formatting diff --git a/icu4c/source/test/intltest/itutil.cpp b/icu4c/source/test/intltest/itutil.cpp index f890a241636..7f969d9ad8f 100644 --- a/icu4c/source/test/intltest/itutil.cpp +++ b/icu4c/source/test/intltest/itutil.cpp @@ -39,7 +39,8 @@ static IntlTest *createEnumSetTest(); extern IntlTest *createSimpleFormatterTest(); extern IntlTest *createUnifiedCacheTest(); extern IntlTest *createQuantityFormatterTest(); -extern IntlTest *createPluralMapTest(); +extern IntlTest *createPluralMapTest(); +extern IntlTest *createStaticUnicodeSetsTest(); #define CASE(id, test) case id: \ @@ -135,6 +136,14 @@ void IntlTestUtilities::runIndexedTest( int32_t index, UBool exec, const char* & callTest(*test, par); } break; + case 24: + name = "StaticUnicodeSetsTest"; + if (exec) { + logln("TestSuite StaticUnicodeSetsTest---"); logln(); + LocalPointer test(createStaticUnicodeSetsTest()); + callTest(*test, par); + } + break; default: name = ""; break; //needed to end loop } } diff --git a/icu4c/source/test/intltest/numbertest.h b/icu4c/source/test/intltest/numbertest.h index 69c3ee44edc..8984fdc3669 100644 --- a/icu4c/source/test/intltest/numbertest.h +++ b/icu4c/source/test/intltest/numbertest.h @@ -214,19 +214,6 @@ class StringSegmentTest : public IntlTest { void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); }; -class UniSetsTest : public IntlTest { - public: - void testSetCoverage(); - - void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); - - private: - void assertInSet(const UnicodeString& localeName, const UnicodeString &setName, - const UnicodeSet& set, const UnicodeString& str); - void assertInSet(const UnicodeString& localeName, const UnicodeString &setName, - const UnicodeSet& set, UChar32 cp); -}; - class NumberParserTest : public IntlTest { public: void testBasic(); @@ -287,9 +274,8 @@ class NumberTest : public IntlTest { TESTCLASS(6, NumberStringBuilderTest); TESTCLASS(7, DoubleConversionTest); TESTCLASS(8, StringSegmentTest); - TESTCLASS(9, UniSetsTest); - TESTCLASS(10, NumberParserTest); - TESTCLASS(11, NumberSkeletonTest); + TESTCLASS(9, NumberParserTest); + TESTCLASS(10, NumberSkeletonTest); default: name = ""; break; // needed to end loop } } diff --git a/icu4c/source/test/intltest/numbertest_parse.cpp b/icu4c/source/test/intltest/numbertest_parse.cpp index 2132c18b2f3..53fbce8eb59 100644 --- a/icu4c/source/test/intltest/numbertest_parse.cpp +++ b/icu4c/source/test/intltest/numbertest_parse.cpp @@ -7,14 +7,14 @@ #include "numbertest.h" #include "numparse_impl.h" -#include "numparse_unisets.h" +#include "static_unicode_sets.h" #include "unicode/dcfmtsym.h" #include "unicode/testlog.h" #include #include -using icu::numparse::impl::unisets::get; +using icu::unisets::get; void NumberParserTest::runIndexedTest(int32_t index, UBool exec, const char*& name, char*) { if (exec) { diff --git a/icu4c/source/test/intltest/numbertest_unisets.cpp b/icu4c/source/test/intltest/static_unisets_test.cpp similarity index 68% rename from icu4c/source/test/intltest/numbertest_unisets.cpp rename to icu4c/source/test/intltest/static_unisets_test.cpp index 7311332dd1e..bfe69963526 100644 --- a/icu4c/source/test/intltest/numbertest_unisets.cpp +++ b/icu4c/source/test/intltest/static_unisets_test.cpp @@ -6,21 +6,40 @@ #if !UCONFIG_NO_FORMATTING #include "numbertest.h" -#include "numparse_unisets.h" +#include "static_unicode_sets.h" #include "unicode/dcfmtsym.h" -using icu::numparse::impl::unisets::get; +using icu::unisets::get; -void UniSetsTest::runIndexedTest(int32_t index, UBool exec, const char*&name, char*) { +class StaticUnicodeSetsTest : public IntlTest { + public: + void testSetCoverage(); + void testNonEmpty(); + + void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); + + private: + void assertInSet(const UnicodeString& localeName, const UnicodeString &setName, + const UnicodeSet& set, const UnicodeString& str); + void assertInSet(const UnicodeString& localeName, const UnicodeString &setName, + const UnicodeSet& set, UChar32 cp); +}; + +extern IntlTest *createStaticUnicodeSetsTest() { + return new StaticUnicodeSetsTest(); +} + +void StaticUnicodeSetsTest::runIndexedTest(int32_t index, UBool exec, const char*&name, char*) { if (exec) { - logln("TestSuite UniSetsTest: "); + logln("TestSuite StaticUnicodeSetsTest: "); } TESTCASE_AUTO_BEGIN; TESTCASE_AUTO(testSetCoverage); + TESTCASE_AUTO(testNonEmpty); TESTCASE_AUTO_END; } -void UniSetsTest::testSetCoverage() { +void StaticUnicodeSetsTest::testSetCoverage() { UErrorCode status = U_ZERO_ERROR; // Lenient comma/period should be supersets of strict comma/period; @@ -67,7 +86,18 @@ void UniSetsTest::testSetCoverage() { } } -void UniSetsTest::assertInSet(const UnicodeString &localeName, const UnicodeString &setName, +void StaticUnicodeSetsTest::testNonEmpty() { + for (int32_t i=0; i(i)); + // Can fail if no data: + assertFalse(UnicodeString("Set should not be empty: ") + i, uset->isEmpty(), FALSE, TRUE); + } +} + +void StaticUnicodeSetsTest::assertInSet(const UnicodeString &localeName, const UnicodeString &setName, const UnicodeSet &set, const UnicodeString &str) { if (str.countChar32(0, str.length()) != 1) { // Ignore locale strings with more than one code point (usually a bidi mark) @@ -76,7 +106,7 @@ void UniSetsTest::assertInSet(const UnicodeString &localeName, const UnicodeStri assertInSet(localeName, setName, set, str.char32At(0)); } -void UniSetsTest::assertInSet(const UnicodeString &localeName, const UnicodeString &setName, +void StaticUnicodeSetsTest::assertInSet(const UnicodeString &localeName, const UnicodeString &setName, const UnicodeSet &set, UChar32 cp) { // If this test case fails, add the specified code point to the corresponding set in // UnicodeSetStaticCache.java and numparse_unisets.cpp diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/UnicodeSetStaticCache.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/StaticUnicodeSets.java similarity index 79% rename from icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/UnicodeSetStaticCache.java rename to icu4j/main/classes/core/src/com/ibm/icu/impl/StaticUnicodeSets.java index 0148b36347d..b4543ef69e2 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/UnicodeSetStaticCache.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/StaticUnicodeSets.java @@ -1,29 +1,26 @@ // © 2017 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html#License -package com.ibm.icu.impl.number.parse; +package com.ibm.icu.impl; import java.util.EnumMap; import java.util.Map; -import com.ibm.icu.impl.ICUData; -import com.ibm.icu.impl.ICUResourceBundle; -import com.ibm.icu.impl.UResource; import com.ibm.icu.impl.UResource.Value; import com.ibm.icu.text.UnicodeSet; import com.ibm.icu.util.ULocale; import com.ibm.icu.util.UResourceBundle; /** - * This class statically initializes UnicodeSets useful for number parsing. Microbenchmarks show this to - * bring a very sizeable performance boost. + * This class statically initializes UnicodeSets, originally built for number parsing. Microbenchmarks + * show this to bring a very sizeable performance boost. * - * IMPORTANT ASSUMPTION: All of the sets contain code points (no strings) and they are all case-folded. - * If this assumption were ever broken, logic in classes such as SymbolMatcher would need to be updated - * in order to return well-formed sets upon calls to getLeadCodePoints(). + * IMPORTANT ASSUMPTION FOR NUMBER PARSING: All of the sets contain code points (no strings) and they are + * all case-folded. If this assumption were ever broken, logic in classes such as SymbolMatcher would + * need to be updated in order to return well-formed sets upon calls to getLeadCodePoints(). * * @author sffc */ -public class UnicodeSetStaticCache { +public class StaticUnicodeSets { public static enum Key { // Ignorables DEFAULT_IGNORABLES, @@ -67,18 +64,57 @@ public class UnicodeSetStaticCache { private static final Map unicodeSets = new EnumMap(Key.class); + /** + * Gets the static-allocated UnicodeSet according to the provided key. + * + * @param key + * The desired UnicodeSet according to the enum in this file. + * @return The requested UnicodeSet. Guaranteed to be frozen and non-null, but may be empty if an + * error occurred during data loading. + */ public static UnicodeSet get(Key key) { - return unicodeSets.get(key); + UnicodeSet candidate = unicodeSets.get(key); + if (candidate == null) { + return UnicodeSet.EMPTY; + } + return candidate; } + /** + * Checks if the UnicodeSet given by key1 contains the given string. + * + * @param str + * The string to check. + * @param key1 + * The set to check. + * @return key1 if the set contains str, or COUNT if not. + */ public static Key chooseFrom(String str, Key key1) { return get(key1).contains(str) ? key1 : null; } + /** + * Checks if the UnicodeSet given by either key1 or key2 contains the string. + * + * Exported as U_COMMON_API for numparse_decimal.cpp + * + * @param str + * The string to check. + * @param key1 + * The first set to check. + * @param key2 + * The second set to check. + * @return key1 if that set contains str; key2 if that set contains str; or COUNT if neither set + * contains str. + */ public static Key chooseFrom(String str, Key key1, Key key2) { return get(key1).contains(str) ? key1 : chooseFrom(str, key2); } + /** + * Looks through all Currency-related sets for the given string, returning the first match or null if + * no match was round. + */ public static Key chooseCurrency(String str) { if (get(Key.DOLLAR_SIGN).contains(str)) { return Key.DOLLAR_SIGN; @@ -187,7 +223,7 @@ public class UnicodeSetStaticCache { .getBundleInstance(ICUData.ICU_BASE_NAME, ULocale.ROOT); rb.getAllItemsWithFallback("parse", new ParseDataSink()); - // TODO: Should there be fallback behavior if for some reason these sets didn't get populated? + // NOTE: It is OK for these assertions to fail if there was a no-data build. assert unicodeSets.containsKey(Key.COMMA); assert unicodeSets.containsKey(Key.STRICT_COMMA); assert unicodeSets.containsKey(Key.PERIOD); diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/DecimalMatcher.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/DecimalMatcher.java index 6d97d3dea9c..91595de6065 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/DecimalMatcher.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/DecimalMatcher.java @@ -3,9 +3,10 @@ package com.ibm.icu.impl.number.parse; import com.ibm.icu.impl.StringSegment; +import com.ibm.icu.impl.StaticUnicodeSets; +import com.ibm.icu.impl.StaticUnicodeSets.Key; import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD; import com.ibm.icu.impl.number.Grouper; -import com.ibm.icu.impl.number.parse.UnicodeSetStaticCache.Key; import com.ibm.icu.lang.UCharacter; import com.ibm.icu.text.DecimalFormatSymbols; import com.ibm.icu.text.UnicodeSet; @@ -63,12 +64,12 @@ public class DecimalMatcher implements NumberParseMatcher { // Attempt to find separators in the static cache - groupingUniSet = UnicodeSetStaticCache.get(groupingKey); - Key decimalKey = UnicodeSetStaticCache.chooseFrom(decimalSeparator, + groupingUniSet = StaticUnicodeSets.get(groupingKey); + Key decimalKey = StaticUnicodeSets.chooseFrom(decimalSeparator, strictSeparators ? Key.STRICT_COMMA : Key.COMMA, strictSeparators ? Key.STRICT_PERIOD : Key.PERIOD); if (decimalKey != null) { - decimalUniSet = UnicodeSetStaticCache.get(decimalKey); + decimalUniSet = StaticUnicodeSets.get(decimalKey); } else { decimalUniSet = new UnicodeSet().add(decimalSeparator.codePointAt(0)).freeze(); } @@ -76,7 +77,7 @@ public class DecimalMatcher implements NumberParseMatcher { if (groupingKey != null && decimalKey != null) { // Everything is available in the static cache separatorSet = groupingUniSet; - leadSet = UnicodeSetStaticCache.get(strictSeparators ? Key.DIGITS_OR_ALL_SEPARATORS + leadSet = StaticUnicodeSets.get(strictSeparators ? Key.DIGITS_OR_ALL_SEPARATORS : Key.DIGITS_OR_STRICT_ALL_SEPARATORS); } else { separatorSet = new UnicodeSet().addAll(groupingUniSet).addAll(decimalUniSet).freeze(); diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/IgnorablesMatcher.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/IgnorablesMatcher.java index 190396bd128..78a33339a30 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/IgnorablesMatcher.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/IgnorablesMatcher.java @@ -3,6 +3,7 @@ package com.ibm.icu.impl.number.parse; import com.ibm.icu.impl.StringSegment; +import com.ibm.icu.impl.StaticUnicodeSets; import com.ibm.icu.text.UnicodeSet; /** @@ -12,10 +13,10 @@ import com.ibm.icu.text.UnicodeSet; public class IgnorablesMatcher extends SymbolMatcher implements NumberParseMatcher.Flexible { public static final IgnorablesMatcher DEFAULT = new IgnorablesMatcher( - UnicodeSetStaticCache.get(UnicodeSetStaticCache.Key.DEFAULT_IGNORABLES)); + StaticUnicodeSets.get(StaticUnicodeSets.Key.DEFAULT_IGNORABLES)); public static final IgnorablesMatcher STRICT = new IgnorablesMatcher( - UnicodeSetStaticCache.get(UnicodeSetStaticCache.Key.STRICT_IGNORABLES)); + StaticUnicodeSets.get(StaticUnicodeSets.Key.STRICT_IGNORABLES)); public static IgnorablesMatcher getInstance(UnicodeSet ignorables) { assert ignorables.isFrozen(); diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/InfinityMatcher.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/InfinityMatcher.java index 1acb6523671..999932b0450 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/InfinityMatcher.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/InfinityMatcher.java @@ -3,6 +3,7 @@ package com.ibm.icu.impl.number.parse; import com.ibm.icu.impl.StringSegment; +import com.ibm.icu.impl.StaticUnicodeSets; import com.ibm.icu.text.DecimalFormatSymbols; /** @@ -27,7 +28,7 @@ public class InfinityMatcher extends SymbolMatcher { } private InfinityMatcher() { - super(UnicodeSetStaticCache.Key.INFINITY); + super(StaticUnicodeSets.Key.INFINITY); } @Override diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/MinusSignMatcher.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/MinusSignMatcher.java index 616015c4411..92e19b4fdb5 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/MinusSignMatcher.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/MinusSignMatcher.java @@ -3,6 +3,7 @@ package com.ibm.icu.impl.number.parse; import com.ibm.icu.impl.StringSegment; +import com.ibm.icu.impl.StaticUnicodeSets; import com.ibm.icu.text.DecimalFormatSymbols; /** @@ -31,7 +32,7 @@ public class MinusSignMatcher extends SymbolMatcher { } private MinusSignMatcher(boolean allowTrailing) { - super(UnicodeSetStaticCache.Key.MINUS_SIGN); + super(StaticUnicodeSets.Key.MINUS_SIGN); this.allowTrailing = allowTrailing; } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PercentMatcher.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PercentMatcher.java index 3944c316843..85eaf0644ae 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PercentMatcher.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PercentMatcher.java @@ -3,6 +3,7 @@ package com.ibm.icu.impl.number.parse; import com.ibm.icu.impl.StringSegment; +import com.ibm.icu.impl.StaticUnicodeSets; import com.ibm.icu.text.DecimalFormatSymbols; /** @@ -27,7 +28,7 @@ public class PercentMatcher extends SymbolMatcher { } private PercentMatcher() { - super(UnicodeSetStaticCache.Key.PERCENT_SIGN); + super(StaticUnicodeSets.Key.PERCENT_SIGN); } @Override diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PermilleMatcher.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PermilleMatcher.java index 3ad6e09eac0..1b9bd223a47 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PermilleMatcher.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PermilleMatcher.java @@ -3,6 +3,7 @@ package com.ibm.icu.impl.number.parse; import com.ibm.icu.impl.StringSegment; +import com.ibm.icu.impl.StaticUnicodeSets; import com.ibm.icu.text.DecimalFormatSymbols; /** @@ -27,7 +28,7 @@ public class PermilleMatcher extends SymbolMatcher { } private PermilleMatcher() { - super(UnicodeSetStaticCache.Key.PERMILLE_SIGN); + super(StaticUnicodeSets.Key.PERMILLE_SIGN); } @Override diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PlusSignMatcher.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PlusSignMatcher.java index dccb6846314..ed40bb84b67 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PlusSignMatcher.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/PlusSignMatcher.java @@ -3,6 +3,7 @@ package com.ibm.icu.impl.number.parse; import com.ibm.icu.impl.StringSegment; +import com.ibm.icu.impl.StaticUnicodeSets; import com.ibm.icu.text.DecimalFormatSymbols; /** @@ -31,7 +32,7 @@ public class PlusSignMatcher extends SymbolMatcher { } private PlusSignMatcher(boolean allowTrailing) { - super(UnicodeSetStaticCache.Key.PLUS_SIGN); + super(StaticUnicodeSets.Key.PLUS_SIGN); this.allowTrailing = allowTrailing; } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/ScientificMatcher.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/ScientificMatcher.java index 6b5c1123552..64f6e3d5ffa 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/ScientificMatcher.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/ScientificMatcher.java @@ -3,6 +3,7 @@ package com.ibm.icu.impl.number.parse; import com.ibm.icu.impl.StringSegment; +import com.ibm.icu.impl.StaticUnicodeSets; import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD; import com.ibm.icu.impl.number.Grouper; import com.ibm.icu.text.DecimalFormatSymbols; @@ -37,11 +38,11 @@ public class ScientificMatcher implements NumberParseMatcher { } private static UnicodeSet minusSignSet() { - return UnicodeSetStaticCache.get(UnicodeSetStaticCache.Key.MINUS_SIGN); + return StaticUnicodeSets.get(StaticUnicodeSets.Key.MINUS_SIGN); } private static UnicodeSet plusSignSet() { - return UnicodeSetStaticCache.get(UnicodeSetStaticCache.Key.PLUS_SIGN); + return StaticUnicodeSets.get(StaticUnicodeSets.Key.PLUS_SIGN); } @Override diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/SymbolMatcher.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/SymbolMatcher.java index f5b27c1d124..24284b160ba 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/SymbolMatcher.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/SymbolMatcher.java @@ -3,6 +3,7 @@ package com.ibm.icu.impl.number.parse; import com.ibm.icu.impl.StringSegment; +import com.ibm.icu.impl.StaticUnicodeSets; import com.ibm.icu.text.UnicodeSet; /** @@ -22,9 +23,9 @@ public abstract class SymbolMatcher implements NumberParseMatcher { uniSet = symbolUniSet; } - protected SymbolMatcher(UnicodeSetStaticCache.Key key) { + protected SymbolMatcher(StaticUnicodeSets.Key key) { string = ""; - uniSet = UnicodeSetStaticCache.get(key); + uniSet = StaticUnicodeSets.get(key); } public UnicodeSet getSet() { diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/ScientificNumberFormatter.java b/icu4j/main/classes/core/src/com/ibm/icu/text/ScientificNumberFormatter.java index e501d0182b5..0683cf98288 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/ScientificNumberFormatter.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/ScientificNumberFormatter.java @@ -13,7 +13,7 @@ import java.text.AttributedCharacterIterator.Attribute; import java.text.CharacterIterator; import java.util.Map; -import com.ibm.icu.impl.number.parse.UnicodeSetStaticCache; +import com.ibm.icu.impl.StaticUnicodeSets; import com.ibm.icu.lang.UCharacter; import com.ibm.icu.util.ULocale; @@ -230,14 +230,14 @@ public final class ScientificNumberFormatter { int start = iterator.getRunStart(NumberFormat.Field.EXPONENT_SIGN); int limit = iterator.getRunLimit(NumberFormat.Field.EXPONENT_SIGN); int aChar = char32AtAndAdvance(iterator); - if (UnicodeSetStaticCache.get(UnicodeSetStaticCache.Key.MINUS_SIGN).contains(aChar)) { + if (StaticUnicodeSets.get(StaticUnicodeSets.Key.MINUS_SIGN).contains(aChar)) { append( iterator, copyFromOffset, start, result); result.append(SUPERSCRIPT_MINUS_SIGN); - } else if (UnicodeSetStaticCache.get(UnicodeSetStaticCache.Key.PLUS_SIGN).contains(aChar)) { + } else if (StaticUnicodeSets.get(StaticUnicodeSets.Key.PLUS_SIGN).contains(aChar)) { append( iterator, copyFromOffset, diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java b/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java index 03febbe1433..753dfcf3169 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java @@ -30,7 +30,7 @@ import com.ibm.icu.impl.ICUResourceBundle; import com.ibm.icu.impl.SimpleCache; import com.ibm.icu.impl.SoftCache; import com.ibm.icu.impl.TextTrieMap; -import com.ibm.icu.impl.number.parse.UnicodeSetStaticCache; +import com.ibm.icu.impl.StaticUnicodeSets; import com.ibm.icu.text.CurrencyDisplayNames; import com.ibm.icu.text.CurrencyMetaInfo; import com.ibm.icu.text.CurrencyMetaInfo.CurrencyDigits; @@ -772,10 +772,10 @@ public class Currency extends MeasureUnit { String isoCode = e.getValue(); // Register under not just symbol, but under every equivalent symbol as well // e.g short width yen and long width yen. - UnicodeSetStaticCache.Key key = UnicodeSetStaticCache.chooseCurrency(symbol); + StaticUnicodeSets.Key key = StaticUnicodeSets.chooseCurrency(symbol); CurrencyStringInfo value = new CurrencyStringInfo(isoCode, symbol); if (key != null) { - UnicodeSet equivalents = UnicodeSetStaticCache.get(key); + UnicodeSet equivalents = StaticUnicodeSets.get(key); // The symbol itself is included in the UnicodeSet for (String equivalentSymbol : equivalents) { symTrie.put(equivalentSymbol, value); diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java index bca8f848a6a..5bfec66f229 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java @@ -2,7 +2,7 @@ // License & terms of use: http://www.unicode.org/copyright.html#License package com.ibm.icu.dev.test.number; -import static com.ibm.icu.impl.number.parse.UnicodeSetStaticCache.get; +import static com.ibm.icu.impl.StaticUnicodeSets.get; import java.math.BigDecimal; import java.util.Random; @@ -11,8 +11,8 @@ import org.junit.Before; import org.junit.Test; import com.ibm.icu.dev.test.TestFmwk; +import com.ibm.icu.impl.StaticUnicodeSets.Key; import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD; -import com.ibm.icu.impl.number.parse.UnicodeSetStaticCache.Key; import com.ibm.icu.lang.UCharacter; import com.ibm.icu.number.NumberFormatter; import com.ibm.icu.number.Precision; diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/UnicodeSetStaticCacheTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/UnicodeSetStaticCacheTest.java deleted file mode 100644 index ca239267bb2..00000000000 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/UnicodeSetStaticCacheTest.java +++ /dev/null @@ -1,24 +0,0 @@ -// © 2018 and later: Unicode, Inc. and others. -// License & terms of use: http://www.unicode.org/copyright.html#License -package com.ibm.icu.dev.test.number; - -import static com.ibm.icu.impl.number.parse.UnicodeSetStaticCache.get; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.ibm.icu.impl.number.parse.UnicodeSetStaticCache.Key; - -/** - * This test class is thin; most of it was moved to ExhaustiveNumberTest. - * @author sffc - */ -public class UnicodeSetStaticCacheTest { - - @Test - public void testFrozen() { - for (Key key : Key.values()) { - assertTrue(get(key).isFrozen()); - } - } -} diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/StaticUnicodeSetsTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/StaticUnicodeSetsTest.java new file mode 100644 index 00000000000..aa4a7db7b01 --- /dev/null +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/StaticUnicodeSetsTest.java @@ -0,0 +1,33 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html#License +package com.ibm.icu.dev.test.util; + +import static com.ibm.icu.impl.StaticUnicodeSets.get; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.ibm.icu.impl.StaticUnicodeSets.Key; + +/** + * NOTE: The test testSetCoverage can be found in ExhaustiveNumberTest.java + * + * @author sffc + */ +public class StaticUnicodeSetsTest { + + @Test + public void testFrozen() { + for (Key key : Key.values()) { + assertTrue(get(key).isFrozen()); + } + } + + @Test + public void testNonEmpty() { + for (Key key : Key.values()) { + // NOTE: No key EMPTY in Java + assertTrue(get(key).isFrozen()); + } + } +}