diff --git a/src/System.Management.Automation/engine/CoreAdapter.cs b/src/System.Management.Automation/engine/CoreAdapter.cs
index 42da612618..d8c2fec89a 100644
--- a/src/System.Management.Automation/engine/CoreAdapter.cs
+++ b/src/System.Management.Automation/engine/CoreAdapter.cs
@@ -3865,6 +3865,33 @@ namespace System.Management.Automation
return entry.isStatic;
}
+ ///
+ /// Get the string representation of the default value of passed-in parameter.
+ ///
+ /// ParameterInfo containing the parameter's default value.
+ /// String representation of the parameter's default value.
+ private static string GetDefaultValueStringRepresentation(ParameterInfo parameterInfo)
+ {
+ var parameterType = parameterInfo.ParameterType;
+ var parameterDefaultValue = parameterInfo.DefaultValue;
+
+ if (parameterDefaultValue == null)
+ {
+ return (parameterType.IsValueType || parameterType.IsGenericMethodParameter)
+ ? "default"
+ : "null";
+ }
+
+ if (parameterType.IsEnum)
+ {
+ return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", parameterType.ToString(), parameterDefaultValue.ToString());
+ }
+
+ return (parameterDefaultValue is string)
+ ? string.Format(CultureInfo.InvariantCulture, "\"{0}\"", parameterDefaultValue.ToString())
+ : parameterDefaultValue.ToString();
+ }
+
#endregion auxiliary methods and classes
#region virtual
@@ -4457,6 +4484,13 @@ namespace System.Management.Automation
builder.Append(ToStringCodeMethods.Type(parameterType));
builder.Append(' ');
builder.Append(parameter.Name);
+
+ if (parameter.HasDefaultValue)
+ {
+ builder.Append(" = ");
+ builder.Append(GetDefaultValueStringRepresentation(parameter));
+ }
+
builder.Append(", ");
}
diff --git a/test/powershell/engine/Api/GetMethodInfoOverloadDefinition.Tests.ps1 b/test/powershell/engine/Api/GetMethodInfoOverloadDefinition.Tests.ps1
new file mode 100644
index 0000000000..aa9fb40127
--- /dev/null
+++ b/test/powershell/engine/Api/GetMethodInfoOverloadDefinition.Tests.ps1
@@ -0,0 +1,178 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+Describe "Method definition Tests" -tags "CI" {
+
+ BeforeAll {
+ Add-Type -NameSpace OverloadDefinitionTest -Name TestClass -MemberDefinition @"
+public static void Bar() { }
+public static void Bar(int param) { }
+public static void Bar(int param1, string param2) { }
+public static string Bar(int? param1, string param2) { return param2; }
+"@
+
+ Add-Type -NameSpace MethodDefinitionTest -Name TestClass -MemberDefinition @"
+public static void TestMethod_Ref(ref int refParam) { }
+
+public static void TestMethod_InOut(in int inParam, out string outParam) { outParam = null; }
+
+public static void TestMethod_Params(params int[] intParams) { }
+
+public static void TestMethod_Generic1(T param) { }
+
+public static void TestMethod_Generic2(T param1, U param2) { }
+
+public static void TestMethod_OptInt(int optParam = int.MinValue) { }
+
+public static void TestMethod_OptString(string optParam = "test string") { }
+
+public static void TestMethod_OptStruct(DateTime optParam = new DateTime()) { }
+
+public static void TestMethod_OptEnum(UriKind optParam = UriKind.Relative) { }
+
+public static void TestMethod_OptGeneric(T param = default) { }
+"@
+
+ $testCases = @(
+ @{
+ Description = "parameter passed by reference";
+ MethodName = "TestMethod_Ref";
+ ExpectedDefinition = "static void TestMethod_Ref([ref] int refParam)"
+ }
+ @{
+ Description = "in and out parameters";
+ MethodName = "TestMethod_InOut";
+ ExpectedDefinition = "static void TestMethod_InOut([ref] int inParam, [ref] string outParam)"
+ }
+ @{
+ Description = "parameters array";
+ MethodName = "TestMethod_Params";
+ ExpectedDefinition = "static void TestMethod_Params(Params int[] intParams)"
+ }
+ @{
+ Description = "one generic parameter";
+ MethodName = "TestMethod_Generic1";
+ ExpectedDefinition = "static void TestMethod_Generic1[T](T param)"
+ }
+ @{
+ Description = "two generic parameters";
+ MethodName = "TestMethod_Generic2";
+ ExpectedDefinition = "static void TestMethod_Generic2[T, U](T param1, U param2)"
+ }
+ @{
+ Description = "optional int parameter";
+ MethodName = "TestMethod_OptInt";
+ ExpectedDefinition = "static void TestMethod_OptInt(int optParam = $([int]::MinValue))"
+ }
+ @{
+ Description = "optional string parameter";
+ MethodName = "TestMethod_OptString";
+ ExpectedDefinition = 'static void TestMethod_OptString(string optParam = "test string")'
+ }
+ @{
+ Description = "optional struct parameter";
+ MethodName = "TestMethod_OptStruct";
+ ExpectedDefinition = 'static void TestMethod_OptStruct(datetime optParam = default)'
+ }
+ @{
+ Description = "optional enum parameter";
+ MethodName = "TestMethod_OptEnum";
+ ExpectedDefinition = "static void TestMethod_OptEnum(System.UriKind optParam = System.UriKind.Relative)"
+ }
+ @{
+ Description = "optional generic parameter";
+ MethodName = "TestMethod_OptGeneric";
+ ExpectedDefinition = "static void TestMethod_OptGeneric[T](T param = default)"
+ }
+ )
+ }
+
+ Context "Verify method definitions" {
+
+ It "Get methods' overload definitions" {
+ $definitions = ([OverloadDefinitionTest.TestClass]::Bar).OverloadDefinitions
+ $definitions.Count | Should -Be 4
+ $definitions[0] | Should -BeExactly "static void Bar()"
+ $definitions[1] | Should -BeExactly "static void Bar(int param)"
+ $definitions[2] | Should -BeExactly "static void Bar(int param1, string param2)"
+ $definitions[3] | Should -BeExactly "static string Bar(System.Nullable[int] param1, string param2)"
+ }
+
+ It "Get definition of the method with " -TestCases $testCases {
+ param($MethodName, $ExpectedDefinition)
+
+ $definition = ([MethodDefinitionTest.TestClass] | Get-Member -Type Method -Static $MethodName).Definition
+ $definition | Should -BeExactly $ExpectedDefinition
+
+ $overloadDefinition = ([MethodDefinitionTest.TestClass]::$MethodName).OverloadDefinitions
+ $overloadDefinition | Should -BeExactly $definition
+ }
+ }
+
+ Context "Verify method definitions' tooltip" {
+
+ It "Tooltip should contain methods' overload definitions" {
+ $result = (TabExpansion2 -inputScript ($s = '[OverloadDefinitionTest.TestClass]::Bar') -cursorColumn $s.Length).CompletionMatches
+ $tooltipParts = $result.ToolTip -split "\r?\n"
+
+ $tooltipParts.Count | Should -Be 4
+ $tooltipParts[0] | Should -BeExactly "static void Bar()"
+ $tooltipParts[1] | Should -BeExactly "static void Bar(int param)"
+ $tooltipParts[2] | Should -BeExactly "static void Bar(int param1, string param2)"
+ $tooltipParts[3] | Should -BeExactly "static string Bar(System.Nullable[int] param1, string param2)"
+ }
+
+ It "Tooltip should contain definition of the method with an optional parameter" {
+ $result = (TabExpansion2 -inputScript ($s = "[MethodDefinitionTest.TestClass]::TestMethod_OptInt") -cursorColumn $s.Length).CompletionMatches
+ $result.ToolTip | Should -BeExactly "static void TestMethod_OptInt(int optParam = $([int]::MinValue))"
+ }
+ }
+
+ Context "Verify Definition of Parameterized Property" {
+ BeforeAll {
+ Add-Type -TypeDefinition @"
+namespace TestParameterizedPropertyDefinition {
+ public class TestClass1
+ {
+ private string[] _indexerArray = new string[1];
+ public string this[int i]
+ {
+ get => _indexerArray[i];
+ set => _indexerArray[i] = value;
+ }
+ }
+
+ public class TestClass2
+ {
+ public int this[int i] => 42;
+ }
+
+ public class TestClass3
+ {
+ [System.Runtime.CompilerServices.IndexerName("TheItem")]
+ public int this[int i] => 42;
+ }
+}
+"@
+ }
+
+ It "Get definition of parametrized property" {
+ $obj = [TestParameterizedPropertyDefinition.TestClass1]::new()
+ $result = $obj | Get-Member -Type ParameterizedProperty
+ $result.Definition | Should -BeExactly "string Item(int i) {get;set;}"
+ }
+
+ It "Get definition of readonly parametrized property" {
+ $obj = [TestParameterizedPropertyDefinition.TestClass2]::new()
+ $result = $obj | Get-Member -Type ParameterizedProperty
+ $result.Definition | Should -BeExactly "int Item(int i) {get;}"
+ }
+
+ It "Get definition of parametrized property with changed name" {
+ $obj = [TestParameterizedPropertyDefinition.TestClass3]::new()
+ $result = $obj | Get-Member -Type ParameterizedProperty
+ $result.Name | Should -BeExactly "TheItem"
+ $result.Definition | Should -BeExactly "int TheItem(int i) {get;}"
+ }
+ }
+}