Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intrinsic arithmetic function overloads #8710

Merged
merged 29 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
202755b
Support long and double for arithmetic operator functions
jrdodds Apr 26, 2023
d6b87e8
Merge branch 'dotnet:main' into IntrinsicFunctionsOverload
jrdodds Apr 26, 2023
d01d30e
added argument that exceeds the size of long
jrdodds Apr 26, 2023
eb2d53f
use a const char for the decimal separator
jrdodds Apr 28, 2023
68b71d6
Support comparison when the lhs is an integer
jrdodds Apr 28, 2023
a5375f3
Order members by TypeCode; add tests and ChangeWave
jrdodds May 6, 2023
16670c7
Add change wave to fast path
jrdodds May 6, 2023
78ba51f
Merge remote-tracking branch 'upstream/main' into IntrinsicFunctionsO…
jrdodds May 6, 2023
7de86f0
add property in Expander_Tests; rename in other classes
jrdodds May 6, 2023
49b0afd
reduce code repetition; try double if long fails in the same method
jrdodds May 10, 2023
792e61a
modify TryConvertToLong to check long min/max values before convertin…
jrdodds May 11, 2023
333f242
modify TryConvertToInt to check int min/max before converting to double
jrdodds May 11, 2023
278e381
Merge branch 'dotnet:main' into IntrinsicFunctionsOverload
jrdodds May 12, 2023
6369e80
change access to TryConvertToInt, TryConvertToLong, TryConvertToDoubl…
jrdodds May 20, 2023
e1e705f
chnages to rely on TryParse
jrdodds May 20, 2023
0f6ed65
modify test TryConvertToLongGivenDoubleWithLongMaxValue for Apple Sil…
jrdodds May 21, 2023
de36cf0
Merge branch 'dotnet:main' into IntrinsicFunctionsOverload
jrdodds May 21, 2023
158e6e6
cache comparer for arithmetic overloads
jrdodds May 22, 2023
f2cb002
change to use Type.FindMembers and Array.Sort
jrdodds May 22, 2023
824825b
add comment
jrdodds May 23, 2023
f64fa81
update TryParse to use invariant culture
jrdodds May 25, 2023
2339681
change to accept thousands separator and add test for different locale
jrdodds May 29, 2023
3d66331
use InvariantCulture with double.TryParse
jrdodds Jun 7, 2023
22f8684
add comments
jrdodds Jun 7, 2023
e1c7115
fix IDE0005 error that is not reported in local builds
jrdodds Jun 7, 2023
6d15f2f
Merge branch 'dotnet:main' into IntrinsicFunctionsOverload
jrdodds Jun 7, 2023
4f21730
revert unintended whitespace formatting
jrdodds Jun 8, 2023
65cea2f
Merge branch 'dotnet:main' into IntrinsicFunctionsOverload
jrdodds Jun 27, 2023
19b5039
fix nullable errors after merge
jrdodds Jun 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
96 changes: 85 additions & 11 deletions src/Build.UnitTests/Evaluation/Expander_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class Expander_Tests
private string _dateToParse = new DateTime(2010, 12, 25).ToString(CultureInfo.CurrentCulture);
private static readonly string s_rootPathPrefix = NativeMethodsShared.IsWindows ? "C:\\" : Path.VolumeSeparatorChar.ToString();

private static bool IsIntrinsicFunctionOverloadsEnabled => ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_8);

[Fact]
public void ExpandAllIntoTaskItems0()
{
Expand Down Expand Up @@ -3394,12 +3396,6 @@ public void PropertyFunctionStaticMethodIntrinsicMaths()
result = expander.ExpandIntoStringLeaveEscaped(@"$([MSBuild]::Modulo(2345.5, 43))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance);

Assert.Equal((2345.5 % 43).ToString(), result);

// test for overflow wrapping
result = expander.ExpandIntoStringLeaveEscaped(@"$([MSBuild]::Add(9223372036854775807, 20))", ExpanderOptions.ExpandProperties, MockElementLocation.Instance);

double expectedResult = 9223372036854775807D + 20D;
Assert.Equal(expectedResult.ToString(), result);
jrdodds marked this conversation as resolved.
Show resolved Hide resolved
}

/// <summary>
Expand Down Expand Up @@ -3693,13 +3689,21 @@ public void Medley()
new string[] {"$([MSBuild]::Add(1,2).CompareTo(3))", "0"},
new string[] {"$([MSBuild]::Add(1,2).CompareTo(3))", "0"},
new string[] {"$([MSBuild]::Add(1,2).CompareTo(3.0))", "0"},
new string[] {"$([MSBuild]::Add(1,2.0).CompareTo(3.0))", "0"},
new string[] {"$([System.Convert]::ToDouble($([MSBuild]::Add(1,2))).CompareTo(3.0))", "0"},
new string[] {"$([MSBuild]::Add(1,2).CompareTo('3'))", "0"},
new string[] {"$([MSBuild]::Add(1,2).CompareTo(3.1))", "-1"},
new string[] {"$([MSBuild]::Add(1,2.0).CompareTo(3.1))", "-1"},
new string[] {"$([System.Convert]::ToDouble($([MSBuild]::Add(1,2))).CompareTo(3.1))", "-1"},
new string[] {"$([MSBuild]::Add(1,2).CompareTo(2))", "1"},
new string[] {"$([MSBuild]::Add(1,2).Equals(3))", "True"},
new string[] {"$([MSBuild]::Add(1,2).Equals(3.0))", "True"},
new string[] {"$([MSBuild]::Add(1,2.0).Equals(3.0))", "True"},
new string[] {"$([System.Convert]::ToDouble($([MSBuild]::Add(1,2))).Equals(3.0))", "True"},
new string[] {"$([MSBuild]::Add(1,2).Equals('3'))", "True"},
new string[] {"$([MSBuild]::Add(1,2).Equals(3.1))", "False"},
new string[] {"$([MSBuild]::Add(1,2.0).Equals(3.1))", "False"},
new string[] {"$([System.Convert]::ToDouble($([MSBuild]::Add(1,2))).Equals(3.1))", "False"},
new string[] {"$(a.Insert(0,'%28'))", "%28no"},
new string[] {"$(a.Insert(0,'\"'))", "\"no"},
new string[] {"$(a.Insert(0,'(('))", "%28%28no"},
Expand Down Expand Up @@ -4176,39 +4180,109 @@ public void PropertyFunctionMathMin()
}

[Fact]
public void PropertyFunctionMSBuildAdd()
public void PropertyFunctionMSBuildAddIntegerLiteral()
{
TestPropertyFunction("$([MSBuild]::Add($(X), 5))", "X", "7", "12");
}

[Fact]
public void PropertyFunctionMSBuildAddRealLiteral()
{
TestPropertyFunction("$([MSBuild]::Add($(X), 0.5))", "X", "7", "7.5");
}

[Fact]
public void PropertyFunctionMSBuildAddIntegerOverflow()
{
// Overflow wrapping - result exceeds size of long
string expected = IsIntrinsicFunctionOverloadsEnabled ? "-9223372036854775808" : (long.MaxValue + 1.0).ToString();
TestPropertyFunction("$([MSBuild]::Add($(X), 1))", "X", long.MaxValue.ToString(), expected);
}

jrdodds marked this conversation as resolved.
Show resolved Hide resolved
[Fact]
public void PropertyFunctionMSBuildAddRealArgument()
{
// string argument is an integer that exceeds the size of long.
double value = long.MaxValue + 1.0;
double expected = value + 1.0;
TestPropertyFunction("$([MSBuild]::Add($(X), 1))", "X", value.ToString(), expected.ToString());
}

[Fact]
public void PropertyFunctionMSBuildAddComplex()
{
TestPropertyFunction("$([MSBuild]::Add($(X), $([MSBuild]::Add(2, 3))))", "X", "7", "12");
}

[Fact]
public void PropertyFunctionMSBuildSubtract()
public void PropertyFunctionMSBuildSubtractIntegerLiteral()
{
TestPropertyFunction("$([MSBuild]::Subtract($(X), 20100000))", "X", "20100042", "42");
}

[Fact]
public void PropertyFunctionMSBuildMultiply()
public void PropertyFunctionMSBuildSubtractRealLiteral()
{
TestPropertyFunction("$([MSBuild]::Subtract($(X), 20100000.0))", "X", "20100042", "42");
}

[Fact]
public void PropertyFunctionMSBuildSubtractIntegerMaxValue()
{
// If the double overload is used, there will be a rounding error.
string expected = IsIntrinsicFunctionOverloadsEnabled ? "1" : "0";
TestPropertyFunction("$([MSBuild]::Subtract($(X), 9223372036854775806))", "X", long.MaxValue.ToString(), expected);
}

[Fact]
public void PropertyFunctionMSBuildMultiplyIntegerLiteral()
{
TestPropertyFunction("$([MSBuild]::Multiply($(X), 8800))", "X", "2", "17600");
}

[Fact]
public void PropertyFunctionMSBuildMultiplyRealLiteral()
{
TestPropertyFunction("$([MSBuild]::Multiply($(X), 1.5))", "X", "2", "3");
}

[Fact]
public void PropertyFunctionMSBuildMultiplyIntegerOverflow()
{
// Overflow - result exceeds size of long
string expected = IsIntrinsicFunctionOverloadsEnabled ? "-2" : (long.MaxValue * 2.0).ToString();
TestPropertyFunction("$([MSBuild]::Multiply($(X), 2))", "X", long.MaxValue.ToString(), expected);
}

[Fact]
public void PropertyFunctionMSBuildMultiplyComplex()
{
TestPropertyFunction("$([MSBuild]::Multiply($(X), $([MSBuild]::Multiply(1, 8800))))", "X", "2", "17600");
}

[Fact]
public void PropertyFunctionMSBuildDivide()
public void PropertyFunctionMSBuildDivideIntegerLiteral()
{
string expected = IsIntrinsicFunctionOverloadsEnabled ? "6" : "6.5536";
TestPropertyFunction("$([MSBuild]::Divide($(X), 10000))", "X", "65536", expected);
}

[Fact]
public void PropertyFunctionMSBuildDivideRealLiteral()
{
TestPropertyFunction("$([MSBuild]::Divide($(X), 10000.0))", "X", "65536", "6.5536");
}

[Fact]
public void PropertyFunctionMSBuildModuloIntegerLiteral()
{
TestPropertyFunction("$([MSBuild]::Modulo($(X), 3))", "X", "10", "1");
}

[Fact]
public void PropertyFunctionMSBuildModuloRealLiteral()
{
TestPropertyFunction("$([MSBuild]::Divide($(X), 10000))", "X", "65536", (6.5536).ToString());
TestPropertyFunction("$([MSBuild]::Modulo($(X), 3.0))", "X", "10", "1");
}

[Fact]
Expand Down