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; - } - } -}