Releases: NightOwl888/ICU4N
Releases · NightOwl888/ICU4N
v60.1.0-alpha.436
Summary
This release focuses primarily on:
- Fixing issues with deploying satellite assemblies to the build and publish output
- Removing support for
ICharSequence
and changing toReadOnlySpan<char>
- Removing support for
StringBuilder
as a character sequence, since it has documented performance problems. See: https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.chars?view=net-8.0#remarks - Reducing unnecessary heap allocations by using the stack and/or array pool
- Removing duplicated business logic from generated code
- Redesigning APIs to work with
Span<char>
andReadOnlySpan<char>
- Removing support for old target frameworks (such as netstandard1.x and netcoreapp3.x)
- Adding support for
net8.0
Note that APIs that accept or return a StringBuilder
are being considered for removal in a future release.
What's Changed
- BUG: ICU4N.Reflection.AssemblyExtensions: Fixed bug that was causing GetCustomAttribute() not to function on net40 by @NightOwl888 in #47
- Added dependency on System.Memory and enabled Span support in net451 and netstandard2.0 by @NightOwl888 in #49
- ICU4N.Impl.ResourceKey: Removed unnecessary unsafe code from InternalSubString() method by @NightOwl888 in #50
- ICU4N.Text.ValueStringBuilder: Added AppendCodePoint() and Remove() methods + tests by @NightOwl888 in #48
- PERFORMANCE: ICU4N.Impl.LocaleIDParser: Converted to ref struct using ValueStringBuilder internally to reduce allocations by @NightOwl888 in #51
- PERFORMANCE: ICU4N.Impl.RuleCharacterIterator: Fixed bottleneck when calling Lookahead() method by @NightOwl888 in #52
- Fixed all build warnings by @NightOwl888 in #53
- BUG: ICU4N.Impl.Utility::ParseInteger(): Fixed logic to ignore case when searching for the prefix "0x" by @NightOwl888 in #58
- BUG: ICU4N.Text.ValueStringBuilder: Use FEATURE_STRING_IMPLCIT_TO_READONLYSPAN instead of NETCOREAPP by @NightOwl888 in #59
- PERFORMANCE: ICU4N.Transliterator: Converted lambda style "anonymous classes" into concrete implementations by @NightOwl888 in #60
- Converted Java array-style ref/out/return values into ref/out parameters in .NET (Fixes #57) by @NightOwl888 in #61
- Auto-generate T4 Templates (Closes #40) by @NightOwl888 in #63
- SWEEP: Changed naming convention suffix of T4 templates by @NightOwl888 in #64
- Added support for Span/ReadOnlySpan in net40 by @NightOwl888 in #68
- Dropped support for ICharSequence in favor of ReadOnlySpan/ReadOnlyMemory by @NightOwl888 in #71
- Removed .NET Standard 1.x and .NET Core 1.x build features (Fixes #72) by @NightOwl888 in #74
- Support building (some) satellite assemblies on macOS via Mono by @paulirwin in #75
- Added net8.0 target and tests (Fixes #73) by @NightOwl888 in #78
- ICU4N.Support.AnonymousComparer: Deleted because this is the same functionality as Comparer.Compare() by @NightOwl888 in #83
- ICU4N.Impl.CacheValue::SoftValue: Removed finalizer by @NightOwl888 in #84
- Rename numeric methods/types to conform with .NET conventions, #12 by @paulirwin in #76
- Normalize constants/field names in Normalizer2Impl, #11 by @paulirwin in #77
- ICU4N.Resources.csproj: Removed NETStandard.Library as a transitive dependency by @NightOwl888 in #86
- Fix for many issues with copying, naming, and loading satellite assemblies by @NightOwl888 in #88
- ICU4N.Resources: Include Newtonsoft.Json binaries so we don't conflict with consumers by @NightOwl888 in #89
- .build/dependencies.props: Added version constraint by @NightOwl888 in #90
New Contributors
- @paulirwin made their first contribution in #75
Full Changelog: v60.1.0-alpha.402...v60.1.0-alpha.436
v60.1.0-alpha.402
Known Issues
- The
ICU4N.FormatNumberRuleBased
uses the .NET formatter and replaces the ASCII digit output with native digits of the current language. This formatter doesn't support all of the features ofDecimalFormat
. Once known issue with it is that it doesn't follow the "half even" or "round toward even" rounding as is in the IEEE 754 specfication. See TR35#Rounding. Instead it rounds "toward positive infinity". To our knowledge, this only affects behavior of floating point numbers when they are larger than the value ofInt64.MaxValue
(9,223,372,036,854,775,807; that is, hexadecimal 0x7FFFFFFFFFFFFFFF) or smaller thanInt64.MinValue
(negative 9,223,372,036,854,775,808; that is, hexadecimal 0x8000000000000000), however, there may be other cases where rounding is incorrect when plural formatting is part of the rule.
Change Log
Breaking Changes
ICU4N.Impl.ResourceKey::Substring()
: Converted from start/end to startIndex/length to match .NET conventions. Optimized to useValueStringBuilder
, whereSpan<T>
is supported.ICU4N.Impl.PluralRulesLoader
+ICU4N.Text.PluralRules
: RenamedForLocale()
>GetInstance()
to match .NET naming conventions.ICU4N.Text.NumberPresentation
: MovedNumberPresentation
enum andNumberPresentationExtensions
class from theICU4N.Text
toICU4N.Globalization
namespace. Changed the values to start with 0 instead of 1 so we have a reasonable default value in .NET.ICU4N.Globalization.UCultureInfo
: RemovedClearCachedData()
method. This is in .NET only to allow it to fetch culture settings that have changed in the underlying OS.ICU4N.Text
(DisplayContext
+DisplayContextType
+DisplayContextExtensions
): Removed from the public API since they had been previously refactored in theICU4N.Globalization
namespace asCapitalization
,DialectHandling
,DisplayLength
, andSubstituteHandling
enums and theDisplayContextOptions
class.ICU4N.Text
(NumberFormat
+DecimalFormat
+RuleBasedNumberFormat
): Removed from the public API and added anIncludeLegacyNumberFormat
build property so they can be optionally compiled for those who need these features. The plan is to port the remaining frunctionality that isn't already covered byFormatNumberRuleBased
into static APIs later.ICU4N.Globalization.Capitalization
: Added "For" prefix to the names as they were in ICU4J, since this adds clarity to their intended purpose. Also explicitly specified numeric values ofCapitalization
,DialectHandling
,DisplayLength
, andSubstituteHandling
enums inICU4N.Globalization
to match ICU4J numeric values.
New Features
1.ICU4N.Impl.PatternProps
: Added WhiteSpace
static field with the same values that are matched with PatternProps.IsWhiteSpace()
for use in Trim()
method overloads.
8. Added new FormatNumberRuleBased
static class to act as the new API for the ICU4J RuleBasedNumberFormat
functionality. This API consists of extension methods for the numeric data types:
- System.Byte
- System.Int16
- System.Int32
- System.Int64
- System.Int128
- System.Numerics.BigInteger
- System.SByte
- System.IntPtr
- System.UInt16
- System.UInt32
- System.UInt64
- System.UInt128
- System.Half
- System.Single
- System.Double
- System.Decimal
ICU4N.Globalization
: AddedNumberFormatRules
class to serve as the rules engine for the Rule-based Number Format functionality. This class is immutable and thread safe. Optimized Rule-based Number Format rule description string parsing to eliminate unnecessary substring allocations.ICU4N.Text
(SplitTokenizerEnumerator
+MultiDelimiterSplitTokenizerEnumerator
): Added features to control delimiter length to exclude from the token and trim behavior for start/end/both (or specify notrimChars
for no trimming)ICU4N.Globalization
: AddedUNumberFormatInfo
class to cover the .NETNumberFormatInfo
API. This class can be instantiated and used in the same way as the .NET API.ICU4N.Globalization.UNumberFormatInfo
: AddedSpellOut
,Ordinal
,Duration
, andNumberingSystem
properties to expose the rules engines andDefaultRuleSetName
andRuleSetNames
properties publicly. These can be used to deterimine theruleSetName
to pass to theFormatNumberRuleBased
APIs.ICU4N.Globalization.UNumberFormatInfo
: AddedCapitalization
property (DisplayContext
enum in ICU4J).ICU4N
: AddedIcuNumber
internal class to serve as the business logic layer for formatting and parsing. Added formatters for long and double to output native digits + tests to confirm that they are the same as theDecimalFormat
instance that backsRuleBasedNumberFormat
. Also addedFormatPlural()
method + tests andFormatXXXRuleBased()
overloads to prepare the parameters for the call into the rules engine (NumberFormatRules
) that is passed.ICU4N.Text.ValueStringBuilder
: AddedInsert()
overload to handleReadOnlySpan<char>
- Added target for .NET 7.0. Fixed conflicts due to the new
AsReadOnly()
extension methods and build errors due the unsafe logic inPluralRules
.
Improvements
- PERFORMANCE:
ICU4N.Globalization.UCultureInfo.Name
: Cache the name locally so it doesn't have to be parsed on every request. ICU4N.Globalization.UCultureInfo::Canonicalize()
: Added null guard clauseICU4N.Impl.PluralRulesLoader
+ICU4N.Text.PluralRules
: AddedGetInstance()
overload that accepts the culture name as a string, for use by internalUCultureData
class.ICU4N.Globalization.UNumberFormatInfoTest
: Added tests to verify all cultures load decimal format settings correctly (we still have some way to go for currency data)ICU4N.Globalization.NumberPresentationExtensions
: AddedIsDefined()
method so we can quickly check for valid values in guard clauses.ICU4N.Numerics.DecimalQuantity_AbstractBCD
: Optimized number parsing usingReadOnlySpan<char>
where appropriate.- Changed the name of
FEATURE_READONLYDICTIONARY
toFEATURE_IREADONLYCOLLECTIONS
to includeIReadOnlyList<T>
. ICU4N.Globalization.NumberPresentationExtensions
: Added an internal extension method to quickly lookup theNumberingSystemRules
instance for the currentUNumberFormatInfo
.ICU4N.Globalization.UCultureInfo
: AddedReadOnly()
andClone()
implementations and added API documentation forNumberFormat
,IsReadOnly
,ReadOnly()
andClone()
members.ICU4N.Impl.ICUResourceBundle.WholeBundle
: Lazy-load theUCultureInfo
instance so we don't fill up theUCultureData
cache with all cultures and non-culture resource names.
Bug Fixes
ICU4N.Util.ResourceBundle::SetRootType()
: Fixed fallthrough to default forMissing
case
v60.1.0-alpha.401
Known Issues
- This package contains a preview of
RuleBasedBreakIterator
which has dependencies onDecimalFormat
,DecimalFormatSymbols
,NumberFormat
, andFormatter
. These will not be made public in the final release, so use these features at your own peril.
Change Log
- Changed to use official
buildTransitive
NuGet feature instead of using a viral copy of theICU4N.targets
file. This allows more options for including subsets of resource data. - Updated README.md with a Managing Resources section.
v60.1.0-alpha.400
Known Issues
- This package relies on an unofficial "viral" copy of the
ICU4N.targets
file duringdotnet pack
for the transitive dependency to be distributed to consumers. It is recommended to use v60.1.0-alpha.401 or higher, which uses the officialbuildTransitive
NuGet support. This will prevent collisions for consumers that use their ownbuild/<packageName>.targets
file. - This package contains a preview of
RuleBasedBreakIterator
which has dependencies onDecimalFormat
,DecimalFormatSymbols
,NumberFormat
, andFormatter
. These features will not be made public in the final release, so use at your own peril.
Change Log
- BREAKING: Restructured NuGet packaging and assemblies. There is now only 1 main assembly, ICU4N.dll (in the package ICU4N) and a separate NuGet package ICU4N.Resources that contains satellite assemblies. Resources are no longer included in the main assembly. This provides the following benefits:
- We can target additional frameworks without having to include additional copies of the resource data
- End users can choose to exclude resource data in distributions for languages that are not required. NOTE: The neutral language cultures contain shared resource data for specific cultures, so don't delete the neutral language file (such as
fr/ICU4N.resources.dll
unless all of the specific cultures (such asfr-CA/ICU4N.resources.dll
) are also deleted.
- Created ICU4J Resource Converter tool to transform resource files into satellite assemblies
- Updated build to generate satellite assemblies incrementally and download ICU4J JAR files during the build.
- Added tests to verify satellite assembly loading.
- Added support for loading raw resource files from the local
/data
folder if it exists. Local resource files override satellite assembly data. The structure is the same as ICU4J, excluding the top-level/impl
folder. - Updated Azure DevOps build script to run the tests in parallel background tasks.
- Added
RuleBasedNumberFormat
and dependencies + tests. NOTE: This API matches ICU4J, but we plan to build a .NET-like API to supersede this one. - BUG:
ICU4N.Support.Globalization.ResourceUtil
: Ensure resource names are converted with both forward and backward slashes. - BUG:
ICU4N.Text.MessagePattern
: useJ2N.Collections.Generic.List<T>
because theEquals()
method compares structural equality. - BUG:
ICU4N.Text.MessageFormat
: UseJ2N.Collections.Generic.Dictionary<TKey, TValue>
because this uses structural equality. - BUG:
ICU4N.Text.PluralFormat
: Corrected append length calculation. - BUG:
ICU4N.Text.MessagePattern
: Fixed 3 Append() calls to calculate the correct length - BUG:
ICU4N.Text.SelectFormat
: Corrected Append() method length calculations in 3 places - BUG:
ICU4N.Text.MessageFormat
: Corrected Append() method length calculations in 4 places - Added
net6.0
target support. ICU4N.Text.PluralRules
: addedTryParse()
overloads and made use ofReadOnlySpan<char>
to reduce allocations when loading rules. AddedSplitTokenEnumerator
andMultiCharSplitTokenEnumerator
structs to tokenize rule strings without allocating substrings.ICU4N.Impl.PluralRulesLoader
: Refactored to usePluralRules.TryParseRule()
directly instead of building a description string from the resource data only to parse the data back out again. EncapsulatedHasExplicitBoundingInfo
logic inside ofRuleList.AddRule()
so it doesn't have to be duplicated.ICU4N.Text.PluralRules.RuleList
: Refactored to use Dictionary instead of List as the underlying collection to take advantage of hashtable lookups and remove a large amount of looping code.ICU4N.Text.MessagePatternPart
: Eliminated static array allocation, since we can do a direct cast to the Enum symbol in .NET. Explicitly numberedMessagePatternArgType
symbols.Directory.Build.props
: Upgraded LangVersion to 9.0- BUG:
ICU4N.Text.CurrencyPluralInfo
: Use J2N dictionary for structural equality - Added tests for
net7.0
. - Changed test target from
net461
tonet48
.
v60.1.0-alpha.356
Change Log
- Added Source Link Support
- Added local dependency on
Microsoft.NETFramework.ReferenceAssemblies
to remove dependency on .NET Framework Targeting Pack during builds - Fixed XML documentation so it will be included in the NuGet package
- Updated build with the latest features
- Use latest SDKs for build and tests (6.0.101, 5.0.404, 3.1.416)
- Added readme.md to NuGet package
- Added target-framework-conditional support for
dependencies.props
- Added
.gitattributes
file - Added CLI build script for Windows, macOS, and Linux
- Added documentation for building, testing, releasing
- Renamed
build
directory to.build
- Added
PrintTargetFrameworks
MSBuild target to read the supported target frameworks for a given test project - Added
SkipGitVersioning
MSBuild property to remove the Nerdbank.GitVersioning NuGet package reference when creating versions via scripts - Updated
azure-pipelines.yml
to allow overriding version info using parameters
- Upgraded J2N package dependency to 2.0.0
v60.1.0-alpha.355
Change Log
- BREAKING:
ICU4N.Collation.Text.CollationElementIterator::Ingorable
: Renamed Ignorable (fixes #35) - BUG:
ICU4N.Util.VersionInfo.INVALID_VERSION_NUMBER_
: Corrected invalid version number string (fixes #36) - Upgraded to J2N 2.0.0-beta-0017
ICU4N.Support.Text.ChoiceFormat
: Fixed ambiguous reference caused by the newJ2N.Numerics.Double
class- Added tests for .NET 6.0 RC2
- Changed build to use
ubuntu-latest
andmacOS-latest
during tests - BUG:
ICU4N.Tests.Support.Globalization.UCultureInfoTest::TestDisplayKeyword()
: Test using display culture. ICU was using culture of the current thread instead, which may be different than the display culture. - BUG:
ICU4N.Support.Globalization.UCultureInfo::GetFullName()
: Fixed cache initialization issue for creating anameCache
entry ICU4N.Dev.Test.Collate.CollationServiceTest::TestRegisterFactory()
: Ignore test failures on Linux until #37 can be resolved
v60.1.0-alpha.354
Change Log
- BUG: Fixed infinite recursion issue when using the locales
zh-CN
,zh-HK
,zh-MO
,zh-SG
,zh-TW
(Fixes #29). - Added
Lazy<T>
to make GetOrAdd() method calls atomic (Fixes #31). - Added test targets for x86 on all target frameworks.
- Upgraded to J2N 2.0.0-beta-0012
- Upgraded to Nerdbank.GitVersioning 3.3.37
- Added tests for .NET 5.0
- Removed support for .NET Standard 1.3
- Downgraded Microsoft.Extensions.Caching.Memory to 2.0.0
v60.1.0-alpha.353
Change Log
- apache/lucenenet#343: Fixed configuration of NuGet package so the
LICENSE.txt
and icon files are in the root of the NuGet package, not in thecontent
directory
v60.1.0-alpha.352
This release contains impactful performance improvements.
Change Log
ICU4N.Support.Collections
: Factored outListExtensions
and movedCopyTo
method to J2N- PERFORMANCE: Swapped in J2N's optimized
ICollection<T>.ToArray()
method where appropriate - PERFORMANCE:
ICU4N.TestFramework
: FixedTestBoilerplate.GetSet()
method so it doesn't lookup a value in every loop from the same dictionary it is iterating over - PERFORMANCE:
ICU4N.Text.UTF16Extension::CharAt()
: FixedStringBuilder
overload to copy out the characters it is analyzing to an array, since the indexer of the .NETStringBuilder
is extremely slow. - PERFORMANCE: Replaced
BitArray
withBitSet
inBreakIterator
andNormalizer
- PERFORMANCE: Fixed
HashSet<T>
capacity allocation with J2N'sHashSet<T>
, which has a capacity constructor overload on all target platforms - PERFORMANCE:
ICU4N.Impl.ICUResourceBundle
: Removed extraHashSet
for tracking unique values, since the existing list can be utilized for that without the extra memory allocations and operations - PERFORMANCE: Swapped in J2N's
HashSet<T>
in other appropriate places ICU4N.TestFramework
: Added implicit operator support forCharacter
,Integer
,Long
, andDouble
classes- PERFORMANCE: Factored out
IDictionary<TKey, TValue>.Get(TKey)
extension method in favor ofIDictionary.TryGetValue(TKey, out TValue)
where a performance advantage can be gained - PERFORMANCE: Added asserts overloads for generic collection types and
UnicodeSet
- PERFORMANCE:
ICU4N.Tests.Transliterator
: OptimizedUnicodeMapTest
by replacingInteger
reference type withint
- PERFORMANCE:
ICU4N.Text.UTF16Extension.tt
: Updated code generation to create a special case overload forStringBuilder
, whose indexer is extremely slow in .NET - PERFORMANCE: Changed
ICU4N.Text.ReplaceableString
implementation to cache a copy of the string in theStringBuilder
, since theChar32At()
method needs to index into the characters and astring
is much faster thanStringBuilder
. The cached string is updated whenever a change is made through theReplaceableString
API or if theStringBuilder
it wraps changes inLength
orGetHashCode()
or whenReplaceableString.ToString()
is called. - PERFORMANCE:
ICU4N.Collation.Impl.Coll.CollationDataBuilder
: Changed to useString.IndexOf()
which performs far better thanStringBuilderExtensions.IndexOf()
- PERFORMANCE:
ICU4N.Tests.Collation
: UpdatedCounter
class to useInterlocked
rather than a lock - PERFORMANCE:
ICU4N.Impl.ICUNotifier
: Updated to use aQueue<T>
rather thanList<T>
- PERFORMANCE: Use
LazyInitializer
throughout the project to load data rather than using a lock and volatile member - PERFORMANCE: Changed classes where appropriate to use a lock object instead of
lock (this)
- PERFORMANCE:
ICU4N.Globalization.UCharacterNameIterator
: Removed unnecessary redundant lock - PERFORMANCE:
ICU4N.Util.VersionInfo
: UseConcurrentDictionary
and remove locking - PERFORMANCE:
ICU4N.Transliterator
: Use lock object,LazyInitializer
, andConcurrentDictionary
where appropriate to avoidlock (this)
- Changed properties to use expression-style syntax, where appropriate
- PERFORMANCE: Optimized empty collection creation
- PERFORMANCE: Eliminated
InvalidCastException
s and created if-then blocks that test the type compatibility instead - PERFORMANCE: Implmentd
GetHashCode()
where it was "not designed" in the original implementation - BREAKING:
ICU4N.Util.UResourceBundle
: ChangedGetLocaleID()
andGetBaseName()
to propertiesLocaleID
andBaseName
ICU4N.Tests.Collation.Dev.Test.Util.ICUResourceBundleCollationTest
: EnabledTestFunctionalEquivalent()
test, as it now passesICU4N.Tests.Dev.Test.Rbbi.RBBITestExtended::TestExtended()
: Enabled the test, as it now passesICU4N.Impl.ICUService
: Fixed broken reference in XML doc comment- Ugraded to J2N 2.0.0-beta-0009
v60.1.0-alpha.351
Change Log
- BREAKING: Moved
LocaleIDParser
,LocaleIDs
, andLocaleUtility
toICU4N.Globalization
namespace ICU4N.Support.Collections
: Deleted unneeded GenericComparer and swapped in the implementation from J2N.- BREAKING:
ICU4N.Impl.ICULocaleService
: RefactoredGet()
andGetKey()
overloads to use out parameters rather than passing in single dimensional arrays (Java has no out parameters, so this was a workaround in ICU4J) - Upgraded to J2N 2.0.0-beta-0008
- Upgraded to Nerdbank.GitVersioning 3.0.28