Skip to content

Commit

Permalink
Converted Java array-style ref/out/return values into ref/out paramet…
Browse files Browse the repository at this point in the history
…ers in .NET (Fixes #57) (#61)

* BREAKING: ICU4N.Impl.Utility::ParseInteger(): Converted pos parameter from array to ref int

* BREAKING: ICU4N.Impl.Utility::ParseUnicodeIdentifier(): Converted pos parameter from int[] to ref int (see #57)

* BREAKING: ICU4N.Impl.Utility::ParseNumber(): Changed pos parameter from int[] to ref int (see #57)

* BREAKING: ICU4N.Impl.Utility (EncodeRun + AppendEncodedByte): Converted fixed length state parameter to ref byte state0 and ref byte state1 (see #57)

* BREAKING: ICU4N.Impl.Utility::ParseChar(): Converted pos parameter from int[] to ref int (see #57)

* ICU4N.Transliterator.Text.TransliteratorIDParser (ParseFilterID() + ParseSingleID() + ParseGlobalFilter()): Changed pos parameter from int[] to ref int (see #57)

* ICU4N.Transliterator.Text.TransliteratorIDParser::ParseGlobalFilter(): Changed withParens parameter from int[] to ref int (see #57). Note that this could be cleaned up further (separate input and output parameters), but since it is in an internal type there is no need.

* ICU4N.Transliterator.Text.TransliteratorIDParser::ParseCompoundID(): Changed globalFilter parameter from UnicodeSet[] to out UnicodeSet (see #57)

* BREAKING: ICU4N.Text.IUnicodeMatcher::Matches(): Changed offset parameter from int[] to ref int (see #57)

* BREAKING: ICU4N.Text.IUnicodeReplacer::Replace(): Changed cursor parameter from int[] to out int (see #57)

* BREAKING: ICU4N.Impl.ICUResourceBundle::GetFunctionalEquivalent() + ICU4N.Text.Collator::GetFunctionalEquivalent(): Changed isAvailable parameter from bool[] to out bool (see #57)

* BREAKING: ICU4N.Impl.Int32TrieBuilder::GetValue(): Changed inBlockZero parameter from bool[] to out bool. There is already an overload that allows omitting the inBlockZero parameter. See #57.

* ICU4N.Text.DictionaryMatcher::Matches(): Changed count parameter from int[] to out int (see #57).

* ICU4N.Globalization.UCultureInfo::ParseTagString(): Converted tags string array parameter to out parameters for language, script, and region (see #57)

* ICU4N.Impl.Grego::FloorDivide(): Changed remainder parameter from long[] to out long (see #57)

* BREAKING: ICU4N.Impl.Grego (DayToFields() + TimeToFields()): Changed "fields" parameter from an int[] to individual out parameters for year, month, dayOfMonth, dayOfWeek, dayOfYear, and millisecondOfDay and changed return value to void

* ICU4N.Impl.UCharacterName::AddGroupName(): Changed return array to out parameters and eliminated extra array member variable (see #57)

* .build/nowarn.props: Disabled LuceneDev1003 and LuceneDev1004 warnings for all projects

* ICU4N.Text.TransliteratorIDParser::IDtoSTV(): Converted return array to out parameters
  • Loading branch information
NightOwl888 authored Nov 23, 2023
1 parent c3d79dd commit 2afe428
Show file tree
Hide file tree
Showing 31 changed files with 481 additions and 459 deletions.
4 changes: 4 additions & 0 deletions .build/nowarn.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@
<PropertyGroup Label="Warnings to be Disabled in All Projects">
<!-- This warning seems to be a false warning and a duplicate of CS8618, except it is not being affected by the MemberNotNullAttribute -->
<NoWarn Label="Member must have a non-null value when exiting.">$(NoWarn);CS8774</NoWarn>

<!-- These have been reviewed, but if more of ICU is ported from Java we may need to review again -->
<NoWarn Label="Method parameters that accept array types should be analyzed">$(NoWarn);LuceneDev1003</NoWarn>
<NoWarn Label="Method parameters that return array types should be analyzed">$(NoWarn);LuceneDev1004</NoWarn>
</PropertyGroup>
</Project>
14 changes: 7 additions & 7 deletions src/ICU4N.Collation/Text/Collator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1306,18 +1306,17 @@ public override void Put(ResourceKey key, ResourceValue value, bool noFallback)
/// </summary>
/// <param name="keyword">A particular keyword as enumerated by <see cref="Keywords"/>.</param>
/// <param name="locID">The requested locale</param>
/// <param name="isAvailable">If non-null, <paramref name="isAvailable"/>[0] will receive and
/// <param name="isAvailable">OUTPUT parameter that will
/// output boolean that indicates whether the requested locale was
/// 'available' to the collation service. If non-null, <paramref name="isAvailable"/>
/// must have length &gt;= 1.</param>
/// 'available' to the collation service.</param>
/// <returns>the locale</returns>
/// <stable>ICU 3.0</stable>
public static UCultureInfo GetFunctionalEquivalent(string keyword,
UCultureInfo locID,
bool[] isAvailable)
out bool isAvailable) // ICU4N: Changed isAvalable from bool[] to out bool
{
return ICUResourceBundle.GetFunctionalEquivalent(BASE, ICUResourceBundle.IcuDataAssembly, RESOURCE,
keyword, locID, isAvailable, true);
keyword, locID, out isAvailable, true);
}

/// <summary>
Expand All @@ -1328,12 +1327,13 @@ public static UCultureInfo GetFunctionalEquivalent(string keyword,
/// <param name="keyword">a particular keyword as enumerated by <see cref="Keywords"/>.</param>
/// <param name="locID">The requested locale</param>
/// <returns>the locale</returns>
/// <seealso cref="GetFunctionalEquivalent(string, UCultureInfo, bool[])"/>
/// <seealso cref="GetFunctionalEquivalent(string, UCultureInfo, out bool)"/>
/// <stable>ICU 3.0</stable>
public static UCultureInfo GetFunctionalEquivalent(string keyword,
UCultureInfo locID)
{
return GetFunctionalEquivalent(keyword, locID, null);
return ICUResourceBundle.GetFunctionalEquivalent(BASE, ICUResourceBundle.IcuDataAssembly, RESOURCE,
keyword, locID, true);
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions src/ICU4N.Transliterator/Text/FunctionReplacer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ public FunctionReplacer(Transliterator transliterator,
public virtual int Replace(IReplaceable text,
int start,
int limit,
int[] cursor)
out int cursor) // ICU4N: Changed cursor parameter from int[] to out int
{

// First delegate to subordinate replacer
int len = replacer.Replace(text, start, limit, cursor);
int len = replacer.Replace(text, start, limit, out cursor);
limit = start + len;

// Now transliterate
Expand Down
38 changes: 20 additions & 18 deletions src/ICU4N.Transliterator/Text/StringMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@ public StringMatcher(string theString,
/// <summary>
/// Implement <see cref="IUnicodeMatcher"/>
/// </summary>
// ICU4N: Converted offset from int[] to ref int
public virtual MatchDegree Matches(IReplaceable text,
int[] offset,
ref int offset,
int limit,
bool incremental)
{
Expand All @@ -107,8 +108,8 @@ public virtual MatchDegree Matches(IReplaceable text,
// always in the BMP and because we are doing a literal match
// operation, which can be done 16-bits at a time.
int i;
int[] cursor = new int[] { offset[0] };
if (limit < cursor[0])
int cursor = offset;
if (limit < cursor)
{
// Match in the reverse direction
for (i = pattern.Length - 1; i >= 0; --i)
Expand All @@ -117,10 +118,10 @@ public virtual MatchDegree Matches(IReplaceable text,
IUnicodeMatcher subm = data.LookupMatcher(keyChar);
if (subm == null)
{
if (cursor[0] > limit &&
keyChar == text[cursor[0]])
if (cursor > limit &&
keyChar == text[cursor])
{ // OK; see note (1) above
--cursor[0];
--cursor;
}
else
{
Expand All @@ -130,7 +131,7 @@ public virtual MatchDegree Matches(IReplaceable text,
else
{
MatchDegree m =
subm.Matches(text, cursor, limit, incremental);
subm.Matches(text, ref cursor, limit, incremental);
if (m != MatchDegree.Match)
{
return m;
Expand All @@ -142,15 +143,15 @@ public virtual MatchDegree Matches(IReplaceable text,
// exist -- we want the rightmost match.
if (matchStart < 0)
{
matchStart = cursor[0] + 1;
matchLimit = offset[0] + 1;
matchStart = cursor + 1;
matchLimit = offset + 1;
}
}
else
{
for (i = 0; i < pattern.Length; ++i)
{
if (incremental && cursor[0] == limit)
if (incremental && cursor == limit)
{
// We've reached the context limit without a mismatch and
// without completing our match.
Expand All @@ -163,10 +164,10 @@ public virtual MatchDegree Matches(IReplaceable text,
// Don't need the cursor < limit check if
// incremental is true (because it's done above); do need
// it otherwise.
if (cursor[0] < limit &&
keyChar == text[cursor[0]])
if (cursor < limit &&
keyChar == text[cursor])
{ // OK; see note (1) above
++cursor[0];
++cursor;
}
else
{
Expand All @@ -176,19 +177,19 @@ public virtual MatchDegree Matches(IReplaceable text,
else
{
MatchDegree m =
subm.Matches(text, cursor, limit, incremental);
subm.Matches(text, ref cursor, limit, incremental);
if (m != MatchDegree.Match)
{
return m;
}
}
}
// Record the match position
matchStart = offset[0];
matchLimit = cursor[0];
matchStart = offset;
matchLimit = cursor;
}

offset[0] = cursor[0];
offset = cursor;
return MatchDegree.Match;
}

Expand Down Expand Up @@ -271,8 +272,9 @@ public virtual void AddMatchSetTo(UnicodeSet toUnionTo)
public virtual int Replace(IReplaceable text,
int start,
int limit,
int[] cursor)
out int cursor) // ICU4N: Changed cursor parameter from int[] to out int
{
cursor = 0;
int outLen = 0;

// Copy segment with out-of-band data
Expand Down
13 changes: 7 additions & 6 deletions src/ICU4N.Transliterator/Text/StringReplacer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ internal class StringReplacer : IUnicodeReplacer
/// text and sets the cursor to the given position.
/// </summary>
/// <param name="theOutput">Text that will replace input text when the
/// <see cref="Replace(IReplaceable, int, int, int[])"/> method is called. May contain stand-in characters
/// <see cref="Replace(IReplaceable, int, int, out int)"/> method is called. May contain stand-in characters
/// that represent nested replacers.</param>
/// <param name="theCursorPos">Cursor position that will be returned by
/// the <see cref="Replace(IReplaceable, int, int, int[])"/> method.</param>
/// the <see cref="Replace(IReplaceable, int, int, out int)"/> method.</param>
/// <param name="theData">Transliterator context object that translates
/// stand-in characters to <see cref="IUnicodeReplacer"/> objects.</param>
public StringReplacer(string theOutput,
Expand All @@ -76,7 +76,7 @@ public StringReplacer(string theOutput,
/// text and does not modify the cursor.
/// </summary>
/// <param name="theOutput">Text that will replace input text when the
/// <see cref="Replace(IReplaceable, int, int, int[])"/> method is called.
/// <see cref="Replace(IReplaceable, int, int, out int)"/> method is called.
/// May contain stand-in characters that represent nested replacers.</param>
/// <param name="theData">Transliterator context object that translates
/// stand-in characters to <see cref="IUnicodeReplacer"/> objects.</param>
Expand Down Expand Up @@ -111,8 +111,9 @@ public StringReplacer(string theOutput,
public virtual int Replace(IReplaceable text,
int start,
int limit,
int[] cursor)
out int cursor) // ICU4N: Changed cursor parameter from int[] to out int
{
cursor = 0;
int outLen;
int newStart = 0;

Expand Down Expand Up @@ -212,7 +213,7 @@ public virtual int Replace(IReplaceable text,
}

// Delegate output generation to replacer object
int len = r.Replace(text, destLimit, destLimit, cursor);
int len = r.Replace(text, destLimit, destLimit, out cursor);
destLimit += len;
}
oOutput = nextIndex;
Expand Down Expand Up @@ -276,7 +277,7 @@ public virtual int Replace(IReplaceable text,
newStart += start;
}

cursor[0] = newStart;
cursor = newStart;
}

return outLen;
Expand Down
21 changes: 10 additions & 11 deletions src/ICU4N.Transliterator/Text/TransliterationRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ public virtual MatchDegree MatchAndReplace(IReplaceable text,
}

int keyLimit;
int[] intRef = new int[1];
int intRef;

// ------------------------ Ante Context ------------------------

Expand All @@ -426,18 +426,18 @@ public virtual MatchDegree MatchAndReplace(IReplaceable text,
MatchDegree match;

// Start reverse match at char before pos.start
intRef[0] = PosBefore(text, position.Start);
intRef = PosBefore(text, position.Start);

if (anteContext != null)
{
match = anteContext.Matches(text, intRef, anteLimit, false);
match = anteContext.Matches(text, ref intRef, anteLimit, false);
if (match != MatchDegree.Match)
{
return MatchDegree.Mismatch;
}
}

oText = intRef[0];
oText = intRef;

minOText = PosAfter(text, oText);

Expand All @@ -450,18 +450,18 @@ public virtual MatchDegree MatchAndReplace(IReplaceable text,

// -------------------- Key and Post Context --------------------

intRef[0] = position.Start;
intRef = position.Start;

if (key != null)
{
match = key.Matches(text, intRef, position.Limit, incremental);
match = key.Matches(text, ref intRef, position.Limit, incremental);
if (match != MatchDegree.Match)
{
return match;
}
}

keyLimit = intRef[0];
keyLimit = intRef;

if (postContext != null)
{
Expand All @@ -474,14 +474,14 @@ public virtual MatchDegree MatchAndReplace(IReplaceable text,
return MatchDegree.PartialMatch;
}

match = postContext.Matches(text, intRef, position.ContextLimit, incremental);
match = postContext.Matches(text, ref intRef, position.ContextLimit, incremental);
if (match != MatchDegree.Match)
{
return match;
}
}

oText = intRef[0];
oText = intRef;

// ------------------------- Stop Anchor ------------------------

Expand All @@ -502,9 +502,8 @@ public virtual MatchDegree MatchAndReplace(IReplaceable text,
// We have a full match. The key is between pos.start and
// keyLimit.

int newLength = output.Replace(text, position.Start, keyLimit, intRef);
int newLength = output.Replace(text, position.Start, keyLimit, out int newStart);
int lenDelta = newLength - (keyLimit - position.Start);
int newStart = intRef[0];

oText += lenDelta;
position.Limit += lenDelta;
Expand Down
29 changes: 15 additions & 14 deletions src/ICU4N.Transliterator/Text/Transliterator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1301,16 +1301,18 @@ public static string GetDisplayName(string id, UCultureInfo inLocale)
GetBundleInstance(ICUData.IcuTransliteratorBaseName, inLocale, ICUResourceBundle.IcuDataAssembly);

// Normalize the ID
string[] stv = TransliteratorIDParser.IDtoSTV(id);
if (stv == null)
TransliteratorIDParser.IDtoSTV(id, out string source, out string target, out string variant, out bool _);
// ICU4N specific - since we are not returning an array, it cannot be null (and it was never null anyway)

// ICU4N specific - use Concat
string ID;
if (!string.IsNullOrEmpty(variant))
{
// No target; malformed id
return "";
ID = string.Concat(source, "-", target, "/", variant);
}
string ID = stv[0] + '-' + stv[1];
if (stv[2] != null && stv[2].Length > 0)
else
{
ID = ID + '/' + stv[2];
ID = string.Concat(source, "-", target);
}

// Use the registered display name, if any
Expand All @@ -1335,7 +1337,7 @@ public static string GetDisplayName(string id, UCultureInfo inLocale)
bundle.GetString(RB_DISPLAY_NAME_PATTERN));

// Construct the argument array
object[] args = new object[] { 2, stv[0], stv[1] };
object[] args = new object[] { 2, source, target };

// Use display names for the scripts, if they exist
for (int j = 1; j <= 2; ++j)
Expand All @@ -1349,8 +1351,8 @@ public static string GetDisplayName(string id, UCultureInfo inLocale)
}

// Format it using the pattern in the resource
return (stv[2].Length > 0) ?
(format.Format(args) + '/' + stv[2]) :
return (variant.Length > 0) ?
(format.Format(args) + '/' + variant) :
format.Format(args);
}
catch (MissingManifestResourceException) { }
Expand Down Expand Up @@ -1429,8 +1431,7 @@ public static Transliterator GetInstance(string id,
{
StringBuffer canonID = new StringBuffer();
IList<SingleID> list = new List<SingleID>();
UnicodeSet[] globalFilter = new UnicodeSet[1];
if (!TransliteratorIDParser.ParseCompoundID(id, dir, canonID, list, globalFilter))
if (!TransliteratorIDParser.ParseCompoundID(id, dir, canonID, list, out UnicodeSet globalFilter)) // ICU4N: Changed globalFilter from UnicodeSet[] to out UnicodeSet
{
throw new ArgumentException("Invalid ID " + id);
}
Expand All @@ -1454,9 +1455,9 @@ public static Transliterator GetInstance(string id,
}

t.ID = canonID.ToString();
if (globalFilter[0] != null)
if (globalFilter != null)
{
t.Filter = globalFilter[0];
t.Filter = globalFilter;
}
return t;
}
Expand Down
Loading

0 comments on commit 2afe428

Please sign in to comment.