Browse Source

Remove IsRef, IsOut and IsIn flags from IParameter and Replace ParameterModifiers with ReferenceKind.

pull/3239/head
Siegfried Pammer 11 months ago
parent
commit
4bf9487ecd
  1. 8
      ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs
  2. 13
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  3. 2
      ICSharpCode.Decompiler/CSharp/CallBuilder.cs
  4. 2
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  5. 4
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs
  6. 20
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs
  7. 6
      ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs
  8. 4
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpConversions.cs
  9. 50
      ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/ParameterDeclaration.cs
  10. 30
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  11. 2
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs
  12. 4
      ICSharpCode.Decompiler/FlowAnalysis/DefiniteAssignmentVisitor.cs
  13. 2
      ICSharpCode.Decompiler/IL/ILReader.cs
  14. 2
      ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs
  15. 4
      ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs
  16. 1
      ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs
  17. 10
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  18. 18
      ICSharpCode.Decompiler/TypeSystem/IParameter.cs
  19. 17
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs
  20. 11
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs
  21. 3
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedParameter.cs

8
ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs

@ -1390,18 +1390,18 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -1390,18 +1390,18 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
{
ITypeDefinition impl = GetTypeDefinition(typeof(ExplicitGenericInterfaceImplementation));
IType genericInterfaceOfString = compilation.FindType(typeof(IGenericInterface<string>));
IMethod implMethod1 = impl.Methods.Single(m => !m.IsConstructor && !m.Parameters[1].IsRef);
IMethod implMethod2 = impl.Methods.Single(m => !m.IsConstructor && m.Parameters[1].IsRef);
IMethod implMethod1 = impl.Methods.Single(m => !m.IsConstructor && m.Parameters[1].ReferenceKind == ReferenceKind.None);
IMethod implMethod2 = impl.Methods.Single(m => !m.IsConstructor && m.Parameters[1].ReferenceKind == ReferenceKind.Ref);
Assert.That(implMethod1.IsExplicitInterfaceImplementation);
Assert.That(implMethod2.IsExplicitInterfaceImplementation);
IMethod interfaceMethod1 = (IMethod)implMethod1.ExplicitlyImplementedInterfaceMembers.Single();
Assert.That(interfaceMethod1.DeclaringType, Is.EqualTo(genericInterfaceOfString));
Assert.That(!interfaceMethod1.Parameters[1].IsRef);
Assert.That(interfaceMethod1.Parameters[1].ReferenceKind == ReferenceKind.None);
IMethod interfaceMethod2 = (IMethod)implMethod2.ExplicitlyImplementedInterfaceMembers.Single();
Assert.That(interfaceMethod2.DeclaringType, Is.EqualTo(genericInterfaceOfString));
Assert.That(interfaceMethod2.Parameters[1].IsRef);
Assert.That(interfaceMethod2.Parameters[1].ReferenceKind == ReferenceKind.Ref);
}
[Test]

13
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1167,7 +1167,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1167,7 +1167,7 @@ namespace ICSharpCode.Decompiler.CSharp
Roles.Comment);
var forwardingCall = new InvocationExpression(new MemberReferenceExpression(new ThisReferenceExpression(), memberDecl.Name,
methodDecl.TypeParameters.Select(tp => new SimpleType(tp.Name))),
methodDecl.Parameters.Select(p => ForwardParameter(p))
methodDecl.Parameters.Select(ForwardParameter)
);
if (m.ReturnType.IsKnownType(KnownTypeCode.Void))
{
@ -1185,12 +1185,17 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1185,12 +1185,17 @@ namespace ICSharpCode.Decompiler.CSharp
{
switch (p.ParameterModifier)
{
case ParameterModifier.Ref:
case ReferenceKind.None:
return new IdentifierExpression(p.Name);
case ReferenceKind.Ref:
case ReferenceKind.RefReadOnly:
return new DirectionExpression(FieldDirection.Ref, new IdentifierExpression(p.Name));
case ParameterModifier.Out:
case ReferenceKind.Out:
return new DirectionExpression(FieldDirection.Out, new IdentifierExpression(p.Name));
case ReferenceKind.In:
return new DirectionExpression(FieldDirection.In, new IdentifierExpression(p.Name));
default:
return new IdentifierExpression(p.Name);
throw new NotSupportedException();
}
}

2
ICSharpCode.Decompiler/CSharp/CallBuilder.cs

@ -78,7 +78,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -78,7 +78,7 @@ namespace ICSharpCode.Decompiler.CSharp
ResolveResult GetResolveResult(int index, TranslatedExpression expression)
{
var param = expectedParameters[index];
if (useImplicitlyTypedOut && param.IsOut && expression.Type is ByReferenceType brt)
if (useImplicitlyTypedOut && param.ReferenceKind == ReferenceKind.Out && expression.Type is ByReferenceType brt)
return new OutVarResolveResult(brt.ElementType);
return expression.ResolveResult;
}

2
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -2409,7 +2409,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2409,7 +2409,7 @@ namespace ICSharpCode.Decompiler.CSharp
// C# 10 lambdas can have attributes, but anonymous methods cannot
isLambda = true;
}
else if (settings.UseLambdaSyntax && ame.Parameters.All(p => p.ParameterModifier == ParameterModifier.None))
else if (settings.UseLambdaSyntax && ame.Parameters.All(p => p.ParameterModifier == ReferenceKind.None && !p.IsParams))
{
// otherwise use lambda only if an expression lambda is possible
isLambda = (body.Statements.Count == 1 && body.Statements.Single() is ReturnStatement);

4
ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs

@ -135,7 +135,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -135,7 +135,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
{
if ((ConversionFlags & ConversionFlags.ShowParameterModifiers) == 0)
{
param.ParameterModifier = ParameterModifier.None;
param.ParameterModifier = ReferenceKind.None;
param.IsScopedRef = false;
param.IsParams = false;
}
if ((ConversionFlags & ConversionFlags.ShowParameterDefaultValues) == 0)
{

20
ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -1077,7 +1077,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -1077,7 +1077,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
return true;
}
var p = lambdaExpression.Parameters.Single();
return !(p.Type.IsNull && p.ParameterModifier == ParameterModifier.None);
return !(p.Type.IsNull && p.ParameterModifier == ReferenceKind.None && !p.IsParams);
}
public virtual void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
@ -2608,6 +2608,11 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -2608,6 +2608,11 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
WriteKeyword(ParameterDeclaration.ThisModifierRole);
Space();
}
if (parameterDeclaration.IsParams)
{
WriteKeyword(ParameterDeclaration.ParamsModifierRole);
Space();
}
if (parameterDeclaration.IsScopedRef)
{
WriteKeyword(ParameterDeclaration.ScopedRefRole);
@ -2615,19 +2620,20 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -2615,19 +2620,20 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
}
switch (parameterDeclaration.ParameterModifier)
{
case ParameterModifier.Ref:
case ReferenceKind.Ref:
WriteKeyword(ParameterDeclaration.RefModifierRole);
Space();
break;
case ParameterModifier.Out:
WriteKeyword(ParameterDeclaration.OutModifierRole);
case ReferenceKind.RefReadOnly:
WriteKeyword(ParameterDeclaration.RefModifierRole);
WriteKeyword(ParameterDeclaration.ReadonlyModifierRole);
Space();
break;
case ParameterModifier.Params:
WriteKeyword(ParameterDeclaration.ParamsModifierRole);
case ReferenceKind.Out:
WriteKeyword(ParameterDeclaration.OutModifierRole);
Space();
break;
case ParameterModifier.In:
case ReferenceKind.In:
WriteKeyword(ParameterDeclaration.InModifierRole);
Space();
break;

6
ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs

@ -196,7 +196,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -196,7 +196,7 @@ namespace ICSharpCode.Decompiler.CSharp
return false;
if (!target.MatchLdThis())
return false;
if (method.Parameters[i].IsIn)
if (method.Parameters[i].ReferenceKind is ReferenceKind.In or ReferenceKind.RefReadOnly)
{
if (!valueInst.MatchLdObj(out valueInst, out _))
return false;
@ -1012,11 +1012,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1012,11 +1012,11 @@ namespace ICSharpCode.Decompiler.CSharp
var deconstruct = method.Parameters[i];
var ctor = primaryCtor.Parameters[i];
if (!deconstruct.IsOut)
if (deconstruct.ReferenceKind != ReferenceKind.Out)
return false;
IType ctorType = ctor.Type;
if (ctor.IsIn)
if (ctor.ReferenceKind is ReferenceKind.In or ReferenceKind.RefReadOnly)
ctorType = ((ByReferenceType)ctorType).ElementType;
if (!ctorType.Equals(((ByReferenceType)deconstruct.Type).ElementType))
return false;

4
ICSharpCode.Decompiler/CSharp/Resolver/CSharpConversions.cs

@ -1128,7 +1128,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -1128,7 +1128,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
foreach (IMethod op in operators)
{
IType sourceType = op.Parameters[0].Type;
if (sourceType.Kind == TypeKind.ByReference && op.Parameters[0].IsIn && fromType.Kind != TypeKind.ByReference)
if (sourceType.Kind == TypeKind.ByReference && op.Parameters[0].ReferenceKind == ReferenceKind.In && fromType.Kind != TypeKind.ByReference)
{
sourceType = ((ByReferenceType)sourceType).ElementType;
}
@ -1235,7 +1235,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -1235,7 +1235,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
// type, as long as no parameter of D has the out parameter modifier.
foreach (IParameter p in d.Parameters)
{
if (p.IsOut)
if (p.ReferenceKind == ReferenceKind.Out)
return Conversion.None;
}
}

50
ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/ParameterDeclaration.cs

@ -26,32 +26,19 @@ @@ -26,32 +26,19 @@
#nullable enable
using System;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.CSharp.Syntax
{
public enum ParameterModifier
{
None,
Ref,
Out,
Params,
In,
Scoped
}
public class ParameterDeclaration : AstNode
{
public static readonly Role<AttributeSection> AttributeRole = EntityDeclaration.AttributeRole;
public static readonly TokenRole ThisModifierRole = new TokenRole("this");
public static readonly TokenRole ScopedRefRole = new TokenRole("scoped");
[Obsolete("Renamed to ScopedRefRole")]
public static readonly TokenRole RefScopedRole = ScopedRefRole;
public static readonly TokenRole RefModifierRole = new TokenRole("ref");
public static readonly TokenRole ReadonlyModifierRole = ComposedType.ReadonlyRole;
public static readonly TokenRole OutModifierRole = new TokenRole("out");
public static readonly TokenRole InModifierRole = new TokenRole("in");
[Obsolete("C# 11 preview: \"ref scoped\" no longer supported")]
public static readonly TokenRole ValueScopedRole = new TokenRole("scoped");
public static readonly TokenRole ParamsModifierRole = new TokenRole("params");
#region PatternPlaceholder
@ -107,6 +94,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -107,6 +94,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
bool hasThisModifier;
bool isParams;
bool isScopedRef;
public CSharpTokenNode ThisKeyword {
@ -127,16 +115,15 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -127,16 +115,15 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
}
public bool IsScopedRef {
get { return isScopedRef; }
public bool IsParams {
get { return isParams; }
set {
ThrowIfFrozen();
isScopedRef = value;
isParams = value;
}
}
[Obsolete("Renamed to IsScopedRef")]
public bool IsRefScoped {
public bool IsScopedRef {
get { return isScopedRef; }
set {
ThrowIfFrozen();
@ -144,15 +131,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -144,15 +131,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
}
[Obsolete("C# 11 preview: \"ref scoped\" no longer supported")]
public bool IsValueScoped {
get { return false; }
set { }
}
ReferenceKind parameterModifier;
ParameterModifier parameterModifier;
public ParameterModifier ParameterModifier {
public ReferenceKind ParameterModifier {
get { return parameterModifier; }
set {
ThrowIfFrozen();
@ -240,19 +221,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -240,19 +221,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
}
public ParameterDeclaration(AstType type, string name, ParameterModifier modifier = ParameterModifier.None)
{
Type = type;
Name = name;
ParameterModifier = modifier;
}
public ParameterDeclaration(string name, ParameterModifier modifier = ParameterModifier.None)
{
Name = name;
ParameterModifier = modifier;
}
public new ParameterDeclaration Clone()
{
return (ParameterDeclaration)base.Clone();

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

@ -372,14 +372,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -372,14 +372,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
for (int i = 0; i < fpt.ParameterTypes.Length; i++)
{
var paramDecl = new ParameterDeclaration();
paramDecl.ParameterModifier = fpt.ParameterReferenceKinds[i] switch {
ReferenceKind.In => ParameterModifier.In,
ReferenceKind.Ref => ParameterModifier.Ref,
ReferenceKind.Out => ParameterModifier.Out,
_ => ParameterModifier.None,
};
paramDecl.ParameterModifier = fpt.ParameterReferenceKinds[i];
IType parameterType = fpt.ParameterTypes[i];
if (paramDecl.ParameterModifier != ParameterModifier.None && parameterType is ByReferenceType brt)
if (paramDecl.ParameterModifier != ReferenceKind.None && parameterType is ByReferenceType brt)
{
paramDecl.Type = ConvertType(brt.ElementType);
}
@ -1649,22 +1644,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1649,22 +1644,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
if (parameter == null)
throw new ArgumentNullException(nameof(parameter));
ParameterDeclaration decl = new ParameterDeclaration();
if (parameter.IsRef)
{
decl.ParameterModifier = ParameterModifier.Ref;
}
else if (parameter.IsOut)
{
decl.ParameterModifier = ParameterModifier.Out;
}
else if (parameter.IsIn)
{
decl.ParameterModifier = ParameterModifier.In;
}
else if (parameter.IsParams)
{
decl.ParameterModifier = ParameterModifier.Params;
}
decl.ParameterModifier = parameter.ReferenceKind;
decl.IsParams = parameter.IsParams;
decl.IsScopedRef = parameter.Lifetime.ScopedRef;
if (ShowAttributes)
{
@ -1685,7 +1666,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1685,7 +1666,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
decl.Name = parameter.Name;
}
if (parameter.IsOptional && decl.ParameterModifier is ParameterModifier.None or ParameterModifier.In && parameter.HasConstantValueInSignature && this.ShowConstantValues)
if (parameter.IsOptional && decl.ParameterModifier is ReferenceKind.None or ReferenceKind.In or ReferenceKind.RefReadOnly
&& parameter.HasConstantValueInSignature && this.ShowConstantValues)
{
try
{

2
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs

@ -389,7 +389,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -389,7 +389,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
private static bool ValidateParameter(ParameterDeclaration p)
{
return p.ParameterModifier == ParameterModifier.None && p.Attributes.Count == 0;
return p.ParameterModifier == Decompiler.TypeSystem.ReferenceKind.None && p.Attributes.Count == 0;
}
}
}

4
ICSharpCode.Decompiler/FlowAnalysis/DefiniteAssignmentVisitor.cs

@ -262,7 +262,7 @@ namespace ICSharpCode.Decompiler.FlowAnalysis @@ -262,7 +262,7 @@ namespace ICSharpCode.Decompiler.FlowAnalysis
bool hasOutArgs = false;
foreach (var arg in call.Arguments)
{
if (arg.MatchLdLoca(out var v) && call.GetParameter(arg.ChildIndex)?.IsOut == true)
if (arg.MatchLdLoca(out var v) && call.GetParameter(arg.ChildIndex)?.ReferenceKind == ReferenceKind.Out)
{
// Visiting ldloca would require the variable to be initialized,
// but we don't need out arguments to be initialized.
@ -278,7 +278,7 @@ namespace ICSharpCode.Decompiler.FlowAnalysis @@ -278,7 +278,7 @@ namespace ICSharpCode.Decompiler.FlowAnalysis
{
foreach (var arg in call.Arguments)
{
if (arg.MatchLdLoca(out var v) && call.GetParameter(arg.ChildIndex)?.IsOut == true)
if (arg.MatchLdLoca(out var v) && call.GetParameter(arg.ChildIndex)?.ReferenceKind == ReferenceKind.Out)
{
HandleStore(v);
}

2
ICSharpCode.Decompiler/IL/ILReader.cs

@ -285,7 +285,7 @@ namespace ICSharpCode.Decompiler.IL @@ -285,7 +285,7 @@ namespace ICSharpCode.Decompiler.IL
{
IParameter parameter = method.Parameters[paramIndex - offset];
ILVariable ilVar = CreateILVariable(paramIndex - offset, parameter.Type, parameter.Name);
ilVar.IsRefReadOnly = parameter.IsIn;
ilVar.IsRefReadOnly = parameter.ReferenceKind is ReferenceKind.In or ReferenceKind.RefReadOnly;
parameterVariables[paramIndex] = ilVar;
paramIndex++;
}

2
ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs

@ -267,7 +267,7 @@ namespace ICSharpCode.Decompiler.IL @@ -267,7 +267,7 @@ namespace ICSharpCode.Decompiler.IL
for (int i = firstOutParam; i < method.Parameters.Count; i++)
{
if (!method.Parameters[i].IsOut)
if (method.Parameters[i].ReferenceKind != ReferenceKind.Out)
return false;
}

4
ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs

@ -556,9 +556,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -556,9 +556,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
internal static bool IsClosureParameter(IParameter parameter, ITypeResolveContext context)
{
if (!parameter.IsRef)
if (parameter.Type is not ByReferenceType brt)
return false;
var type = ((ByReferenceType)parameter.Type).ElementType.GetDefinition();
var type = brt.ElementType.GetDefinition();
return type != null
&& type.Kind == TypeKind.Struct
&& TransformDisplayClassUsage.IsPotentialClosure(context.CurrentTypeDefinition, type);

1
ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs

@ -343,6 +343,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -343,6 +343,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
ReferenceKind.Ref => 1,
ReferenceKind.Out => 2, // in/out also count the modreq
ReferenceKind.In => 2,
ReferenceKind.RefReadOnly => 2, // counts the modopt
_ => throw new NotSupportedException()
};
parameters[i] = type.ParameterTypes[i].AcceptVisitor(this);

10
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -124,8 +124,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -124,8 +124,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// will be reported as custom attribute.
/// </summary>
ScopedRef = 0x4000,
[Obsolete("Use ScopedRef instead")]
LifetimeAnnotations = ScopedRef,
/// <summary>
/// Replace 'IntPtr' types with the 'nint' type even in absence of [NativeIntegerAttribute].
/// Note: DecompilerTypeSystem constructor removes this setting from the options if
@ -133,11 +131,19 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -133,11 +131,19 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
NativeIntegersWithoutAttribute = 0x8000,
/// <summary>
/// If this option is active, [RequiresLocationAttribute] on parameters is removed
/// and parameters are marked as ref readonly.
/// Otherwise, the attribute is preserved but the parameters are not marked
/// as if it was a ref parameter without any attributes.
/// </summary>
RefReadOnlyParameters = 0x10000,
/// <summary>
/// Default settings: typical options for the decompiler, with all C# languages features enabled.
/// </summary>
Default = Dynamic | Tuple | ExtensionMethods | DecimalConstants | ReadOnlyStructsAndParameters
| RefStructs | UnmanagedConstraints | NullabilityAnnotations | ReadOnlyMethods
| NativeIntegers | FunctionPointers | ScopedRef | NativeIntegersWithoutAttribute
| RefReadOnlyParameters
}
/// <summary>

18
ICSharpCode.Decompiler/TypeSystem/IParameter.cs

@ -32,7 +32,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -32,7 +32,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
None,
Out,
Ref,
In
In,
RefReadOnly,
}
public struct LifetimeAnnotation
@ -71,21 +72,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -71,21 +72,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
LifetimeAnnotation Lifetime { get; }
/// <summary>
/// Gets whether this parameter is a C# 'ref' parameter.
/// </summary>
bool IsRef { get; }
/// <summary>
/// Gets whether this parameter is a C# 'out' parameter.
/// </summary>
bool IsOut { get; }
/// <summary>
/// Gets whether this parameter is a C# 'in' parameter.
/// </summary>
bool IsIn { get; }
/// <summary>
/// Gets whether this parameter is a C# 'params' parameter.
/// </summary>

17
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs

@ -76,9 +76,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -76,9 +76,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IEnumerable<IAttribute> GetAttributes() => attributes;
public ReferenceKind ReferenceKind => referenceKind;
public bool IsRef => referenceKind == ReferenceKind.Ref;
public bool IsOut => referenceKind == ReferenceKind.Out;
public bool IsIn => referenceKind == ReferenceKind.In;
public bool IsParams => isParams;
@ -115,12 +112,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -115,12 +112,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public static string ToString(IParameter parameter)
{
StringBuilder b = new StringBuilder();
if (parameter.IsRef)
b.Append("ref ");
if (parameter.IsOut)
b.Append("out ");
if (parameter.IsIn)
b.Append("in ");
b.Append(parameter.ReferenceKind switch {
ReferenceKind.None => "",
ReferenceKind.Ref => "ref ",
ReferenceKind.Out => "out ",
ReferenceKind.In => "in ",
ReferenceKind.RefReadOnly => "ref readonly ",
_ => throw new NotSupportedException()
});
if (parameter.IsParams)
b.Append("params ");
b.Append(parameter.Name);

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

@ -21,7 +21,6 @@ using System.Collections.Generic; @@ -21,7 +21,6 @@ using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using ICSharpCode.Decompiler.Util;
@ -76,13 +75,10 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -76,13 +75,10 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
b.Add(KnownAttribute.DefaultParameterValue, KnownTypeCode.Object, GetConstantValue(throwOnInvalidMetadata: false));
}
if (!IsOut && !IsIn)
{
if ((attributes & ParameterAttributes.In) == ParameterAttributes.In)
if ((attributes & ParameterAttributes.In) == ParameterAttributes.In && ReferenceKind is not (ReferenceKind.In or ReferenceKind.RefReadOnly))
b.Add(KnownAttribute.In);
if ((attributes & ParameterAttributes.Out) == ParameterAttributes.Out)
if ((attributes & ParameterAttributes.Out) == ParameterAttributes.Out && ReferenceKind != ReferenceKind.Out)
b.Add(KnownAttribute.Out);
}
b.Add(parameter.GetCustomAttributes(), SymbolKind.Parameter);
b.AddMarshalInfo(parameter.GetMarshallingDescriptor());
@ -93,9 +89,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -93,9 +89,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
const ParameterAttributes inOut = ParameterAttributes.In | ParameterAttributes.Out;
public ReferenceKind ReferenceKind => DetectRefKind();
public bool IsRef => DetectRefKind() == ReferenceKind.Ref;
public bool IsOut => Type.Kind == TypeKind.ByReference && (attributes & inOut) == ParameterAttributes.Out;
public bool IsIn => DetectRefKind() == ReferenceKind.In;
public bool IsOptional => (attributes & ParameterAttributes.Optional) != 0;

3
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedParameter.cs

@ -37,9 +37,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -37,9 +37,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
IEnumerable<IAttribute> IParameter.GetAttributes() => baseParameter.GetAttributes();
ReferenceKind IParameter.ReferenceKind => baseParameter.ReferenceKind;
bool IParameter.IsRef => baseParameter.IsRef;
bool IParameter.IsOut => baseParameter.IsOut;
bool IParameter.IsIn => baseParameter.IsIn;
bool IParameter.IsParams => baseParameter.IsParams;
bool IParameter.IsOptional => baseParameter.IsOptional;
bool IParameter.HasConstantValueInSignature => baseParameter.HasConstantValueInSignature;

Loading…
Cancel
Save