Browse Source

Handle explicit optional parameter after default parameter

pull/3470/head
ds5678 2 months ago committed by Jeremy Pritts
parent
commit
2a0675fb4a
  1. 4
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.cs
  2. 3
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  3. 30
      ICSharpCode.Decompiler/TypeSystem/IParameter.cs
  4. 6
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs

4
ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -307,6 +308,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -307,6 +308,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
}
#endif
public static void Issue3469([Optional][DefaultParameterValue(0)] int i, [Optional] DateTime d)
{
}
#if CS120
public static D LambdaWithOptionalParameter()

3
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -1735,8 +1735,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1735,8 +1735,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
decl.Name = parameter.Name;
}
if (parameter.IsOptional && decl.ParameterModifier is ReferenceKind.None or ReferenceKind.In or ReferenceKind.RefReadOnly
&& parameter.HasConstantValueInSignature && this.ShowConstantValues)
if (parameter.GetDefaultValueAssignmentAllowed() && this.ShowConstantValues)
{
try
{

30
ICSharpCode.Decompiler/TypeSystem/IParameter.cs

@ -105,4 +105,34 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -105,4 +105,34 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
IParameterizedMember? Owner { get; }
}
internal static class IParameterExtensions
{
public static bool GetDefaultValueAssignmentAllowed(this IParameter parameter)
{
if (!DefaultValueAssignmentAllowedIndividual(parameter))
return false;
if (parameter.Owner == null)
return true;
for (int i = parameter.Owner.Parameters.Count - 1; i >= 0; i--)
{
IParameter otherParameter = parameter.Owner.Parameters[i];
if (otherParameter == parameter)
break;
if (DefaultValueAssignmentAllowedIndividual(otherParameter) || otherParameter.IsParams)
continue;
return false;
}
return true;
static bool DefaultValueAssignmentAllowedIndividual(IParameter parameter)
{
return parameter.IsOptional && parameter.HasConstantValueInSignature && parameter.ReferenceKind is ReferenceKind.None or ReferenceKind.In or ReferenceKind.RefReadOnly;
}
}
}
}

6
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs

@ -63,14 +63,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -63,14 +63,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
var metadata = module.metadata;
var parameter = metadata.GetParameter(handle);
bool defaultValueAssignmentAllowed = ReferenceKind is ReferenceKind.None or ReferenceKind.In or ReferenceKind.RefReadOnly;
bool defaultValueAssignmentAllowed = this.GetDefaultValueAssignmentAllowed();
if (IsOptional && (!defaultValueAssignmentAllowed || !HasConstantValueInSignature))
if (IsOptional && !defaultValueAssignmentAllowed)
{
b.Add(KnownAttribute.Optional);
}
if (!(IsDecimalConstant || !HasConstantValueInSignature) && (!defaultValueAssignmentAllowed || !IsOptional))
if (!IsDecimalConstant && HasConstantValueInSignature && !defaultValueAssignmentAllowed)
{
b.Add(KnownAttribute.DefaultParameterValue, KnownTypeCode.Object, GetConstantValue(throwOnInvalidMetadata: false));
}

Loading…
Cancel
Save