diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
index 9d44a14a3..53bf7942b 100644
--- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
+++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
@@ -91,7 +91,6 @@ namespace ICSharpCode.Decompiler.CSharp
new InlineReturnTransform(), // must run before DetectPinnedRegions
new RemoveInfeasiblePathTransform(),
new DetectPinnedRegions(), // must run after inlining but before non-critical control flow transforms
- new ParameterNullCheckTransform(), // must run after inlining but before yield/async
new YieldReturnDecompiler(), // must run after inlining but before loop detection
new AsyncAwaitDecompiler(), // must run after inlining but before loop detection
new DetectCatchWhenConditionBlocks(), // must run after inlining but before loop detection
@@ -185,7 +184,6 @@ namespace ICSharpCode.Decompiler.CSharp
new AddCheckedBlocks(),
new DeclareVariables(), // should run after most transforms that modify statements
new TransformFieldAndConstructorInitializers(), // must run after DeclareVariables
- new DecimalConstantTransform(),
new PrettifyAssignments(), // must run after DeclareVariables
new IntroduceUsingDeclarations(),
new IntroduceExtensionMethods(), // must run after IntroduceUsingDeclarations
diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/DecimalConstantTransform.cs b/ICSharpCode.Decompiler/CSharp/Transforms/DecimalConstantTransform.cs
deleted file mode 100644
index ea9d78ff9..000000000
--- a/ICSharpCode.Decompiler/CSharp/Transforms/DecimalConstantTransform.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this
-// software and associated documentation files (the "Software"), to deal in the Software
-// without restriction, including without limitation the rights to use, copy, modify, merge,
-// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-// to whom the Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-using ICSharpCode.Decompiler.CSharp.Syntax;
-using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
-using ICSharpCode.Decompiler.TypeSystem;
-
-namespace ICSharpCode.Decompiler.CSharp.Transforms
-{
- ///
- /// Transforms decimal constant fields.
- ///
- public class DecimalConstantTransform : DepthFirstAstVisitor, IAstTransform
- {
- static readonly PrimitiveType decimalType = new PrimitiveType("decimal");
-
- public override void VisitFieldDeclaration(FieldDeclaration fieldDeclaration)
- {
- const Modifiers staticReadOnly = Modifiers.Static | Modifiers.Readonly;
- if ((fieldDeclaration.Modifiers & staticReadOnly) == staticReadOnly && decimalType.IsMatch(fieldDeclaration.ReturnType))
- {
- foreach (var attributeSection in fieldDeclaration.Attributes)
- {
- foreach (var attribute in attributeSection.Attributes)
- {
- var t = attribute.Type.GetSymbol() as IType;
- if (t != null && t.Name == "DecimalConstantAttribute" && t.Namespace == "System.Runtime.CompilerServices")
- {
- attribute.Remove();
- if (attributeSection.Attributes.Count == 0)
- attributeSection.Remove();
- fieldDeclaration.Modifiers = (fieldDeclaration.Modifiers & ~staticReadOnly) | Modifiers.Const;
- return;
- }
- }
- }
- }
- }
-
- public void Run(AstNode rootNode, TransformContext context)
- {
- if (!context.Settings.DecimalConstants)
- return;
- rootNode.AcceptVisitor(this);
- }
- }
-}
diff --git a/ICSharpCode.Decompiler/DecompilerSettings.cs b/ICSharpCode.Decompiler/DecompilerSettings.cs
index 1032093b3..533eb1ed3 100644
--- a/ICSharpCode.Decompiler/DecompilerSettings.cs
+++ b/ICSharpCode.Decompiler/DecompilerSettings.cs
@@ -152,7 +152,6 @@ namespace ICSharpCode.Decompiler
}
if (languageVersion < CSharp.LanguageVersion.CSharp11_0)
{
- parameterNullCheck = false;
scopedRef = false;
requiredMembers = false;
numericIntPtr = false;
@@ -164,7 +163,7 @@ namespace ICSharpCode.Decompiler
public CSharp.LanguageVersion GetMinimumRequiredVersion()
{
- if (parameterNullCheck || scopedRef || requiredMembers || numericIntPtr || utf8StringLiterals || unsignedRightShift || checkedOperators)
+ if (scopedRef || requiredMembers || numericIntPtr || utf8StringLiterals || unsignedRightShift || checkedOperators)
return CSharp.LanguageVersion.CSharp11_0;
if (fileScopedNamespaces || recordStructs)
return CSharp.LanguageVersion.CSharp10_0;
@@ -443,26 +442,6 @@ namespace ICSharpCode.Decompiler
}
}
- bool parameterNullCheck = false;
-
- ///
- /// Use C# 11 preview parameter null-checking (string param!!
).
- ///
- [Category("C# 11.0 / VS 2022.4")]
- [Description("DecompilerSettings.ParameterNullCheck")]
- [Browsable(false)]
- [Obsolete("This feature did not make it into C# 11, and may be removed in a future version of the decompiler.")]
- public bool ParameterNullCheck {
- get { return parameterNullCheck; }
- set {
- if (parameterNullCheck != value)
- {
- parameterNullCheck = value;
- OnPropertyChanged();
- }
- }
- }
-
bool anonymousMethods = true;
///
diff --git a/ICSharpCode.Decompiler/IL/Transforms/ParameterNullCheckTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/ParameterNullCheckTransform.cs
deleted file mode 100644
index 7deb3d9ea..000000000
--- a/ICSharpCode.Decompiler/IL/Transforms/ParameterNullCheckTransform.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2017 Siegfried Pammer
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this
-// software and associated documentation files (the "Software"), to deal in the Software
-// without restriction, including without limitation the rights to use, copy, modify, merge,
-// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-// to whom the Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#nullable enable
-
-using System.Diagnostics.CodeAnalysis;
-
-using ICSharpCode.Decompiler.TypeSystem;
-
-namespace ICSharpCode.Decompiler.IL.Transforms
-{
- ///
- /// Implements transforming <PrivateImplementationDetails>.ThrowIfNull(name, "name");
- ///
- class ParameterNullCheckTransform : IILTransform
- {
- void IILTransform.Run(ILFunction function, ILTransformContext context)
- {
-#pragma warning disable 618 // ParameterNullCheck is obsolete
- if (!context.Settings.ParameterNullCheck)
- return;
-#pragma warning restore 618
- // we only need to look at the entry-point as parameter null-checks
- // do not produce any IL control-flow instructions
- Block entryPoint = ((BlockContainer)function.Body).EntryPoint;
- int index = 0;
- // Early versions of this pattern produced call ThrowIfNull instructions after
- // state-machine initialization instead of right at the start of the method.
- // In order to support both patterns, we scan all instructions,
- // if the current function is decorated with a state-machine attribute.
- bool scanFullBlock = function.Method != null
- && (function.Method.HasAttribute(KnownAttribute.IteratorStateMachine)
- || function.Method.HasAttribute(KnownAttribute.AsyncIteratorStateMachine)
- || function.Method.HasAttribute(KnownAttribute.AsyncStateMachine));
- // loop over all instructions
- while (index < entryPoint.Instructions.Count)
- {
- // The pattern does not match for the current instruction
- if (!MatchThrowIfNullCall(entryPoint.Instructions[index], out ILVariable? parameterVariable))
- {
- if (scanFullBlock)
- {
- // continue scanning
- index++;
- continue;
- }
- else
- {
- // abort
- break;
- }
- }
- // remove the call to ThrowIfNull
- entryPoint.Instructions.RemoveAt(index);
- // remember to generate !! when producing the final output.
- parameterVariable.HasNullCheck = true;
- }
- }
-
- // call .ThrowIfNull(ldloc parameterVariable, ldstr "parameterVariable")
- private bool MatchThrowIfNullCall(ILInstruction instruction, [NotNullWhen(true)] out ILVariable? parameterVariable)
- {
- parameterVariable = null;
- if (instruction is not Call call)
- return false;
- if (call.Arguments.Count != 2)
- return false;
- if (!call.Method.IsStatic || !call.Method.FullNameIs("", "ThrowIfNull"))
- return false;
- if (!(call.Arguments[0].MatchLdLoc(out parameterVariable) && parameterVariable.Kind == VariableKind.Parameter))
- return false;
- return true;
- }
- }
-}