Browse Source

Add support for unsigned right shift.

Only for user-defined operators so far; builtin right shifts still cast to the appropriate type.
pull/2994/head
Daniel Grunwald 2 years ago
parent
commit
3c46271a11
  1. 32
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs
  2. 10
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Operators.cs
  3. 1
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  4. 7
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  5. 1
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs
  6. 1
      ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs
  7. 3
      ICSharpCode.Decompiler/CSharp/OutputVisitor/GenericGrammarAmbiguityVisitor.cs
  8. 1
      ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertParenthesesVisitor.cs
  9. 21
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs
  10. 7
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs
  11. 9
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/AssignmentExpression.cs
  12. 5
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/BinaryOperatorExpression.cs
  13. 5
      ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/OperatorDeclaration.cs
  14. 7
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  15. 6
      ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs
  16. 21
      ICSharpCode.Decompiler/DecompilerSettings.cs
  17. 2
      ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs
  18. 4
      ICSharpCode.Decompiler/Output/IAmbience.cs
  19. 4
      ILSpy/Languages/CSharpLanguage.cs
  20. 9
      ILSpy/Properties/Resources.Designer.cs
  21. 3
      ILSpy/Properties/Resources.resx

32
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs

@ -201,6 +201,12 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -201,6 +201,12 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
throw new NotImplementedException();
}
#if CS110
public static CustomStruct operator >>>(CustomStruct lhs, int rhs)
{
throw new NotImplementedException();
}
#endif
public static CustomStruct operator &(CustomStruct lhs, CustomStruct rhs)
{
throw new NotImplementedException();
@ -4219,6 +4225,32 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -4219,6 +4225,32 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
#endif
}
#if CS110
public static void CustomStructUnsignedRightShiftTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
//CustomStruct l = default(CustomStruct);
//p >>>= 5;
//l >>>= 5;
customStructField >>>= 5;
CustomStructProp >>>= 5;
c.CustomStructField >>>= 5;
c.CustomStructProp >>>= 5;
s.CustomStructField >>>= 5;
s.CustomStructProp >>>= 5;
customClassField.CustomStructField >>>= 5;
customClassField.CustomStructProp >>>= 5;
otherCustomStructField.CustomStructField >>>= 5;
otherCustomStructField.CustomStructProp >>>= 5;
CustomClassProp.CustomStructField >>>= 5;
CustomClassProp.CustomStructProp >>>= 5;
GetClass().CustomStructField >>>= 5;
GetClass().CustomStructProp >>>= 5;
GetRefStruct().CustomStructField >>>= 5;
GetRefStruct().CustomStructProp >>>= 5;
GetRefCustomStruct() >>>= 5;
}
#endif
public static void CustomStructBitAndTest(CustomStruct p, CustomClass c, CustomStruct2 s)
{
//CustomStruct l = default(CustomStruct);

10
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Operators.cs

@ -72,6 +72,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -72,6 +72,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return null;
}
#if CS110
public static AllOperators operator >>>(AllOperators a, int b)
{
return null;
}
#endif
public static AllOperators operator ~(AllOperators a)
{
return null;
@ -170,6 +177,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -170,6 +177,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
c = a ^ b;
c = a << 5;
c = a >> 5;
#if CS110
c = a >>> 5;
#endif
c = ~a;
c = !a;
c = -a;

1
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -530,6 +530,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -530,6 +530,7 @@ namespace ICSharpCode.Decompiler.CSharp
typeSystemAstBuilder.SupportInitAccessors = settings.InitAccessors;
typeSystemAstBuilder.SupportRecordClasses = settings.RecordClasses;
typeSystemAstBuilder.SupportRecordStructs = settings.RecordStructs;
typeSystemAstBuilder.SupportUnsignedRightShift = settings.UnsignedRightShift;
typeSystemAstBuilder.AlwaysUseGlobal = settings.AlwaysUseGlobal;
return typeSystemAstBuilder;
}

7
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1729,6 +1729,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1729,6 +1729,7 @@ namespace ICSharpCode.Decompiler.CSharp
case BinaryOperatorType.ExclusiveOr:
case BinaryOperatorType.ShiftLeft:
case BinaryOperatorType.ShiftRight:
case BinaryOperatorType.UnsignedShiftRight:
return false;
default:
return true;
@ -1804,7 +1805,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1804,7 +1805,7 @@ namespace ICSharpCode.Decompiler.CSharp
else if (inst.Method.Parameters.Count == 2)
{
var value = Translate(inst.Value).ConvertTo(inst.Method.Parameters[1].Type, this);
AssignmentOperatorType? op = GetAssignmentOperatorTypeFromMetadataName(inst.Method.Name);
AssignmentOperatorType? op = GetAssignmentOperatorTypeFromMetadataName(inst.Method.Name, settings);
Debug.Assert(op != null);
return new AssignmentExpression(target, op.Value, value)
@ -1822,7 +1823,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1822,7 +1823,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
internal static AssignmentOperatorType? GetAssignmentOperatorTypeFromMetadataName(string name)
internal static AssignmentOperatorType? GetAssignmentOperatorTypeFromMetadataName(string name, DecompilerSettings settings)
{
switch (name)
{
@ -1846,6 +1847,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1846,6 +1847,8 @@ namespace ICSharpCode.Decompiler.CSharp
return AssignmentOperatorType.ShiftLeft;
case "op_RightShift":
return AssignmentOperatorType.ShiftRight;
case "op_UnsignedRightShift" when settings.UnsignedRightShift:
return AssignmentOperatorType.UnsignedShiftRight;
default:
return null;
}

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

@ -237,6 +237,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -237,6 +237,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
astBuilder.SupportInitAccessors = (ConversionFlags & ConversionFlags.SupportInitAccessors) != 0;
astBuilder.SupportRecordClasses = (ConversionFlags & ConversionFlags.SupportRecordClasses) != 0;
astBuilder.SupportRecordStructs = (ConversionFlags & ConversionFlags.SupportRecordStructs) != 0;
astBuilder.SupportUnsignedRightShift = (ConversionFlags & ConversionFlags.SupportUnsignedRightShift) != 0;
return astBuilder;
}

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

@ -826,6 +826,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -826,6 +826,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
break;
case BinaryOperatorType.ShiftLeft:
case BinaryOperatorType.ShiftRight:
case BinaryOperatorType.UnsignedShiftRight:
spacePolicy = policy.SpaceAroundShiftOperator;
break;
case BinaryOperatorType.NullCoalescing:

3
ICSharpCode.Decompiler/CSharp/OutputVisitor/GenericGrammarAmbiguityVisitor.cs

@ -92,6 +92,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -92,6 +92,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
case BinaryOperatorType.ShiftRight when genericNestingLevel >= 2:
genericNestingLevel -= 2;
break;
case BinaryOperatorType.UnsignedShiftRight when genericNestingLevel >= 3:
genericNestingLevel -= 3;
break;
default:
return true; // stop visiting, no ambiguity found
}

1
ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertParenthesesVisitor.cs

@ -122,6 +122,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -122,6 +122,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
return PrecedenceLevel.Additive;
case BinaryOperatorType.ShiftLeft:
case BinaryOperatorType.ShiftRight:
case BinaryOperatorType.UnsignedShiftRight:
return PrecedenceLevel.Shift;
case BinaryOperatorType.GreaterThan:
case BinaryOperatorType.GreaterThanOrEqual:

21
ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs

@ -674,6 +674,27 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -674,6 +674,27 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
}
}
}
OperatorMethod[]? unsignedShiftRightOperators;
public OperatorMethod[] UnsignedShiftRightOperators {
get {
OperatorMethod[]? ops = LazyInit.VolatileRead(ref unsignedShiftRightOperators);
if (ops != null)
{
return ops;
}
else
{
return LazyInit.GetOrSet(ref unsignedShiftRightOperators, Lift(
new LambdaBinaryOperatorMethod<int, int>(this, (a, b) => (int)((uint)a >> b)),
new LambdaBinaryOperatorMethod<uint, int>(this, (a, b) => a >> b),
new LambdaBinaryOperatorMethod<long, int>(this, (a, b) => (long)((ulong)a >> b)),
new LambdaBinaryOperatorMethod<ulong, int>(this, (a, b) => a >> b)
));
}
}
}
#endregion
#region Equality operators

7
ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs

@ -685,7 +685,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -685,7 +685,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
{
isNullable = true;
}
if (op == BinaryOperatorType.ShiftLeft || op == BinaryOperatorType.ShiftRight)
if (op == BinaryOperatorType.ShiftLeft || op == BinaryOperatorType.ShiftRight || op == BinaryOperatorType.UnsignedShiftRight)
{
// special case: the shift operators allow "var x = null << null", producing int?.
if (lhsType.Kind == TypeKind.Null && rhsType.Kind == TypeKind.Null)
@ -805,6 +805,9 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -805,6 +805,9 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
case BinaryOperatorType.ShiftRight:
methodGroup = operators.ShiftRightOperators;
break;
case BinaryOperatorType.UnsignedShiftRight:
methodGroup = operators.UnsignedShiftRightOperators;
break;
case BinaryOperatorType.Equality:
case BinaryOperatorType.InEquality:
case BinaryOperatorType.LessThan:
@ -1256,6 +1259,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -1256,6 +1259,8 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
return "op_LeftShift";
case BinaryOperatorType.ShiftRight:
return "op_RightShift";
case BinaryOperatorType.UnsignedShiftRight:
return "op_UnsignedRightShift";
case BinaryOperatorType.Equality:
return "op_Equality";
case BinaryOperatorType.InEquality:

9
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/AssignmentExpression.cs

@ -47,6 +47,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -47,6 +47,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
public readonly static TokenRole ModulusRole = new TokenRole("%=");
public readonly static TokenRole ShiftLeftRole = new TokenRole("<<=");
public readonly static TokenRole ShiftRightRole = new TokenRole(">>=");
public readonly static TokenRole UnsignedShiftRightRole = new TokenRole(">>>=");
public readonly static TokenRole BitwiseAndRole = new TokenRole("&=");
public readonly static TokenRole BitwiseOrRole = new TokenRole("|=");
public readonly static TokenRole ExclusiveOrRole = new TokenRole("^=");
@ -129,6 +130,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -129,6 +130,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return ShiftLeftRole;
case AssignmentOperatorType.ShiftRight:
return ShiftRightRole;
case AssignmentOperatorType.UnsignedShiftRight:
return UnsignedShiftRightRole;
case AssignmentOperatorType.BitwiseAnd:
return BitwiseAndRole;
case AssignmentOperatorType.BitwiseOr:
@ -164,6 +167,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -164,6 +167,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return BinaryOperatorType.ShiftLeft;
case AssignmentOperatorType.ShiftRight:
return BinaryOperatorType.ShiftRight;
case AssignmentOperatorType.UnsignedShiftRight:
return BinaryOperatorType.UnsignedShiftRight;
case AssignmentOperatorType.BitwiseAnd:
return BinaryOperatorType.BitwiseAnd;
case AssignmentOperatorType.BitwiseOr:
@ -195,6 +200,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -195,6 +200,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return ExpressionType.LeftShiftAssign;
case AssignmentOperatorType.ShiftRight:
return ExpressionType.RightShiftAssign;
case AssignmentOperatorType.UnsignedShiftRight:
return ExpressionType.Extension;
case AssignmentOperatorType.BitwiseAnd:
return ExpressionType.AndAssign;
case AssignmentOperatorType.BitwiseOr:
@ -259,6 +266,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -259,6 +266,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
ShiftLeft,
/// <summary>left >>= right</summary>
ShiftRight,
/// <summary>left >>>= right</summary>
UnsignedShiftRight,
/// <summary>left &amp;= right</summary>
BitwiseAnd,

5
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/BinaryOperatorExpression.cs

@ -52,6 +52,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -52,6 +52,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
public readonly static TokenRole ModulusRole = new TokenRole("%");
public readonly static TokenRole ShiftLeftRole = new TokenRole("<<");
public readonly static TokenRole ShiftRightRole = new TokenRole(">>");
public readonly static TokenRole UnsignedShiftRightRole = new TokenRole(">>>");
public readonly static TokenRole NullCoalescingRole = new TokenRole("??");
public readonly static TokenRole RangeRole = new TokenRole("..");
public readonly static TokenRole IsKeywordRole = IsExpression.IsKeywordRole;
@ -151,6 +152,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -151,6 +152,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return ShiftLeftRole;
case BinaryOperatorType.ShiftRight:
return ShiftRightRole;
case BinaryOperatorType.UnsignedShiftRight:
return UnsignedShiftRightRole;
case BinaryOperatorType.NullCoalescing:
return NullCoalescingRole;
case BinaryOperatorType.Range:
@ -262,6 +265,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -262,6 +265,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
ShiftLeft,
/// <summary>left &gt;&gt; right</summary>
ShiftRight,
/// <summary>left &gt;&gt;&gt; right</summary>
UnsignedShiftRight,
/// <summary>left ?? right</summary>
NullCoalescing,

5
ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/OperatorDeclaration.cs

@ -57,6 +57,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -57,6 +57,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
ExclusiveOr,
LeftShift,
RightShift,
UnsignedRightShift,
Equality,
Inequality,
GreaterThan,
@ -94,6 +95,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -94,6 +95,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
public static readonly TokenRole ExclusiveOrRole = new TokenRole("^");
public static readonly TokenRole LeftShiftRole = new TokenRole("<<");
public static readonly TokenRole RightShiftRole = new TokenRole(">>");
public static readonly TokenRole UnsignedRightShiftRole = new TokenRole(">>>");
public static readonly TokenRole EqualityRole = new TokenRole("==");
public static readonly TokenRole InequalityRole = new TokenRole("!=");
public static readonly TokenRole GreaterThanRole = new TokenRole(">");
@ -127,6 +129,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -127,6 +129,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
names[(int)OperatorType.ExclusiveOr] = new string[] { "^", "op_ExclusiveOr" };
names[(int)OperatorType.LeftShift] = new string[] { "<<", "op_LeftShift" };
names[(int)OperatorType.RightShift] = new string[] { ">>", "op_RightShift" };
names[(int)OperatorType.UnsignedRightShift] = new string[] { ">>>", "op_UnsignedRightShift" };
names[(int)OperatorType.Equality] = new string[] { "==", "op_Equality" };
names[(int)OperatorType.Inequality] = new string[] { "!=", "op_Inequality" };
names[(int)OperatorType.GreaterThan] = new string[] { ">", "op_GreaterThan" };
@ -230,6 +233,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -230,6 +233,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return LeftShiftRole;
case OperatorType.RightShift:
return RightShiftRole;
case OperatorType.UnsignedRightShift:
return UnsignedRightShiftRole;
case OperatorType.Equality:
return EqualityRole;
case OperatorType.Inequality:

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

@ -225,6 +225,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -225,6 +225,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
/// </summary>
public bool SupportRecordStructs { get; set; }
/// <summary>
/// Controls whether C# 11 "operator >>>" is supported.
/// </summary>
public bool SupportUnsignedRightShift { get; set; }
/// <summary>
/// Controls whether all fully qualified type names should be prefixed with "global::".
/// </summary>
@ -2217,6 +2222,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -2217,6 +2222,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
OperatorType? opType = OperatorDeclaration.GetOperatorType(op.Name);
if (opType == null)
return ConvertMethod(op);
if (opType == OperatorType.UnsignedRightShift && !SupportUnsignedRightShift)
return ConvertMethod(op);
OperatorDeclaration decl = new OperatorDeclaration();
decl.Modifiers = GetMemberModifiers(op);

6
ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs

@ -142,7 +142,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -142,7 +142,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
break;
}
BinaryOperatorType? bop = GetBinaryOperatorTypeFromMetadataName(method.Name);
BinaryOperatorType? bop = GetBinaryOperatorTypeFromMetadataName(method.Name, context.Settings);
if (bop != null && arguments.Length == 2)
{
invocationExpression.Arguments.Clear(); // detach arguments from invocationExpression
@ -350,7 +350,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -350,7 +350,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
}
static BinaryOperatorType? GetBinaryOperatorTypeFromMetadataName(string name)
static BinaryOperatorType? GetBinaryOperatorTypeFromMetadataName(string name, DecompilerSettings settings)
{
switch (name)
{
@ -374,6 +374,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -374,6 +374,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return BinaryOperatorType.ShiftLeft;
case "op_RightShift":
return BinaryOperatorType.ShiftRight;
case "op_UnsignedRightShift" when settings.UnsignedRightShift:
return BinaryOperatorType.UnsignedShiftRight;
case "op_Equality":
return BinaryOperatorType.Equality;
case "op_Inequality":

21
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -154,12 +154,13 @@ namespace ICSharpCode.Decompiler @@ -154,12 +154,13 @@ namespace ICSharpCode.Decompiler
requiredMembers = false;
numericIntPtr = false;
utf8StringLiterals = false;
unsignedRightShift = false;
}
}
public CSharp.LanguageVersion GetMinimumRequiredVersion()
{
if (parameterNullCheck || scopedRef || requiredMembers || numericIntPtr || utf8StringLiterals)
if (parameterNullCheck || scopedRef || requiredMembers || numericIntPtr || utf8StringLiterals || unsignedRightShift)
return CSharp.LanguageVersion.CSharp11_0;
if (fileScopedNamespaces || recordStructs)
return CSharp.LanguageVersion.CSharp10_0;
@ -1199,6 +1200,24 @@ namespace ICSharpCode.Decompiler @@ -1199,6 +1200,24 @@ namespace ICSharpCode.Decompiler
}
}
bool unsignedRightShift = true;
/// <summary>
/// Gets/Sets whether to use C# 11.0 unsigned right shift operator.
/// </summary>
[Category("C# 11.0 / VS 2022.4")]
[Description("DecompilerSettings.UnsignedRightShift")]
public bool UnsignedRightShift {
get { return unsignedRightShift; }
set {
if (unsignedRightShift != value)
{
unsignedRightShift = value;
OnPropertyChanged();
}
}
}
bool showXmlDocumentation = true;
/// <summary>

2
ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

@ -386,7 +386,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -386,7 +386,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ILInstruction rhs;
if (operatorCall.Arguments.Count == 2)
{
if (CSharp.ExpressionBuilder.GetAssignmentOperatorTypeFromMetadataName(operatorCall.Method.Name) == null)
if (CSharp.ExpressionBuilder.GetAssignmentOperatorTypeFromMetadataName(operatorCall.Method.Name, context.Settings) == null)
return false;
rhs = operatorCall.Arguments[1];
}

4
ICSharpCode.Decompiler/Output/IAmbience.cs

@ -109,6 +109,10 @@ namespace ICSharpCode.Decompiler.Output @@ -109,6 +109,10 @@ namespace ICSharpCode.Decompiler.Output
/// Support <c>record</c> structs.
/// </summary>
SupportRecordStructs = 0x40000,
/// <summary>
/// Support <c>&gt;&gt;&gt;</c> as unsigned right shift operator.
/// </summary>
SupportUnsignedRightShift = 0x80000,
StandardConversionFlags = ShowParameterNames |
ShowAccessibility |

4
ILSpy/Languages/CSharpLanguage.cs

@ -749,6 +749,10 @@ namespace ICSharpCode.ILSpy @@ -749,6 +749,10 @@ namespace ICSharpCode.ILSpy
{
flags |= ConversionFlags.SupportRecordStructs;
}
if (settings.UnsignedRightShift)
{
flags |= ConversionFlags.SupportUnsignedRightShift;
}
if (settings.InitAccessors)
{
flags |= ConversionFlags.SupportInitAccessors;

9
ILSpy/Properties/Resources.Designer.cs generated

@ -1280,6 +1280,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -1280,6 +1280,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Unsigned right shift (&gt;&gt;&gt;).
/// </summary>
public static string DecompilerSettings_UnsignedRightShift {
get {
return ResourceManager.GetString("DecompilerSettings.UnsignedRightShift", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use discards.
/// </summary>

3
ILSpy/Properties/Resources.resx

@ -450,6 +450,9 @@ Are you sure you want to continue?</value> @@ -450,6 +450,9 @@ Are you sure you want to continue?</value>
<data name="DecompilerSettings.SwitchExpressions" xml:space="preserve">
<value>Switch expressions</value>
</data>
<data name="DecompilerSettings.UnsignedRightShift" xml:space="preserve">
<value>Unsigned right shift (&gt;&gt;&gt;)</value>
</data>
<data name="DecompilerSettings.UseDiscards" xml:space="preserve">
<value>Use discards</value>
</data>

Loading…
Cancel
Save