diff --git a/src/System.Management.Automation/engine/LanguagePrimitives.cs b/src/System.Management.Automation/engine/LanguagePrimitives.cs index 54a9d568455..50b2e7950f7 100644 --- a/src/System.Management.Automation/engine/LanguagePrimitives.cs +++ b/src/System.Management.Automation/engine/LanguagePrimitives.cs @@ -14,6 +14,7 @@ using System.Management.Automation.Internal; using System.Management.Automation.Language; using System.Management.Automation.Runspaces; +using System.Numerics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; @@ -3307,6 +3308,11 @@ private static string ConvertNumericToString(object valueToConvert, return sgl.ToString(SinglePrecision, numberFormat); } + if (valueToConvert is BigInteger b) + { + return b.ToString(numberFormat); + } + return (string)Convert.ChangeType(valueToConvert, resultType, CultureInfo.InvariantCulture.NumberFormat); } catch (Exception e) @@ -4380,7 +4386,8 @@ internal static ConversionRank GetConversionRank(Type fromType, Type toType) typeof(Int16), typeof(Int32), typeof(Int64), typeof(UInt16), typeof(UInt32), typeof(UInt64), typeof(sbyte), typeof(byte), - typeof(Single), typeof(double), typeof(decimal) + typeof(Single), typeof(double), typeof(decimal), + typeof(BigInteger) }; private static Type[] s_integerTypes = new Type[] { diff --git a/src/System.Management.Automation/engine/parser/Compiler.cs b/src/System.Management.Automation/engine/parser/Compiler.cs index 229aa3a5887..ac40050d4ab 100644 --- a/src/System.Management.Automation/engine/parser/Compiler.cs +++ b/src/System.Management.Automation/engine/parser/Compiler.cs @@ -4171,7 +4171,9 @@ public object VisitCommand(CommandAst commandAst) private Expression GetCommandArgumentExpression(CommandElementAst element) { var constElement = element as ConstantExpressionAst; - if (constElement != null && LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constElement.StaticType))) + if (constElement != null + && (LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constElement.StaticType)) + || constElement.StaticType == typeof(System.Numerics.BigInteger))) { var commandArgumentText = constElement.Extent.Text; if (!commandArgumentText.Equals(constElement.Value.ToString(), StringComparison.Ordinal)) diff --git a/src/System.Management.Automation/engine/runtime/ScriptBlockToPowerShell.cs b/src/System.Management.Automation/engine/runtime/ScriptBlockToPowerShell.cs index 66b5f63da82..e2409eba626 100644 --- a/src/System.Management.Automation/engine/runtime/ScriptBlockToPowerShell.cs +++ b/src/System.Management.Automation/engine/runtime/ScriptBlockToPowerShell.cs @@ -643,7 +643,9 @@ private void ConvertCommand(CommandAst commandAst, bool isTrustedInput) { var constantExprAst = ast as ConstantExpressionAst; object argument; - if (constantExprAst != null && LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constantExprAst.StaticType))) + if (constantExprAst != null + && (LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constantExprAst.StaticType)) + || constantExprAst.StaticType == typeof(System.Numerics.BigInteger))) { var commandArgumentText = constantExprAst.Extent.Text; argument = constantExprAst.Value; diff --git a/test/powershell/Language/Parser/ParameterBinding.Tests.ps1 b/test/powershell/Language/Parser/ParameterBinding.Tests.ps1 index a480997271f..7fd26912ead 100644 --- a/test/powershell/Language/Parser/ParameterBinding.Tests.ps1 +++ b/test/powershell/Language/Parser/ParameterBinding.Tests.ps1 @@ -425,3 +425,44 @@ Describe "Custom type conversion in parameter binding" -Tags 'Feature' { } } } + +Describe 'Roundtrippable Conversions for Bare-string Numeric Literals passed to [string] Parameters' -Tags CI { + + BeforeAll { + $TestValues = @( + @{ Argument = "34uy" } + @{ Argument = "48y" } + @{ Argument = "8s" } + @{ Argument = "49us" } + @{ Argument = "26" } + @{ Argument = "28u" } + @{ Argument = "24l" } + @{ Argument = "32ul" } + @{ Argument = "20d" } + @{ Argument = "6n" } + ) + + function Test-SimpleStringValue([string] $Value) { $Value } + function Test-AdvancedStringValue { + [CmdletBinding()] + param( + [string] + $Value + ) + + $Value + } + } + + It 'should correctly convert back to string in simple functions' -TestCases $TestValues { + param($Argument) + + Invoke-Expression "Test-SimpleStringValue -Value $Argument" | Should -BeExactly $Argument + } + + It 'should correctly convert back to string in advanced functions' -TestCases $TestValues { + param($Argument) + + Invoke-Expression "Test-AdvancedStringValue -Value $Argument" | Should -BeExactly $Argument + } +}