Enable same set of analyzers for C# tools that are used by the repo (#81073)
authorMarek Safar <marek.safar@gmail.com>
Thu, 9 Feb 2023 16:07:14 +0000 (17:07 +0100)
committerGitHub <noreply@github.com>
Thu, 9 Feb 2023 16:07:14 +0000 (17:07 +0100)
Co-authored-by: Tlakaelel Axayakatl Ceja <tlakaelel.ceja@microsoft.com>
113 files changed:
eng/pipelines/runtime-linker-tests.yml
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/DiagnosticContext.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/GenericArgumentDataFlow.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/DiagnosticContext.cs
src/coreclr/tools/aot/ILLink.Shared/TrimAnalysis/DiagnosticContext.cs
src/tools/illink/.editorconfig
src/tools/illink/external/Mono.Options/Options.cs
src/tools/illink/external/corert/src/System.Private.CoreLib/shared/System/Reflection/AssemblyNameFormatter.cs
src/tools/illink/external/corert/src/System.Private.CoreLib/shared/System/Reflection/AssemblyNameHelpers.cs
src/tools/illink/external/corert/src/System.Private.CoreLib/shared/System/Reflection/AssemblyNameLexer.cs
src/tools/illink/external/corert/src/System.Private.CoreLib/shared/System/Reflection/AssemblyNameParser.cs
src/tools/illink/external/corert/src/System.Private.CoreLib/shared/System/Reflection/RuntimeAssemblyName.cs
src/tools/illink/external/corert/src/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/TypeLexer.cs
src/tools/illink/external/corert/src/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/TypeName.cs
src/tools/illink/external/corert/src/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/TypeParser.cs
src/tools/illink/src/ILLink.CodeFix/DynamicallyAccessedMembersCodeFixProvider.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/BasicBlockExtensions.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/CapturedReferenceValue.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/ControlFlowGraphProxy.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/InterproceduralState.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowVisitor.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalStateLattice.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/MethodBodyValue.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/IMethodSymbolExtensions.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/IOperationExtensions.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/IPropertySymbolExtensions.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/ISymbolExtensions.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAssemblyFilesAnalyzer.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresDynamicCodeAnalyzer.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeUtils.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ArrayValue.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/DiagnosticContext.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/FieldValue.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/FlowAnnotations.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/GenericParameterValue.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodParameterValue.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodProxy.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodReturnValue.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/ParameterProxy.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/SingleValueExtensions.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisAssignmentPattern.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs
src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimDataFlowAnalysis.cs
src/tools/illink/src/ILLink.Shared/TrimAnalysis/DiagnosticContext.cs
src/tools/illink/src/ILLink.Shared/TrimAnalysis/FlowAnnotations.cs
src/tools/illink/src/ILLink.Tasks/CreateRuntimeRootDescriptorFile.cs
src/tools/illink/src/ILLink.Tasks/LinkTask.cs
src/tools/illink/src/ILLink.Tasks/Utils.cs
src/tools/illink/src/linker/Linker.Dataflow/ArrayValue.cs
src/tools/illink/src/linker/Linker.Dataflow/DiagnosticContext.cs
src/tools/illink/src/linker/Linker.Dataflow/DynamicallyAccessedMembersTypeHierarchy.cs
src/tools/illink/src/linker/Linker.Dataflow/FieldValue.cs
src/tools/illink/src/linker/Linker.Dataflow/FlowAnnotations.cs
src/tools/illink/src/linker/Linker.Dataflow/GenericArgumentDataFlow.cs
src/tools/illink/src/linker/Linker.Dataflow/GenericParameterValue.cs
src/tools/illink/src/linker/Linker.Dataflow/HandleCallAction.cs
src/tools/illink/src/linker/Linker.Dataflow/HoistedLocalKey.cs
src/tools/illink/src/linker/Linker.Dataflow/InterproceduralState.cs
src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs
src/tools/illink/src/linker/Linker.Dataflow/MethodParameterValue.cs
src/tools/illink/src/linker/Linker.Dataflow/MethodProxy.cs
src/tools/illink/src/linker/Linker.Dataflow/MethodReturnValue.cs
src/tools/illink/src/linker/Linker.Dataflow/ReflectionMarker.cs
src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
src/tools/illink/src/linker/Linker.Dataflow/RequireDynamicallyAccessedMembersAction.cs
src/tools/illink/src/linker/Linker.Dataflow/ScannerExtensions.cs
src/tools/illink/src/linker/Linker.Dataflow/TrimAnalysisAssignmentPattern.cs
src/tools/illink/src/linker/Linker.Dataflow/TrimAnalysisMethodCallPattern.cs
src/tools/illink/src/linker/Linker.Dataflow/TrimAnalysisPatternStore.cs
src/tools/illink/src/linker/Linker.Dataflow/ValueNode.cs
src/tools/illink/src/linker/Linker.Steps/BodySubstitutionParser.cs
src/tools/illink/src/linker/Linker.Steps/CheckSuppressionsStep.cs
src/tools/illink/src/linker/Linker.Steps/DescriptorMarker.cs
src/tools/illink/src/linker/Linker.Steps/LinkAttributesParser.cs
src/tools/illink/src/linker/Linker.Steps/MarkExportedTypesTargetStep.cs
src/tools/illink/src/linker/Linker.Steps/MarkStep.cs
src/tools/illink/src/linker/Linker.Steps/MarkSubStepsDispatcher.cs
src/tools/illink/src/linker/Linker.Steps/OutputStep.cs
src/tools/illink/src/linker/Linker.Steps/OutputWarningSuppressions.cs
src/tools/illink/src/linker/Linker.Steps/ProcessLinkerXmlBase.cs
src/tools/illink/src/linker/Linker.Steps/ProcessWarningsStep.cs
src/tools/illink/src/linker/Linker.Steps/ReflectionBlockedStep.cs
src/tools/illink/src/linker/Linker.Steps/RemoveSecurityStep.cs
src/tools/illink/src/linker/Linker.Steps/SweepStep.cs
src/tools/illink/src/linker/Linker/AssemblyAction.cs
src/tools/illink/src/linker/Linker/DependencyInfo.cs
src/tools/illink/src/linker/Linker/DgmlDependencyRecorder.cs
src/tools/illink/src/linker/Linker/DocumentationSignatureGenerator.PartVisitor.cs
src/tools/illink/src/linker/Linker/DocumentationSignatureParser.cs
src/tools/illink/src/linker/Linker/Driver.cs
src/tools/illink/src/linker/Linker/DynamicDependency.cs
src/tools/illink/src/linker/Linker/FeatureSettings.cs
src/tools/illink/src/linker/Linker/LinkContext.cs
src/tools/illink/src/linker/Linker/MessageContainer.cs
src/tools/illink/src/linker/Linker/MessageOrigin.cs
src/tools/illink/src/linker/Linker/MethodReferenceExtensions.cs
src/tools/illink/src/linker/Linker/PInvokeInfo.cs
src/tools/illink/src/linker/Linker/RemoveAttributeInstancesAttribute.cs
src/tools/illink/src/linker/Linker/TypeDefinitionExtensions.cs
src/tools/illink/src/linker/Linker/TypeNameResolver.cs
src/tools/illink/src/linker/Linker/TypeReferenceWalker.cs
src/tools/illink/src/linker/Linker/UnconditionalSuppressMessageAttributeState.cs
src/tools/illink/src/linker/Linker/WarnVersion.cs
src/tools/illink/src/tlens/TLens.Analyzers/Analyzer.cs
src/tools/illink/src/tlens/TLens.Analyzers/UnnecessaryFieldsAssignmentAnalyzer.cs
src/tools/illink/src/tlens/TLens.Analyzers/UserOperatorCalledForNullCheckAnalyzer.cs
src/tools/illink/src/tlens/TLens/MethodDefinitionExtensions.cs

index 3b965ac..4a28e9d 100644 (file)
@@ -74,6 +74,7 @@ extends:
           - linux_x64
           jobParameters:
             testGroup: innerloop
+            testResultsFormat: 'vstest'
             timeoutInMinutes: 120
             nameSuffix: ILLink_Runtime_Testing
             condition:
index 146e49a..32db4d1 100644 (file)
@@ -8,7 +8,7 @@ using ILCompiler.Logging;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-    public readonly partial struct DiagnosticContext
+    internal readonly partial struct DiagnosticContext
     {
         public readonly MessageOrigin Origin;
         private readonly bool _diagnosticsEnabled;
index 555091d..abd6676 100644 (file)
@@ -18,7 +18,7 @@ using MultiValue = ILLink.Shared.DataFlow.ValueSet<ILLink.Shared.DataFlow.Single
 
 namespace ILCompiler.Dataflow
 {
-    public readonly struct GenericArgumentDataFlow
+    internal readonly struct GenericArgumentDataFlow
     {
         private readonly Logger _logger;
         private readonly NodeFactory _factory;
index 5e0f18a..bce75d7 100644 (file)
@@ -5,7 +5,7 @@ using Mono.Linker;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       public readonly partial struct DiagnosticContext
+       internal readonly partial struct DiagnosticContext
        {
                public readonly MessageOrigin Origin;
                public readonly bool DiagnosticsEnabled;
index bfb7ab5..42220a0 100644 (file)
@@ -15,7 +15,7 @@ namespace ILLink.Shared.TrimAnalysis
        ///  - Single-file warnings (suppressed by RequiresAssemblyFilesAttribute)
        /// Note that not all categories are used/supported by all tools, for example the ILLink only handles trimmer warnings and ignores the rest.
        /// </summary>
-       public readonly partial struct DiagnosticContext
+       internal readonly partial struct DiagnosticContext
        {
                /// <param name="id">The diagnostic ID, this will be used to determine the category of diagnostic (trimmer, AOT, single-file)</param>
                /// <param name="args">The arguments for diagnostic message.</param>
index a51e8f0..caefe78 100644 (file)
@@ -35,187 +35,11 @@ csharp_style_conditional_delegate_call = true:suggestion
 # Avoid redundant accessibility modifiers when they're default
 dotnet_style_require_accessibility_modifiers = omit_if_default:suggestion
 
-### Code Style Analyzers
-
-# IDE0004: Remove unnecessary cast
-dotnet_diagnostic.IDE0004.severity = warning
-
-# IDE0005: Remove unnecessary usings/imports
-dotnet_diagnostic.IDE0005.severity = warning
-
-# IDE0019: Use pattern matching
-dotnet_diagnostic.IDE0019.severity = warning
-
-# IDE0020: Use pattern matching
-dotnet_diagnostic.IDE0020.severity = warning
-
-# IDE0029: Null check can be simplified
-dotnet_diagnostic.IDE0029.severity = warning
-
-# IDE0031: Null check can be simplified
-dotnet_diagnostic.IDE0031.severity = warning
-
-# IDE0035: Remove unreachable code
-dotnet_diagnostic.IDE0035.severity = warning
-
-# IDE0036: Order modifiers
-dotnet_diagnostic.IDE0036.severity = warning
-
-# IDE0039: Prefer local functions over anonymous functions
-dotnet_diagnostic.IDE0039.severity = warning
-
-# IDE0041: Null check can be simplified
-dotnet_diagnostic.IDE0041.severity = warning
-
-# IDE0043: Format string contains invalid placeholder
-dotnet_diagnostic.IDE0043.severity = warning
-
-# IDE0044: Make field readonly
-dotnet_diagnostic.IDE0044.severity = warning
-
-# IDE0047: Parentheses can be removed
-dotnet_diagnostic.IDE0047.severity = warning
-
-# IDE0051: Remove unused private members (no reads or writes)
-dotnet_diagnostic.IDE0051.severity = warning
-
-# IDE0052: Remove unread private member
-dotnet_diagnostic.IDE0052.severity = warning
-
-# IDE0053: Prefer expression bodies for lambdas
-dotnet_diagnostic.IDE0053.severity = warning
-
-# IDE0054: Use compound assignment
-dotnet_diagnostic.IDE0054.severity = warning
-
-# IDE0059: Unnecessary assignment to a value
-dotnet_diagnostic.IDE0059.severity = warning
-
-# IDE0060: Remove unused parameter
-dotnet_diagnostic.IDE0060.severity = warning
-
-# IDE0062: Local function can be made static
-dotnet_diagnostic.IDE0062.severity = none
-
-# IDE0065: Using directives to be placed outside the namespace
-dotnet_diagnostic.IDE0065.severity = warning
-
-# IDE0073: File header
-dotnet_diagnostic.IDE0073.severity = warning
 file_header_template = Copyright (c) .NET Foundation and contributors. All rights reserved.\nLicensed under the MIT license. See LICENSE file in the project root for full license information.
 
-# IDE0074: Use compound assignment
-dotnet_diagnostic.IDE0074.severity = warning
-
-# IDE0082: Convert typeof to nameof
-dotnet_diagnostic.IDE0082.severity = warning
-
-# IDE0083: Use is not pattern matching
-#dotnet_diagnostic.IDE0083.severity = warning // requires new C# for Mono
-
-# IDE0100: Remove redundant equality
-dotnet_diagnostic.IDE0100.severity = none
-
-# IDE0110: Remove unnecessary discard
-dotnet_diagnostic.IDE0110.severity = warning
-
-# IDE0170: Simplify property pattern
-dotnet_diagnostic.IDE0170.severity = none
-
-# IDE0071: Interpolation can be simplified
-dotnet_diagnostic.IDE0071.severity = none
-
-# IDE0200: Lambda expression can be removed
-dotnet_diagnostic.IDE0200.severity = none
-
-## CA analyzer rules
-dotnet_analyzer_diagnostic.category-performance.severity = warning
-dotnet_analyzer_diagnostic.category-maintainability.severity = warning
-dotnet_analyzer_diagnostic.category-reliability.severity = warning
-dotnet_analyzer_diagnostic.category-usage.severity = warning
-#dotnet_analyzer_diagnostic.category-style.severity = warning
-
-# call GC.SuppressFinalize(object)
-dotnet_diagnostic.CA1816.severity = none
-
-# CA1834: Use 'StringBuilder.Append(char)'
-dotnet_diagnostic.CA1834.severity = none
-
-# CA1859: Change return type of method
-dotnet_diagnostic.CA1859.severity = none
-
-# CA1860: Prefer count to 0 rather than 'Any()'
-dotnet_diagnostic.CA1860.severity = none
-
-# RS2008 Ignore analyzer release tracking
-dotnet_diagnostic.RS2008.severity = none
-
-# Exception type is not sufficiently specific
-dotnet_diagnostic.CA2201.severity = none
-
-# xUnit1004: Test methods should not be skipped
-dotnet_diagnostic.xUnit1004.severity = none
-
-# CA1805: Member is explicitly initialized to it's default value
-dotnet_diagnostic.CA1805.severity = none
-
-# CA1066: Implement IEquatable when overriding Equals
-dotnet_diagnostic.CA1066.severity = none
-
-# CA1067: Override Equals because it implements IEquatable
-dotnet_diagnostic.CA1067.severity = none
-
-# CA1311: Specify culture version
-dotnet_diagnostic.CA1311.severity = none
-
-# CA3075: Unsafe overload of method
-dotnet_diagnostic.CA3075.severity = none
-
-## SA analyzer rules
+### Code Style Analyzers
 
 # Access modifier must be declared
 dotnet_diagnostic.SA1400.severity = none
 
-dotnet_diagnostic.SA1129.severity = none
-
-# SA1518: File is required to end with newline character
-dotnet_diagnostic.SA1518.severity = none
-
-# SA1205: Partial elements should declare access modifier
-dotnet_diagnostic.SA1205.severity = none
-
-# SA1027: Tabs and spaces should be used correctly
-dotnet_diagnostic.SA1027.severity = none
-
-# SA1121: Use built-in type alias
-dotnet_diagnostic.SA1121.severity = none
-
-# SA1028: Code should not contain trailing whitespace
-dotnet_diagnostic.SA1028.severity = none
-
-# SA1212: A get accessor appears after a set accessor
-dotnet_diagnostic.SA1212.severity = none
-
-# SA1001: Commas should not be preceded by whitespace
-dotnet_diagnostic.SA1001.severity = none
-
-[src/linker/ref/**/*.cs]
-
-# CA1822: Mark members as static
-dotnet_diagnostic.CA1822.severity = none
-
-# IDE0060: Remove unused parameter
-dotnet_diagnostic.IDE0060.severity = none
-
-[test/**/*.cs]
-dotnet_diagnostic.IDE0060.severity = none
-
-[test/Mono.Linker.Tests/TestCases/Dependencies/WarningSuppressionExpectations*.cs]
 dotnet_diagnostic.IDE0073.severity = none
-
-[external**]
-dotnet_diagnostic.IDE0073.severity = none
-
-[external**]
-dotnet_analyzer_diagnostic.severity = none
-generated_code = true
index 4873318..b8fe76c 100644 (file)
@@ -97,7 +97,7 @@ namespace System.Reflection
 
                        // App-compat: You can use double or single quotes to quote a name, and Fusion (or rather the IdentityAuthority) picks one
                        // by some algorithm. Rather than guess at it, we use double quotes consistently.
-                       if (s != s.Trim() || s.Contains("\"") || s.Contains("\'"))
+                       if (s != s.Trim() || s.Contains('"') || s.Contains('\''))
                                needsQuoting = true;
 
                        if (needsQuoting)
@@ -153,4 +153,4 @@ namespace System.Reflection
                        new KeyValuePair<char, string>('t', "\t"),
                };
        }
-}
\ No newline at end of file
+}
index 9b9c1a7..d6db056 100644 (file)
@@ -16,7 +16,7 @@ namespace System.Reflection
                //
                // These helpers convert between the combined flags+contentType+processorArchitecture value and the separated parts.
                //
-               // Since these are only for trusted callers, they do NOT check for out of bound bits. 
+               // Since these are only for trusted callers, they do NOT check for out of bound bits.
                //
 
                internal static AssemblyContentType ExtractAssemblyContentType(this AssemblyNameFlags flags)
@@ -39,4 +39,4 @@ namespace System.Reflection
                        return (AssemblyNameFlags)(((int)flags) | (((int)contentType) << 9) | ((int)processorArchitecture << 4));
                }
        }
-}
\ No newline at end of file
+}
index 5ef3d59..060f605 100644 (file)
@@ -23,20 +23,19 @@ namespace System.Reflection
                }
 
                //
-               // Return the next token in assembly name. If you expect the result to be DisplayNameToken.String, 
+               // Return the next token in assembly name. If you expect the result to be DisplayNameToken.String,
                // use GetNext(out String) instead.
                //
                internal Token GetNext()
                {
-                       string ignore;
-                       return GetNext(out ignore);
+                       return GetNext(out _);
                }
 
                //
-               // Return the next token in assembly name. If the result is DisplayNameToken.String, 
+               // Return the next token in assembly name. If the result is DisplayNameToken.String,
                // sets "tokenString" to the tokenized string.
                //
-               internal Token GetNext(out string tokenString)
+               internal Token GetNext(out string? tokenString)
                {
                        tokenString = null;
                        while (char.IsWhiteSpace(_chars[_index]))
@@ -121,4 +120,4 @@ namespace System.Reflection
                private readonly char[] _chars;
                private int _index;
        }
-}
\ No newline at end of file
+}
index 7bb5319..b746336 100644 (file)
@@ -26,7 +26,7 @@ namespace System.Reflection
                        AssemblyNameLexer lexer = new AssemblyNameLexer(s);
 
                        // Name must come first.
-                       string name;
+                       string? name;
                        AssemblyNameLexer.Token token = lexer.GetNext(out name);
                        if (token != AssemblyNameLexer.Token.String)
                                throw new FileLoadException();
@@ -34,9 +34,9 @@ namespace System.Reflection
                        if (string.IsNullOrEmpty(name) || name.IndexOfAny(s_illegalCharactersInSimpleName) != -1)
                                throw new FileLoadException();
 
-                       Version version = null;
-                       string cultureName = null;
-                       byte[] pkt = null;
+                       Version? version = null;
+                       string? cultureName = null;
+                       byte[]? pkt = null;
                        AssemblyNameFlags flags = 0;
 
                        List<string> alreadySeen = new List<string>();
@@ -45,7 +45,7 @@ namespace System.Reflection
                        {
                                if (token != AssemblyNameLexer.Token.Comma)
                                        throw new FileLoadException();
-                               string attributeName;
+                               string? attributeName;
                                token = lexer.GetNext(out attributeName);
                                if (token != AssemblyNameLexer.Token.String)
                                        throw new FileLoadException();
@@ -59,12 +59,12 @@ namespace System.Reflection
 
                                if (token != AssemblyNameLexer.Token.Equals)
                                        throw new FileLoadException();
-                               string attributeValue;
+                               string? attributeValue;
                                token = lexer.GetNext(out attributeValue);
                                if (token != AssemblyNameLexer.Token.String)
                                        throw new FileLoadException();
 
-                               if (String.IsNullOrEmpty(attributeName))
+                               if (string.IsNullOrEmpty(attributeName))
                                        throw new FileLoadException();
 
                                for (int i = 0; i < alreadySeen.Count; i++)
@@ -72,6 +72,7 @@ namespace System.Reflection
                                        if (alreadySeen[i].Equals(attributeName, StringComparison.OrdinalIgnoreCase))
                                                throw new FileLoadException(); // Cannot specify the same attribute twice.
                                }
+                               Debug.Assert(attributeValue is not null);
                                alreadySeen.Add(attributeName);
                                if (attributeName.Equals("Version", StringComparison.OrdinalIgnoreCase))
                                {
@@ -116,7 +117,7 @@ namespace System.Reflection
                                // Desktop compat: If we got here, the attribute name is unknown to us. Ignore it (as long it's not duplicated.)
                                token = lexer.GetNext();
                        }
-                       return new RuntimeAssemblyName(name, version, cultureName, flags, pkt);
+                       return new RuntimeAssemblyName(name!, version!, cultureName!, flags, pkt!);
                }
 
                private static Version ParseVersion(string attributeValue)
@@ -213,4 +214,4 @@ namespace System.Reflection
 
                private static readonly char[] s_illegalCharactersInSimpleName = { '/', '\\', ':' };
        }
-}
\ No newline at end of file
+}
index 561e938..4c340ea 100644 (file)
@@ -51,7 +51,7 @@ namespace System.Reflection
                // Equality - this compares every bit of data in the RuntimeAssemblyName which is acceptable for use as keys in a cache
                // where semantic duplication is permissible. This method is *not* meant to define ref->def binding rules or
                // assembly binding unification rules.
-               public bool Equals(RuntimeAssemblyName other)
+               public bool Equals(RuntimeAssemblyName? other)
                {
                        if (other == null)
                                return false;
@@ -99,9 +99,9 @@ namespace System.Reflection
                        return true;
                }
 
-               public sealed override bool Equals(object obj)
+               public sealed override bool Equals(object? obj)
                {
-                       RuntimeAssemblyName other = obj as RuntimeAssemblyName;
+                       RuntimeAssemblyName? other = obj as RuntimeAssemblyName;
                        if (other == null)
                                return false;
                        return Equals(other);
@@ -120,4 +120,4 @@ namespace System.Reflection
                        }
                }
        }
-}
\ No newline at end of file
+}
index 4a24297..ba04548 100644 (file)
@@ -10,7 +10,7 @@ namespace System.Reflection.Runtime.TypeParsing
        //
        internal sealed class TypeLexer
        {
-               public TypeLexer(String s)
+               public TypeLexer(string s)
                {
                        // Turn the string into a char array with a NUL terminator.
                        char[] chars = new char[s.Length + 1];
@@ -35,7 +35,7 @@ namespace System.Reflection.Runtime.TypeParsing
                        {
                                SkipWhiteSpace();
                                int index = _index + 1;
-                               while (Char.IsWhiteSpace(_chars[index]))
+                               while (char.IsWhiteSpace(_chars[index]))
                                        index++;
                                char c = _chars[index];
                                return CharToToken(c);
@@ -68,7 +68,7 @@ namespace System.Reflection.Runtime.TypeParsing
                //
                // Terminated by the first non-escaped reserved character ('[', ']', '+', '&', '*' or ',')
                //
-               public String GetNextIdentifier()
+               public string GetNextIdentifier()
                {
                        SkipWhiteSpace();
 
@@ -94,12 +94,12 @@ namespace System.Reflection.Runtime.TypeParsing
                                                // Common sense would dictate throwing an ArgumentException but that's not what the desktop CLR does.
                                                // The desktop CLR treats this case by returning FALSE from TypeName::TypeNameParser::GetIdentifier().
                                                // Unfortunately, no one checks this return result. Instead, the CLR keeps parsing (unfortunately, the lexer
-                                               // was left in some strange state by the previous failure but typically, this goes unnoticed) and eventually, tries to resolve 
+                                               // was left in some strange state by the previous failure but typically, this goes unnoticed) and eventually, tries to resolve
                                                // a Type whose name is the empty string. When it can't resolve that type, the CLR throws a TypeLoadException()
                                                // complaining about be unable to find a type with the empty name.
                                                //
                                                // To emulate this accidental behavior, we'll throw a special exception that's caught by the TypeParser.
-                                               // 
+                                               //
                                                throw new IllegalEscapeSequenceException();
                                        }
                                }
@@ -107,11 +107,11 @@ namespace System.Reflection.Runtime.TypeParsing
                        }
 
                        _index = src;
-                       return new String(buffer, 0, dst);
+                       return new string(buffer, 0, dst);
                }
 
                //
-               // Lex the next segment as the assembly name at the end of an assembly-qualified type name. (Do not use for 
+               // Lex the next segment as the assembly name at the end of an assembly-qualified type name. (Do not use for
                // assembly names embedded inside generic type arguments.)
                //
                // Terminated by NUL. There are no escape characters defined by the typename lexer (however, AssemblyName
@@ -133,14 +133,14 @@ namespace System.Reflection.Runtime.TypeParsing
                                buffer[dst++] = c;
                        }
                        _index = src;
-                       String fullName = new String(buffer, 0, dst);
+                       string fullName = new string(buffer, 0, dst);
                        return AssemblyNameParser.Parse(fullName);
                }
 
                //
                // Lex the next segment as an assembly name embedded inside a generic argument type.
                //
-               // Terminated by an unescaped ']'. 
+               // Terminated by an unescaped ']'.
                //
                public RuntimeAssemblyName GetNextEmbeddedAssemblyName()
                {
@@ -167,7 +167,7 @@ namespace System.Reflection.Runtime.TypeParsing
                                buffer[dst++] = c;
                        }
                        _index = src;
-                       String fullName = new String(buffer, 0, dst);
+                       var fullName = new string(buffer, 0, dst);
                        return AssemblyNameParser.Parse(fullName);
                }
 
@@ -198,8 +198,8 @@ namespace System.Reflection.Runtime.TypeParsing
                }
 
                //
-               // The desktop typename parser has a strange attitude towards whitespace. It throws away whitespace between punctuation tokens and whitespace 
-               // preceeding identifiers or assembly names (and this cannot be escaped away). But whitespace between the end of an identifier 
+               // The desktop typename parser has a strange attitude towards whitespace. It throws away whitespace between punctuation tokens and whitespace
+               // preceeding identifiers or assembly names (and this cannot be escaped away). But whitespace between the end of an identifier
                // and the punctuation that ends it is *not* ignored.
                //
                // In other words, GetType("   Foo") searches for "Foo" but GetType("Foo   ") searches for "Foo   ".
@@ -209,7 +209,7 @@ namespace System.Reflection.Runtime.TypeParsing
                //
                private void SkipWhiteSpace()
                {
-                       while (Char.IsWhiteSpace(_chars[_index]))
+                       while (char.IsWhiteSpace(_chars[_index]))
                                _index++;
                }
 
@@ -235,4 +235,4 @@ namespace System.Reflection.Runtime.TypeParsing
                Ampersand = 6,        //'&'
                Other = 7,            //Type identifier, AssemblyName or embedded AssemblyName.
        }
-}
\ No newline at end of file
+}
index 9c42d01..a8d20ae 100644 (file)
@@ -7,7 +7,7 @@ using System.Collections.Generic;
 namespace System.Reflection.Runtime.TypeParsing
 {
        //
-       // The TypeName class is the base class for a family of types that represent the nodes in a parse tree for 
+       // The TypeName class is the base class for a family of types that represent the nodes in a parse tree for
        // assembly-qualified type names.
        //
        public abstract class TypeName
@@ -206,7 +206,7 @@ namespace System.Reflection.Runtime.TypeParsing
                        {
                                s += sep;
                                sep = ",";
-                               AssemblyQualifiedTypeName assemblyQualifiedTypeArgument = genericTypeArgument as AssemblyQualifiedTypeName;
+                               AssemblyQualifiedTypeName? assemblyQualifiedTypeArgument = genericTypeArgument as AssemblyQualifiedTypeName;
                                if (assemblyQualifiedTypeArgument == null || assemblyQualifiedTypeArgument.AssemblyName == null)
                                        s += genericTypeArgument.ToString();
                                else
@@ -216,4 +216,4 @@ namespace System.Reflection.Runtime.TypeParsing
                        return s;
                }
        }
-}
\ No newline at end of file
+}
index 218c252..712bfdd 100644 (file)
@@ -7,14 +7,14 @@ using System.Collections.Generic;
 namespace System.Reflection.Runtime.TypeParsing
 {
        //
-       // Parser for type names passed to GetType() apis. 
+       // Parser for type names passed to GetType() apis.
        //
        public sealed class TypeParser
        {
                //
                // Parses a typename. The typename may be optionally postpended with a "," followed by a legal assembly name.
                //
-               public static TypeName ParseTypeName(string s)
+               public static TypeName? ParseTypeName(string s)
                {
                        try
                        {
@@ -29,15 +29,15 @@ namespace System.Reflection.Runtime.TypeParsing
                //
                // Parses a typename. The typename may be optionally postpended with a "," followed by a legal assembly name.
                //
-               private static TypeName ParseAssemblyQualifiedTypeName(String s)
-        {
+               private static TypeName? ParseAssemblyQualifiedTypeName(string s)
+               {
                        if (string.IsNullOrEmpty(s))
                                return null;
 
                        // Desktop compat: a whitespace-only "typename" qualified by an assembly name throws an ArgumentException rather than
                        // a TypeLoadException.
                        int idx = 0;
-                       while (idx < s.Length && Char.IsWhiteSpace(s[idx]))
+                       while (idx < s.Length && char.IsWhiteSpace(s[idx]))
                        {
                                idx++;
                        }
@@ -64,11 +64,11 @@ namespace System.Reflection.Runtime.TypeParsing
                        catch (TypeLexer.IllegalEscapeSequenceException)
                        {
                                // Emulates a CLR4.5 bug that causes any string that contains an illegal escape sequence to be parsed as the empty string.
-                               return ParseAssemblyQualifiedTypeName(String.Empty);
+                               return ParseAssemblyQualifiedTypeName(string.Empty);
                        }
                }
 
-               private TypeParser(String s)
+               private TypeParser(string s)
                {
                        _lexer = new TypeLexer(s);
                }
@@ -161,14 +161,14 @@ namespace System.Reflection.Runtime.TypeParsing
 
                //
                // Foo or Foo+Inner
-               // 
+               //
                private NamedTypeName ParseNamedTypeName()
                {
                        NamedTypeName namedType = ParseNamespaceTypeName();
                        while (_lexer.Peek == TokenType.Plus)
                        {
                                _lexer.Skip();
-                               String nestedTypeName = _lexer.GetNextIdentifier();
+                               string nestedTypeName = _lexer.GetNextIdentifier();
                                namedType = new NestedTypeName(nestedTypeName, namedType);
                        }
                        return namedType;
@@ -176,7 +176,7 @@ namespace System.Reflection.Runtime.TypeParsing
 
                //
                // Non-nested named type.
-               // 
+               //
                private NamespaceTypeName ParseNamespaceTypeName()
                {
                        string fullName = _lexer.GetNextIdentifier();
@@ -202,7 +202,7 @@ namespace System.Reflection.Runtime.TypeParsing
                        }
                        else if (token == TokenType.OpenSqBracket)
                        {
-                               RuntimeAssemblyName assemblyName = null;
+                               RuntimeAssemblyName? assemblyName = null;
                                NonQualifiedTypeName typeName = ParseNonQualifiedTypeName();
                                token = _lexer.GetNextToken();
                                if (token == TokenType.Comma)
@@ -223,4 +223,4 @@ namespace System.Reflection.Runtime.TypeParsing
 
                private readonly TypeLexer _lexer;
        }
-}
\ No newline at end of file
+}
index 249dd1c..28d82ba 100644 (file)
@@ -63,21 +63,21 @@ namespace ILLink.CodeFix
 
                public sealed override ImmutableArray<string> FixableDiagnosticIds => SupportedDiagnostics.Select (dd => dd.Id).ToImmutableArray ();
 
-               private static LocalizableString CodeFixTitle => new LocalizableResourceString (nameof (Resources.DynamicallyAccessedMembersCodeFixTitle), Resources.ResourceManager, typeof (Resources));
+               private static LocalizableResourceString CodeFixTitle => new LocalizableResourceString (nameof (Resources.DynamicallyAccessedMembersCodeFixTitle), Resources.ResourceManager, typeof (Resources));
 
                private static string FullyQualifiedAttributeName => DynamicallyAccessedMembersAnalyzer.FullyQualifiedDynamicallyAccessedMembersAttribute;
 
                private static readonly string[] AttributeOnReturn = {
                        DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter.AsString (),
-                       DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType.AsString() ,
+                       DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType.AsString(),
                        DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsField.AsString (),
-                       DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter.AsString () ,
+                       DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter.AsString (),
                        DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides.AsString ()
                };
 
                private static readonly string[] AttributeOnGeneric = {
                        DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsParameter.AsString(),
-                       DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType.AsString () ,
+                       DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType.AsString (),
                        DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsField.AsString(),
                        DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsThisParameter.AsString(),
                        DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter.AsString(),
index f4f1c85..d97038d 100644 (file)
@@ -24,4 +24,4 @@ namespace Microsoft.CodeAnalysis.FlowAnalysis
                        }
                }
        }
-}
\ No newline at end of file
+}
index 9714223..94ee978 100644 (file)
@@ -7,7 +7,7 @@ using Microsoft.CodeAnalysis;
 
 namespace ILLink.RoslynAnalyzer.DataFlow
 {
-       public struct CapturedReferenceValue : IEquatable<CapturedReferenceValue>
+       public readonly struct CapturedReferenceValue : IEquatable<CapturedReferenceValue>
        {
                public readonly IOperation? Reference;
 
@@ -35,12 +35,18 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                }
 
                public bool Equals (CapturedReferenceValue other) => Reference == other.Reference;
+
+               public override bool Equals (object obj)
+                       => obj is CapturedReferenceValue inst && Equals (inst);
+
+               public override int GetHashCode ()
+                       => Reference?.GetHashCode () ?? 0;
        }
 
 
        public struct CapturedReferenceLattice : ILattice<CapturedReferenceValue>
        {
-               public CapturedReferenceValue Top => new CapturedReferenceValue ();
+               public CapturedReferenceValue Top => default;
 
                public CapturedReferenceValue Meet (CapturedReferenceValue left, CapturedReferenceValue right)
                {
@@ -55,4 +61,4 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                        throw new InvalidOperationException ();
                }
        }
-}
\ No newline at end of file
+}
index 84d4dc2..498bdf8 100644 (file)
@@ -197,4 +197,4 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                public BlockProxy LastBlock (RegionProxy region) =>
                        new BlockProxy (ControlFlowGraph.Blocks[region.Region.LastBlockOrdinal]);
        }
-}
\ No newline at end of file
+}
index 54ab776..11aba46 100644 (file)
@@ -38,6 +38,12 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                public bool Equals (InterproceduralState<TValue, TValueLattice> other)
                        => Methods.Equals (other.Methods) && HoistedLocals.Equals (other.HoistedLocals);
 
+               public override bool Equals (object obj)
+                       => obj is InterproceduralState<TValue, TValueLattice> inst && Equals (inst);
+
+               public override int GetHashCode ()
+                       => throw new NotImplementedException ();
+
                public InterproceduralState<TValue, TValueLattice> Clone ()
                        => new (Methods.Clone (),
                        HoistedLocals.Clone (), lattice);
@@ -103,4 +109,4 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                                HoistedLocalLattice.Meet (left.HoistedLocals, right.HoistedLocals),
                                this);
        }
-}
\ No newline at end of file
+}
index 6b9c8bb..80629ae 100644 (file)
@@ -44,8 +44,8 @@ namespace ILLink.RoslynAnalyzer.DataFlow
 
                public void InterproceduralAnalyze ()
                {
-                       var methodGroupLattice = new ValueSetLattice<MethodBodyValue> ();
-                       var hoistedLocalLattice = new DictionaryLattice<LocalKey, Maybe<TValue>, MaybeLattice<TValue, TLattice>> ();
+                       ValueSetLattice<MethodBodyValue> methodGroupLattice = default;
+                       DictionaryLattice<LocalKey, Maybe<TValue>, MaybeLattice<TValue, TLattice>> hoistedLocalLattice = default;
                        var interproceduralStateLattice = new InterproceduralStateLattice<TValue, TLattice> (
                                methodGroupLattice, hoistedLocalLattice);
                        var interproceduralState = interproceduralStateLattice.Top;
@@ -89,4 +89,4 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                        ImmutableDictionary<CaptureId, FlowCaptureKind> lValueFlowCaptures,
                        InterproceduralState<TValue, TLattice> interproceduralState);
        }
-}
\ No newline at end of file
+}
index eee0441..b46d00e 100644 (file)
@@ -282,7 +282,7 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                                // (don't have specific I*Operation types), such as pointer dereferences.
                                if (targetOperation.Kind is OperationKind.None)
                                        break;
-                               throw new NotImplementedException ($"{targetOperation.GetType ().ToString ()}: {targetOperation.Syntax.GetLocation ().GetLineSpan ()}");
+                               throw new NotImplementedException ($"{targetOperation.GetType ()}: {targetOperation.Syntax.GetLocation ().GetLineSpan ()}");
                        }
                        return Visit (operation.Value, state);
                }
@@ -293,7 +293,7 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                        if (!operation.GetValueUsageInfo (Method).HasFlag (ValueUsageInfo.Read)) {
                                // There are known cases where this assert doesn't hold, because LValueFlowCaptureProvider
                                // produces the wrong result in some cases for flow captures with IsInitialization = true.
-                               // https://github.com/dotnet/linker/issues/2749 
+                               // https://github.com/dotnet/linker/issues/2749
                                // Debug.Assert (IsLValueFlowCapture (operation.Id));
                                return TopValue;
                        }
index e26a965..6b5677d 100644 (file)
@@ -21,6 +21,12 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                public bool Equals (LocalKey other) => SymbolEqualityComparer.Default.Equals (Local, other.Local) &&
                        (CaptureId?.Equals (other.CaptureId) ?? other.CaptureId == null);
 
+               public override bool Equals (object obj)
+                       => obj is LocalKey inst && Equals (inst);
+
+               public override int GetHashCode ()
+                       => CaptureId is null ? SymbolEqualityComparer.Default.GetHashCode (Local) : CaptureId.GetHashCode ();
+
                public override string ToString ()
                {
                        if (Local != null)
@@ -41,7 +47,7 @@ namespace ILLink.RoslynAnalyzer.DataFlow
 
                public LocalState (TValue defaultValue)
                        : this (new DefaultValueDictionary<LocalKey, TValue> (defaultValue),
-                               new DefaultValueDictionary<CaptureId, CapturedReferenceValue> (new CapturedReferenceValue ()))
+                               new DefaultValueDictionary<CaptureId, CapturedReferenceValue> (default (CapturedReferenceValue)))
                {
                }
 
@@ -52,14 +58,20 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                }
 
                public LocalState (DefaultValueDictionary<LocalKey, TValue> dictionary)
-                       : this (dictionary, new DefaultValueDictionary<CaptureId, CapturedReferenceValue> (new CapturedReferenceValue ()))
+                       : this (dictionary, new DefaultValueDictionary<CaptureId, CapturedReferenceValue> (default (CapturedReferenceValue)))
                {
                }
 
                public bool Equals (LocalState<TValue> other) => Dictionary.Equals (other.Dictionary);
 
+               public override bool Equals (object obj)
+                       => obj is LocalState<TValue> inst && Equals (inst);
+
                public TValue Get (LocalKey key) => Dictionary.Get (key);
 
+               public override int GetHashCode ()
+                       => throw new NotImplementedException ();
+
                public void Set (LocalKey key, TValue value) => Dictionary.Set (key, value);
 
                public override string ToString () => Dictionary.ToString ();
@@ -76,7 +88,7 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                public LocalStateLattice (TValueLattice valueLattice)
                {
                        Lattice = new DictionaryLattice<LocalKey, TValue, TValueLattice> (valueLattice);
-                       CapturedReferenceLattice = new DictionaryLattice<CaptureId, CapturedReferenceValue, CapturedReferenceLattice> (new CapturedReferenceLattice ());
+                       CapturedReferenceLattice = new DictionaryLattice<CaptureId, CapturedReferenceValue, CapturedReferenceLattice> (default (CapturedReferenceLattice));
                        Top = new (Lattice.Top);
                }
 
index aba4b6f..99fe326 100644 (file)
@@ -30,5 +30,10 @@ namespace ILLink.RoslynAnalyzer.DataFlow
                        Debug.Assert (ControlFlowGraph == other.ControlFlowGraph);
                        return true;
                }
+
+               public override bool Equals (object obj)
+                       => obj is MethodBodyValue inst && Equals (inst);
+
+               public override int GetHashCode () => SymbolEqualityComparer.Default.GetHashCode (Method);
        }
-}
\ No newline at end of file
+}
index b372d4f..cd9017c 100644 (file)
@@ -172,7 +172,7 @@ namespace ILLink.RoslynAnalyzer
                                throw new NotImplementedException ();
 
                        var diagnosticContext = new DiagnosticContext (location);
-                       var requireDynamicallyAccessedMembersAction = new RequireDynamicallyAccessedMembersAction (diagnosticContext, new ReflectionAccessAnalyzer ());
+                       var requireDynamicallyAccessedMembersAction = new RequireDynamicallyAccessedMembersAction (diagnosticContext, default (ReflectionAccessAnalyzer));
                        requireDynamicallyAccessedMembersAction.Invoke (sourceValue, targetWithDynamicallyAccessedMembers);
 
                        return diagnosticContext.Diagnostics;
index cc61d3c..c656ff0 100644 (file)
@@ -69,4 +69,4 @@ namespace ILLink.RoslynAnalyzer
                        return method.Parameters.Length + (method.HasImplicitThis () ? 1 : 0);
                }
        }
-}
\ No newline at end of file
+}
index 8e472f4..7367025 100644 (file)
@@ -17,25 +17,24 @@ namespace ILLink.RoslynAnalyzer
                public static ValueUsageInfo GetValueUsageInfo (this IOperation operation, ISymbol containingSymbol)
                {
                        /*
-            |    code                  | Read | Write | ReadableRef | WritableRef | NonReadWriteRef |
-            | x.Prop = 1               |      |  ✔️   |             |             |                 |
-            | x.Prop += 1              |  ✔️  |  ✔️   |             |             |                 |
-            | x.Prop++                 |  ✔️  |  ✔️   |             |             |                 |
-            | Foo(x.Prop)              |  ✔️  |       |             |             |                 |
-            | Foo(x.Prop),             |      |       |     ✔️      |             |                 |
-               where void Foo(in T v)
-            | Foo(out x.Prop)          |      |       |             |     ✔️      |                 |
-            | Foo(ref x.Prop)          |      |       |     ✔️      |     ✔️      |                 |
-            | nameof(x)                |      |       |             |             |       ✔️        | ️
-            | sizeof(x)                |      |       |             |             |       ✔️        | ️
-            | typeof(x)                |      |       |             |             |       ✔️        | ️
-            | out var x                |      |  ✔️   |             |             |                 | ️
-            | case X x:                |      |  ✔️   |             |             |                 | ️
-            | obj is X x               |      |  ✔️   |             |             |                 |
-            | ref var x =              |      |       |     ✔️      |     ✔️      |                 |
-            | ref readonly var x =     |      |       |     ✔️      |             |                 |
-
-            */
+                       |    code                  | Read | Write | ReadableRef | WritableRef | NonReadWriteRef |
+                       | x.Prop = 1               |      |  ✔️   |             |             |                 |
+                       | x.Prop += 1              |  ✔️  |  ✔️   |             |             |                 |
+                       | x.Prop++                 |  ✔️  |  ✔️   |             |             |                 |
+                       | Foo(x.Prop)              |  ✔️  |       |             |             |                 |
+                       | Foo(x.Prop),             |      |       |     ✔️      |             |                 |
+                          where void Foo(in T v)
+                       | Foo(out x.Prop)          |      |       |             |     ✔️      |                 |
+                       | Foo(ref x.Prop)          |      |       |     ✔️      |     ✔️      |                 |
+                       | nameof(x)                |      |       |             |             |       ✔️        | ️
+                       | sizeof(x)                |      |       |             |             |       ✔️        | ️
+                       | typeof(x)                |      |       |             |             |       ✔️        | ️
+                       | out var x                |      |  ✔️   |             |             |                 | ️
+                       | case X x:                |      |  ✔️   |             |             |                 | ️
+                       | obj is X x               |      |  ✔️   |             |             |                 |
+                       | ref var x =              |      |       |     ✔️      |     ✔️      |                 |
+                       | ref readonly var x =     |      |       |     ✔️      |             |                 |
+                       */
                        if (operation is ILocalReferenceOperation localReference &&
                                localReference.IsDeclaration &&
                                !localReference.IsImplicit) // Workaround for https://github.com/dotnet/roslyn/issues/30753
index 24cb456..e7e6447 100644 (file)
@@ -29,4 +29,4 @@ namespace ILLink.RoslynAnalyzer
                        return setMethod;
                }
        }
-}
\ No newline at end of file
+}
index c3aff3c..7e830f7 100644 (file)
@@ -109,7 +109,7 @@ namespace ILLink.RoslynAnalyzer
                        switch (symbol) {
                        case IFieldSymbol fieldSymbol:
                                sb.Append (fieldSymbol.ContainingSymbol.ToDisplayString (ILLinkTypeDisplayFormat));
-                               sb.Append (".");
+                               sb.Append ('.');
                                sb.Append (fieldSymbol.MetadataName);
                                break;
 
@@ -131,7 +131,7 @@ namespace ILLink.RoslynAnalyzer
                                        // don't include the containing type's name. This matches the behavior of
                                        // CSharpErrorMessageFormat.
                                        sb.Append (methodSymbol.ContainingType.ToDisplayString (ILLinkTypeDisplayFormat));
-                                       sb.Append (".");
+                                       sb.Append ('.');
                                }
                                // Format parameter types with only type names.
                                sb.Append (methodSymbol.ToDisplayString (ILLinkMemberDisplayFormat));
index af53109..49c85c7 100644 (file)
@@ -357,7 +357,7 @@ namespace ILLink.RoslynAnalyzer
                /// </summary>
                /// <param name="compilation">Compilation to search for members</param>
                /// <returns>A list of special incomptaible members</returns>
-               protected virtual ImmutableArray<ISymbol> GetSpecialIncompatibleMembers (Compilation compilation) => new ImmutableArray<ISymbol> ();
+               protected virtual ImmutableArray<ISymbol> GetSpecialIncompatibleMembers (Compilation compilation) => default;
 
                /// <summary>
                /// Verifies that the MSBuild requirements to run the analyzer are fulfilled
index db32750..d739bcc 100644 (file)
@@ -92,7 +92,7 @@ namespace ILLink.RoslynAnalyzer
                }
 
                protected override bool VerifyAttributeArguments (AttributeData attribute) => attribute.ConstructorArguments.Length == 0 ||
-                       attribute.ConstructorArguments.Length >= 1 && attribute.ConstructorArguments[0] is { Type: { SpecialType: SpecialType.System_String } } ctorArg;
+                       attribute.ConstructorArguments.Length >= 1 && attribute.ConstructorArguments[0] is { Type.SpecialType: SpecialType.System_String } ctorArg;
 
                protected override string GetMessageFromAttribute (AttributeData requiresAttribute)
                {
index e3a781d..9629a81 100644 (file)
@@ -37,7 +37,7 @@ namespace ILLink.RoslynAnalyzer
                        options.IsMSBuildPropertyValueTrue (MSBuildPropertyOptionNames.EnableAotAnalyzer, compilation);
 
                protected override bool VerifyAttributeArguments (AttributeData attribute) =>
-                       attribute.ConstructorArguments.Length >= 1 && attribute.ConstructorArguments[0] is { Type: { SpecialType: SpecialType.System_String } } ctorArg;
+                       attribute.ConstructorArguments.Length >= 1 && attribute.ConstructorArguments[0] is { Type.SpecialType: SpecialType.System_String } ctorArg;
 
                protected override string GetMessageFromAttribute (AttributeData? requiresAttribute)
                {
index a6e8bb8..bd6bacb 100644 (file)
@@ -39,7 +39,7 @@ namespace ILLink.RoslynAnalyzer
                /// Doesn't check the associated symbol for overrides and virtual methods because the analyzer should warn on mismatched between the property AND the accessors
                /// </summary>
                /// <param name="member">
-               ///     Symbol that is either an overriding member or an overriden/virtual member
+               /// Symbol that is either an overriding member or an overriden/virtual member
                /// </param>
                public static bool IsOverrideInRequiresScope (this ISymbol member, string requiresAttribute)
                {
index d6b17d0..a776b45 100644 (file)
@@ -34,7 +34,7 @@ namespace ILLink.RoslynAnalyzer
                /// <param name="attribute">Attribute data to compare.</param>
                /// <returns>True if the validation was successfull; otherwise, returns false.</returns>
                public static bool VerifyRequiresUnreferencedCodeAttributeArguments (AttributeData attribute)
-                       => attribute.ConstructorArguments.Length >= 1 && attribute.ConstructorArguments[0] is { Type: { SpecialType: SpecialType.System_String } } ctorArg;
+                       => attribute.ConstructorArguments.Length >= 1 && attribute.ConstructorArguments[0] is { Type.SpecialType: SpecialType.System_String } ctorArg;
 
                public static string GetMessageFromAttribute (AttributeData? requiresAttribute)
                {
@@ -42,4 +42,4 @@ namespace ILLink.RoslynAnalyzer
                        return MessageFormat.FormatRequiresAttributeMessageArg (message);
                }
        }
-}
\ No newline at end of file
+}
index a9a9547..835a60e 100644 (file)
@@ -7,7 +7,7 @@ using MultiValue = ILLink.Shared.DataFlow.ValueSet<ILLink.Shared.DataFlow.Single
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       partial record ArrayValue
+       internal partial record ArrayValue
        {
                public readonly Dictionary<int, MultiValue> IndexValues;
 
index f920a2e..d269dfe 100644 (file)
@@ -9,7 +9,7 @@ using Microsoft.CodeAnalysis;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       readonly partial struct DiagnosticContext
+       internal readonly partial struct DiagnosticContext
        {
                public List<Diagnostic> Diagnostics { get; } = new ();
 
index 03feb9b..c6a315c 100644 (file)
@@ -9,7 +9,7 @@ using Microsoft.CodeAnalysis;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       partial record FieldValue
+       internal partial record FieldValue
        {
                public FieldValue (IFieldSymbol fieldSymbol) => FieldSymbol = fieldSymbol;
 
index b918a18..f895879 100644 (file)
@@ -11,7 +11,7 @@ using Microsoft.CodeAnalysis;
 #nullable enable
 namespace ILLink.Shared.TrimAnalysis
 {
-       sealed partial class FlowAnnotations
+       internal sealed partial class FlowAnnotations
        {
                // In the analyzer there's no stateful data the flow annotations need to store
                // so we just create a singleton on demand.
index e4bd90b..2156d71 100644 (file)
@@ -13,7 +13,7 @@ namespace ILLink.Shared.TrimAnalysis
        /// This is a System.Type value which represents generic parameter (basically result of typeof(T))
        /// Its actual type is unknown, but it can have annotations.
        /// </summary>
-       partial record GenericParameterValue
+       internal partial record GenericParameterValue
        {
                public GenericParameterValue (ITypeParameterSymbol typeParameterSymbol) => GenericParameter = new (typeParameterSymbol);
 
index 318e9a0..96c4a07 100644 (file)
@@ -12,7 +12,7 @@ using Microsoft.CodeAnalysis;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       partial struct HandleCallAction
+       internal partial struct HandleCallAction
        {
 #pragma warning disable CA1822 // Mark members as static - the other partial implementations might need to be instance methods
 #pragma warning disable IDE0060 // Unused parameters - the other partial implementation may need the parameter
@@ -27,7 +27,7 @@ namespace ILLink.Shared.TrimAnalysis
                        _operation = operation;
                        _diagnosticContext = diagnosticContext;
                        _annotations = FlowAnnotations.Instance;
-                       _reflectionAccessAnalyzer = new ReflectionAccessAnalyzer ();
+                       _reflectionAccessAnalyzer = default;
                        _requireDynamicallyAccessedMembersAction = new (diagnosticContext, _reflectionAccessAnalyzer);
                }
 
index 36915b0..6766800 100644 (file)
@@ -7,7 +7,7 @@ using Microsoft.CodeAnalysis;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       partial record MethodParameterValue
+       internal partial record MethodParameterValue
        {
                public MethodParameterValue (IParameterSymbol parameterSymbol)
                        : this (new ParameterProxy (parameterSymbol)) { }
index 0c059e9..5001e58 100644 (file)
@@ -7,7 +7,7 @@ using Microsoft.CodeAnalysis;
 
 namespace ILLink.Shared.TypeSystemProxy
 {
-       readonly partial struct MethodProxy
+       internal readonly partial struct MethodProxy
        {
                public MethodProxy (IMethodSymbol method) => Method = method;
 
index 2f5a67f..d156fcf 100644 (file)
@@ -9,7 +9,7 @@ using Microsoft.CodeAnalysis;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       partial record MethodReturnValue
+       internal partial record MethodReturnValue
        {
                public MethodReturnValue (IMethodSymbol methodSymbol)
                {
index 27b47d4..8888b45 100644 (file)
@@ -7,7 +7,7 @@ using Microsoft.CodeAnalysis;
 
 namespace ILLink.Shared.TypeSystemProxy
 {
-       partial struct ParameterProxy
+       internal partial struct ParameterProxy
        {
                public ParameterProxy (IParameterSymbol parameter)
                {
index 0945de0..95cbb2f 100644 (file)
@@ -7,7 +7,7 @@ using ILLink.Shared.TypeSystemProxy;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       partial struct RequireDynamicallyAccessedMembersAction
+       internal partial struct RequireDynamicallyAccessedMembersAction
        {
                readonly ReflectionAccessAnalyzer _reflectionAccessAnalyzer;
 #pragma warning disable CA1822 // Mark members as static - the other partial implementations might need to be instance methods
index f2e8afa..5362f26 100644 (file)
@@ -19,7 +19,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis
                                        TypeKind.TypeParameter =>
                                                new NullableValueWithDynamicallyAccessedMembers (new TypeProxy (type),
                                                        new GenericParameterValue ((ITypeParameterSymbol) underlyingType)),
-                                       // typeof(Nullable<>) 
+                                       // typeof(Nullable<>)
                                        TypeKind.Error => new SystemTypeValue (new TypeProxy (type)),
                                        TypeKind.Class or TypeKind.Struct or TypeKind.Interface =>
                                                new NullableSystemTypeValue (new TypeProxy (type), new SystemTypeValue (new TypeProxy (underlyingType))),
index 2be8d09..316b9f9 100644 (file)
@@ -45,7 +45,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis
                                        if (targetValue is not ValueWithDynamicallyAccessedMembers targetWithDynamicallyAccessedMembers)
                                                throw new NotImplementedException ();
 
-                                       var requireDynamicallyAccessedMembersAction = new RequireDynamicallyAccessedMembersAction (diagnosticContext, new ReflectionAccessAnalyzer ());
+                                       var requireDynamicallyAccessedMembersAction = new RequireDynamicallyAccessedMembersAction (diagnosticContext, default (ReflectionAccessAnalyzer));
                                        requireDynamicallyAccessedMembersAction.Invoke (sourceValue, targetWithDynamicallyAccessedMembers);
                                }
                        }
index 1877947..5f9f0a6 100644 (file)
@@ -328,16 +328,16 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis
                                        case SpecialType.System_Byte when constantValue is byte byteConstantValue:
                                                constValue = new ConstIntValue (byteConstantValue);
                                                return true;
-                                       case SpecialType.System_Int16 when constantValue is Int16 int16ConstantValue:
+                                       case SpecialType.System_Int16 when constantValue is short int16ConstantValue:
                                                constValue = new ConstIntValue (int16ConstantValue);
                                                return true;
-                                       case SpecialType.System_UInt16 when constantValue is UInt16 uint16ConstantValue:
+                                       case SpecialType.System_UInt16 when constantValue is ushort uint16ConstantValue:
                                                constValue = new ConstIntValue (uint16ConstantValue);
                                                return true;
-                                       case SpecialType.System_Int32 when constantValue is Int32 int32ConstantValue:
+                                       case SpecialType.System_Int32 when constantValue is int int32ConstantValue:
                                                constValue = new ConstIntValue (int32ConstantValue);
                                                return true;
-                                       case SpecialType.System_UInt32 when constantValue is UInt32 uint32ConstantValue:
+                                       case SpecialType.System_UInt32 when constantValue is uint uint32ConstantValue:
                                                constValue = new ConstIntValue ((int) uint32ConstantValue);
                                                return true;
                                        }
index fed0715..e90bd25 100644 (file)
@@ -129,7 +129,7 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis
                        if (lines == null)
                                return;
                        foreach (var line in lines) {
-                               TraceWrite (new String ('\t', level));
+                               TraceWrite (new string ('\t', level));
                                TraceWriteLine (line);
                        }
                }
index bfb7ab5..42220a0 100644 (file)
@@ -15,7 +15,7 @@ namespace ILLink.Shared.TrimAnalysis
        ///  - Single-file warnings (suppressed by RequiresAssemblyFilesAttribute)
        /// Note that not all categories are used/supported by all tools, for example the ILLink only handles trimmer warnings and ignores the rest.
        /// </summary>
-       public readonly partial struct DiagnosticContext
+       internal readonly partial struct DiagnosticContext
        {
                /// <param name="id">The diagnostic ID, this will be used to determine the category of diagnostic (trimmer, AOT, single-file)</param>
                /// <param name="args">The arguments for diagnostic message.</param>
index 52006fe..64d0b6f 100644 (file)
@@ -10,7 +10,7 @@ using ILLink.Shared.TypeSystemProxy;
 namespace ILLink.Shared.TrimAnalysis
 {
        // Shared helpers to go from MethodProxy to dataflow values.
-       public partial class FlowAnnotations
+       internal partial class FlowAnnotations
        {
                internal partial bool MethodRequiresDataFlowAnalysis (MethodProxy method);
 
index 43ad688..8efb5ee 100644 (file)
@@ -62,7 +62,7 @@ namespace ILLink.Tasks
                /// Helper utility to track feature switch macros in header file
                /// This type is used in a dictionary as a key
                /// </summary>
-               readonly struct FeatureSwitchMembers
+               readonly struct FeatureSwitchMembers : IEquatable<FeatureSwitchMembers>
                {
                        public string Feature { get; }
                        public string FeatureValue { get; }
@@ -85,10 +85,10 @@ namespace ILLink.Tasks
                        }
 
                        public override bool Equals (object obj)
-                       {
-                               FeatureSwitchMembers other = (FeatureSwitchMembers) obj;
-                               return other._key.Equals (_key);
-                       }
+                               => obj is FeatureSwitchMembers inst && Equals (inst);
+
+                       public bool Equals (FeatureSwitchMembers fsm)
+                               => fsm._key == _key;
                }
 
                readonly Dictionary<string, string> namespaceDictionary = new Dictionary<string, string> ();
@@ -301,7 +301,11 @@ namespace ILLink.Tasks
                void OutputXml (string iLLinkTrimXmlFilePath, string outputFileName)
                {
                        XmlDocument doc = new XmlDocument ();
-                       doc.Load (iLLinkTrimXmlFilePath);
+                       using (var sr = new StreamReader (iLLinkTrimXmlFilePath)) {
+                               XmlReader reader = XmlReader.Create (sr, new XmlReaderSettings () { XmlResolver = null });
+                               doc.Load (reader);
+                       }
+
                        XmlElement linkerNode = doc["linker"];
 
                        if (featureSwitchMembers.Count > 0) {
index e805b2c..753d716 100644 (file)
@@ -231,11 +231,11 @@ namespace ILLink.Tasks
 
                private string DotNetPath {
                        get {
-                               if (!String.IsNullOrEmpty (_dotnetPath))
+                               if (!string.IsNullOrEmpty (_dotnetPath))
                                        return _dotnetPath;
 
                                _dotnetPath = Environment.GetEnvironmentVariable (DotNetHostPathEnvironmentName);
-                               if (String.IsNullOrEmpty (_dotnetPath))
+                               if (string.IsNullOrEmpty (_dotnetPath))
                                        throw new InvalidOperationException ($"{DotNetHostPathEnvironmentName} is not set");
 
                                return _dotnetPath;
@@ -255,7 +255,7 @@ namespace ILLink.Tasks
 
                public string ILLinkPath {
                        get {
-                               if (!String.IsNullOrEmpty (_illinkPath))
+                               if (!string.IsNullOrEmpty (_illinkPath))
                                        return _illinkPath;
 
 #pragma warning disable IL3000 // Avoid accessing Assembly file path when publishing as a single file
@@ -366,10 +366,10 @@ namespace ILLink.Tasks
                                // Add per-assembly optimization arguments
                                foreach (var optimization in _optimizationNames) {
                                        string optimizationValue = assembly.GetMetadata (optimization);
-                                       if (String.IsNullOrEmpty (optimizationValue))
+                                       if (string.IsNullOrEmpty (optimizationValue))
                                                continue;
 
-                                       if (!Boolean.TryParse (optimizationValue, out bool enabled))
+                                       if (!bool.TryParse (optimizationValue, out bool enabled))
                                                throw new ArgumentException ($"optimization metadata {optimization} must be True or False");
 
                                        SetOpt (args, optimization, assemblyName, enabled);
@@ -377,8 +377,8 @@ namespace ILLink.Tasks
 
                                // Add per-assembly verbosity arguments
                                string singleWarn = assembly.GetMetadata ("TrimmerSingleWarn");
-                               if (!String.IsNullOrEmpty (singleWarn)) {
-                                       if (!Boolean.TryParse (singleWarn, out bool value))
+                               if (!string.IsNullOrEmpty (singleWarn)) {
+                                       if (!bool.TryParse (singleWarn, out bool value))
                                                throw new ArgumentException ($"TrimmerSingleWarn metadata must be True or False");
 
                                        if (value)
@@ -450,7 +450,7 @@ namespace ILLink.Tasks
                                foreach (var customData in CustomData) {
                                        var key = customData.ItemSpec;
                                        var value = customData.GetMetadata ("Value");
-                                       if (String.IsNullOrEmpty (value))
+                                       if (string.IsNullOrEmpty (value))
                                                throw new ArgumentException ("custom data requires \"Value\" metadata");
                                        args.Append ("--custom-data ").Append (' ').Append (key).Append ('=').AppendLine (Quote (value));
                                }
@@ -460,7 +460,7 @@ namespace ILLink.Tasks
                                foreach (var featureSetting in FeatureSettings) {
                                        var feature = featureSetting.ItemSpec;
                                        var featureValue = featureSetting.GetMetadata ("Value");
-                                       if (String.IsNullOrEmpty (featureValue))
+                                       if (string.IsNullOrEmpty (featureValue))
                                                throw new ArgumentException ("feature settings require \"Value\" metadata");
                                        args.Append ("--feature ").Append (feature).Append (' ').AppendLine (featureValue);
                                }
@@ -486,11 +486,11 @@ namespace ILLink.Tasks
                                        // handle optional before/aftersteps
                                        var beforeStep = customStep.GetMetadata ("BeforeStep");
                                        var afterStep = customStep.GetMetadata ("AfterStep");
-                                       if (!String.IsNullOrEmpty (beforeStep) && !String.IsNullOrEmpty (afterStep))
+                                       if (!string.IsNullOrEmpty (beforeStep) && !string.IsNullOrEmpty (afterStep))
                                                throw new ArgumentException ("custom step may not have both \"BeforeStep\" and \"AfterStep\" metadata");
-                                       if (!String.IsNullOrEmpty (beforeStep))
+                                       if (!string.IsNullOrEmpty (beforeStep))
                                                customStepString = $"-{beforeStep}:{customStepString}";
-                                       if (!String.IsNullOrEmpty (afterStep))
+                                       if (!string.IsNullOrEmpty (afterStep))
                                                customStepString = $"+{afterStep}:{customStepString}";
 
                                        args.AppendLine (Quote (customStepString));
index fc8aa76..87c802b 100644 (file)
@@ -21,4 +21,4 @@ namespace ILLink.Tasks
                        }
                }
        }
-}
\ No newline at end of file
+}
index 570714f..3a42e37 100644 (file)
@@ -12,7 +12,7 @@ using MultiValue = ILLink.Shared.DataFlow.ValueSet<ILLink.Shared.DataFlow.Single
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       partial record ArrayValue
+       internal partial record ArrayValue
        {
                public static MultiValue Create (MultiValue size, TypeReference elementType)
                {
@@ -95,17 +95,17 @@ namespace ILLink.Shared.TrimAnalysis
                        bool first = true;
                        foreach (var element in IndexValues) {
                                if (!first) {
-                                       result.Append (",");
+                                       result.Append (',');
                                        first = false;
                                }
 
-                               result.Append ("(");
+                               result.Append ('(');
                                result.Append (element.Key);
                                result.Append (",(");
                                bool firstValue = true;
                                foreach (var v in element.Value.Value) {
                                        if (firstValue) {
-                                               result.Append (",");
+                                               result.Append (',');
                                                firstValue = false;
                                        }
 
@@ -118,4 +118,4 @@ namespace ILLink.Shared.TrimAnalysis
                        return result.ToString ();
                }
        }
-}
\ No newline at end of file
+}
index 51997c9..f68404e 100644 (file)
@@ -5,7 +5,7 @@ using Mono.Linker;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       public readonly partial struct DiagnosticContext
+       internal readonly partial struct DiagnosticContext
        {
                public readonly MessageOrigin Origin;
                public readonly bool DiagnosticsEnabled;
index caa1be8..5bfdfce 100644 (file)
@@ -65,7 +65,7 @@ namespace Mono.Linker.Dataflow
                        }
 
                        // For the purposes of the DynamicallyAccessedMembers type hierarchies
-                       // we consider interfaces of marked types to be also "marked" in that 
+                       // we consider interfaces of marked types to be also "marked" in that
                        // their annotations will be applied to the type regardless if later on
                        // we decide to remove the interface. This is to keep the complexity of the implementation
                        // relatively low. In the future it could be possibly optimized.
index 6d20f83..5e7e64c 100644 (file)
@@ -16,7 +16,7 @@ namespace ILLink.Shared.TrimAnalysis
        /// <summary>
        /// A representation of a field. Typically a result of ldfld.
        /// </summary>
-       sealed partial record FieldValue : IValueWithStaticType
+       internal sealed partial record FieldValue : IValueWithStaticType
        {
                public FieldValue (TypeDefinition? staticType, FieldDefinition fieldToLoad, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
                {
@@ -38,4 +38,5 @@ namespace ILLink.Shared.TrimAnalysis
 
                public override string ToString () => this.ValueToString (Field, DynamicallyAccessedMemberTypes);
        }
-}
\ No newline at end of file
+
+}
index 777a03d..4bbb0d5 100644 (file)
@@ -15,7 +15,7 @@ using Mono.Linker.Dataflow;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       sealed partial class FlowAnnotations
+       internal sealed partial class FlowAnnotations
        {
                readonly LinkContext _context;
                readonly Dictionary<TypeDefinition, TypeAnnotations> _annotations = new Dictionary<TypeDefinition, TypeAnnotations> ();
@@ -194,7 +194,7 @@ namespace ILLink.Shared.TrimAnalysis
                        // class, interface, struct can have annotations
                        DynamicallyAccessedMemberTypes typeAnnotation = GetMemberTypesForDynamicallyAccessedMembersAttribute (type);
 
-                       var annotatedFields = new ArrayBuilder<FieldAnnotation> ();
+                       ArrayBuilder<FieldAnnotation> annotatedFields = default;
 
                        // First go over all fields with an explicit annotation
                        if (type.HasFields) {
index 5b43e77..9d358a3 100644 (file)
@@ -41,4 +41,4 @@ namespace Mono.Linker.Dataflow
                        requireDynamicallyAccessedMembersAction.Invoke (value, targetValue);
                }
        }
-}
\ No newline at end of file
+}
index 8f1d606..7742bc6 100644 (file)
@@ -13,7 +13,7 @@ namespace ILLink.Shared.TrimAnalysis
        /// This is a System.Type value which represents generic parameter (basically result of typeof(T))
        /// Its actual type is unknown, but it can have annotations.
        /// </summary>
-       partial record GenericParameterValue
+       internal partial record GenericParameterValue
        {
                public GenericParameterValue (GenericParameter genericParameter, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
                {
@@ -30,4 +30,4 @@ namespace ILLink.Shared.TrimAnalysis
 
                public override string ToString () => this.ValueToString (GenericParameter, DynamicallyAccessedMemberTypes);
        }
-}
\ No newline at end of file
+}
index 9a65b93..adf728b 100644 (file)
@@ -10,7 +10,7 @@ using Mono.Linker.Dataflow;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       partial struct HandleCallAction
+       internal partial struct HandleCallAction
        {
 #pragma warning disable CA1822 // Mark members as static - the other partial implementations might need to be instance methods
 
index 503bdc6..6e7173d 100644 (file)
@@ -30,4 +30,4 @@ namespace Mono.Linker.Dataflow
                public static bool operator == (HoistedLocalKey left, HoistedLocalKey right) => left.Equals (right);
                public static bool operator != (HoistedLocalKey left, HoistedLocalKey right) => !(left == right);
        }
-}
\ No newline at end of file
+}
index bfb5cf5..2415f73 100644 (file)
@@ -103,4 +103,4 @@ namespace Mono.Linker.Dataflow
                                HoistedLocalsLattice.Meet (left.HoistedLocals, right.HoistedLocals),
                                this);
        }
-}
\ No newline at end of file
+}
index fab08ed..cf73255 100644 (file)
@@ -42,7 +42,7 @@ namespace Mono.Linker.Dataflow
                }
        }
 
-       abstract partial class MethodBodyScanner
+       internal abstract partial class MethodBodyScanner
        {
                protected readonly LinkContext _context;
                protected readonly InterproceduralStateLattice InterproceduralStateLattice;
@@ -54,7 +54,7 @@ namespace Mono.Linker.Dataflow
                        this.InterproceduralStateLattice = new InterproceduralStateLattice (default, default, context);
                }
 
-               internal MultiValue ReturnValue { private set; get; }
+               internal MultiValue ReturnValue { get; private set; }
 
                protected virtual void WarnAboutInvalidILInMethod (MethodBody method, int ilOffset)
                {
@@ -256,7 +256,7 @@ namespace Mono.Linker.Dataflow
                                // Disabled asserts due to a bug
                                // Debug.Assert (interproceduralState.Count == 1 + calleeMethods.Count ());
                                // foreach (var method in calleeMethods)
-                               //      Debug.Assert (interproceduralState.Any (kvp => kvp.Key.Method == method));
+                               //  Debug.Assert (interproceduralState.Any (kvp => kvp.Key.Method == method));
                        } else {
                                Debug.Assert (interproceduralState.MethodBodies.Count () == 1);
                        }
@@ -288,7 +288,7 @@ namespace Mono.Linker.Dataflow
 
                        BasicBlockIterator blockIterator = new BasicBlockIterator (methodIL);
 
-                       ReturnValue = new ();
+                       ReturnValue = default;
                        foreach (Instruction operation in methodIL.Instructions) {
                                int curBasicBlock = blockIterator.MoveNext (operation);
 
@@ -656,7 +656,7 @@ namespace Mono.Linker.Dataflow
                                                if (hasReturnValue) {
                                                        StackSlot retValue = PopUnknown (currentStack, 1, methodBody, operation.Offset);
                                                        // If the return value is a reference, treat it as the value itself for now
-                                                       //      We can handle ref return values better later
+                                                       // We can handle ref return values better later
                                                        ReturnValue = MultiValueLattice.Meet (ReturnValue, DereferenceValue (retValue.Value, locals, ref interproceduralState));
                                                        ValidateNoReferenceToReference (locals, methodBody.Method, operation.Offset);
                                                }
@@ -728,7 +728,7 @@ namespace Mono.Linker.Dataflow
 
                        bool isByRef = code == Code.Ldarga || code == Code.Ldarga_S;
                        isByRef |= paramType.IsByRefOrPointer ();
-                       isByRef |= param.IsImplicitThis == true && paramType.IsValueType;
+                       isByRef |= param.IsImplicitThis && paramType.IsValueType;
 
                        StackSlot slot = new StackSlot (
                                isByRef
index 8fac8fe..9e7aa68 100644 (file)
@@ -13,7 +13,7 @@ namespace ILLink.Shared.TrimAnalysis
        /// <summary>
        /// A value that came from a method parameter - such as the result of a ldarg.
        /// </summary>
-       partial record MethodParameterValue : IValueWithStaticType
+       internal partial record MethodParameterValue : IValueWithStaticType
        {
                public MethodParameterValue (TypeDefinition? staticType, ParameterProxy param, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes, bool overrideIsThis = false)
                {
@@ -27,4 +27,4 @@ namespace ILLink.Shared.TrimAnalysis
 
                public TypeDefinition? StaticType { get; }
        }
-}
\ No newline at end of file
+}
index 421db0a..a4ca063 100644 (file)
@@ -8,7 +8,7 @@ using Mono.Linker;
 
 namespace ILLink.Shared.TypeSystemProxy
 {
-       readonly partial struct MethodProxy : IEquatable<MethodProxy>
+       internal readonly partial struct MethodProxy : IEquatable<MethodProxy>
        {
                public MethodProxy (MethodDefinition method) => Method = method;
 
index f6cb423..5234f9b 100644 (file)
@@ -14,7 +14,7 @@ namespace ILLink.Shared.TrimAnalysis
        /// <summary>
        /// Return value from a method
        /// </summary>
-       partial record MethodReturnValue : IValueWithStaticType
+       internal partial record MethodReturnValue : IValueWithStaticType
        {
                public MethodReturnValue (TypeDefinition? staticType, MethodDefinition method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
                {
@@ -36,4 +36,4 @@ namespace ILLink.Shared.TrimAnalysis
 
                public override string ToString () => this.ValueToString (Method, DynamicallyAccessedMemberTypes);
        }
-}
\ No newline at end of file
+}
index be69951..6dbd6e7 100644 (file)
@@ -196,4 +196,4 @@ namespace Mono.Linker.Dataflow
                        _markStep.MarkStaticConstructorVisibleToReflection (type, new DependencyInfo (DependencyKind.AccessedViaReflection, origin.Provider), origin);
                }
        }
-}
\ No newline at end of file
+}
index 530ecf2..a3fd649 100644 (file)
@@ -120,16 +120,18 @@ namespace Mono.Linker.Dataflow
 
                public override bool HandleCall (MethodBody callingMethodBody, MethodReference calledMethod, Instruction operation, ValueNodeList methodParams, out MultiValue methodReturnValue)
                {
-                       methodReturnValue = new ();
-
                        var reflectionProcessed = _markStep.ProcessReflectionDependency (callingMethodBody, operation);
-                       if (reflectionProcessed)
+                       if (reflectionProcessed) {
+                               methodReturnValue = default;
                                return false;
+                       }
 
                        Debug.Assert (callingMethodBody.Method == _origin.Provider);
                        var calledMethodDefinition = _context.TryResolve (calledMethod);
-                       if (calledMethodDefinition == null)
+                       if (calledMethodDefinition == null) {
+                               methodReturnValue = default;
                                return false;
+                       }
 
                        _origin = _origin.WithInstructionOffset (operation.Offset);
 
index 5f1f8ee..cae166a 100644 (file)
@@ -9,7 +9,7 @@ using Mono.Linker.Dataflow;
 
 namespace ILLink.Shared.TrimAnalysis
 {
-       partial struct RequireDynamicallyAccessedMembersAction
+       internal partial struct RequireDynamicallyAccessedMembersAction
        {
                readonly ReflectionMarker _reflectionMarker;
 
index 7b8dbba..8ff2490 100644 (file)
@@ -22,7 +22,7 @@ namespace Mono.Linker.Dataflow
                        foreach (Instruction operation in methodIL.Instructions) {
                                if (!operation.OpCode.IsControlFlowInstruction ())
                                        continue;
-                               Object value = operation.Operand;
+                               object value = operation.Operand;
                                if (value is Instruction inst) {
                                        branchTargets.Add (inst.Offset);
                                } else if (value is Instruction[] instructions) {
index 5ab5ab3..1517afa 100644 (file)
@@ -48,4 +48,4 @@ namespace Mono.Linker.Dataflow
                        }
                }
        }
-}
\ No newline at end of file
+}
index a9d9cdf..7f20ba6 100644 (file)
@@ -73,4 +73,4 @@ namespace Mono.Linker.Dataflow
                                out MultiValue _);
                }
        }
-}
\ No newline at end of file
+}
index ee88e9d..fd84929 100644 (file)
@@ -58,4 +58,4 @@ namespace Mono.Linker.Dataflow
                                pattern.MarkAndProduceDiagnostics (reflectionMarker, markStep, _context);
                }
        }
-}
\ No newline at end of file
+}
index 3374ca3..b52e7ba 100644 (file)
@@ -26,7 +26,7 @@ namespace Mono.Linker.Dataflow
 
                public override int GetHashCode ()
                {
-                       HashCode hashCode = new HashCode ();
+                       HashCode hashCode = default;
                        foreach (var item in this)
                                hashCode.Add (item.GetHashCode ());
                        return hashCode.ToHashCode ();
index 128354b..17315ac 100644 (file)
@@ -128,7 +128,7 @@ namespace Mono.Linker.Steps
                                        continue;
 
                                string name = GetAttribute (resourceNav, "name");
-                               if (String.IsNullOrEmpty (name)) {
+                               if (string.IsNullOrEmpty (name)) {
                                        LogWarning (resourceNav, DiagnosticId.XmlMissingNameAttributeInResource);
                                        continue;
                                }
index 611acb9..466d421 100644 (file)
@@ -19,7 +19,7 @@ namespace Mono.Linker.Steps
 
                public override bool IsActiveFor (AssemblyDefinition assembly)
                {
-                       // Only process assemblies which went through marking. 
+                       // Only process assemblies which went through marking.
                        // The code relies on MarkStep to identify the useful suppressions.
                        // Assemblies which didn't go through marking would not produce any warnings and thus would report all suppressions as redundant.
                        var assemblyAction = Annotations.GetAction (assembly);
index ebacbf8..a527ca2 100644 (file)
@@ -190,23 +190,23 @@ namespace Mono.Linker.Steps
                {
                        StringBuilder sb = new StringBuilder ();
                        sb.Append (meth.ReturnType.FullName);
-                       sb.Append (" ");
+                       sb.Append (' ');
                        sb.Append (meth.Name);
                        if (includeGenericParameters && meth.HasGenericParameters) {
-                               sb.Append ("`");
+                               sb.Append ('`');
                                sb.Append (meth.GenericParameters.Count);
                        }
 
-                       sb.Append ("(");
+                       sb.Append ('(');
                        if (meth.HasMetadataParameters ()) {
                                int i = 0;
                                foreach (var p in meth.GetMetadataParameters ()) {
                                        if (i++ > 0)
-                                               sb.Append (",");
+                                               sb.Append (',');
                                        sb.Append (p.ParameterType.FullName);
                                }
                        }
-                       sb.Append (")");
+                       sb.Append (')');
                        return sb.ToString ();
                }
 
@@ -263,7 +263,7 @@ namespace Mono.Linker.Steps
 
                                if (accessors.Length > 0) {
                                        for (int i = 0; i < accessors.Length; ++i)
-                                               accessors[i] = accessors[i].ToLower ();
+                                               accessors[i] = accessors[i].ToLowerInvariant ();
 
                                        return accessors;
                                }
index 6de2fde..a0002ae 100644 (file)
@@ -40,8 +40,8 @@ namespace Mono.Linker.Steps
 
                (CustomAttribute[]? customAttributes, MessageOrigin[]? origins) ProcessAttributes (XPathNavigator nav, ICustomAttributeProvider provider)
                {
-                       var customAttributesBuilder = new ArrayBuilder<CustomAttribute> ();
-                       var originsBuilder = new ArrayBuilder<MessageOrigin> ();
+                       ArrayBuilder<CustomAttribute> customAttributesBuilder = default;
+                       ArrayBuilder<MessageOrigin> originsBuilder = default;
                        foreach (XPathNavigator attributeNav in nav.SelectChildren ("attribute", string.Empty)) {
                                if (!ShouldProcessElement (attributeNav))
                                        continue;
@@ -127,9 +127,9 @@ namespace Mono.Linker.Steps
                        //
                        // public sealed class RemoveAttributeInstancesAttribute : Attribute
                        // {
-                       //              public RemoveAttributeInstancesAttribute () {}
-                       //              public RemoveAttributeInstancesAttribute (object values) {} // For legacy uses
-                       //              public RemoveAttributeInstancesAttribute (params object[] values) {}
+                       //  public RemoveAttributeInstancesAttribute () {}
+                       //  public RemoveAttributeInstancesAttribute (object values) {} // For legacy uses
+                       //  public RemoveAttributeInstancesAttribute (params object[] values) {}
                        // }
                        //
                        const MethodAttributes ctorAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Final;
@@ -225,7 +225,7 @@ namespace Mono.Linker.Steps
 
                CustomAttributeArgument[] ReadCustomAttributeArguments (XPathNavigator nav, TypeDefinition attributeType)
                {
-                       var args = new ArrayBuilder<CustomAttributeArgument> ();
+                       ArrayBuilder<CustomAttributeArgument> args = default;
 
                        foreach (XPathNavigator argumentNav in nav.SelectChildren ("argument", string.Empty)) {
                                CustomAttributeArgument? caa = ReadCustomAttributeArgument (argumentNav, attributeType);
@@ -306,11 +306,11 @@ namespace Mono.Linker.Steps
                                if (typeref is ArrayType arrayTypeRef) {
                                        var elementType = arrayTypeRef.ElementType;
                                        var arrayArgumentIterator = nav.SelectChildren ("argument", string.Empty);
-                                       ArrayBuilder<CustomAttributeArgument> elements = new ArrayBuilder<CustomAttributeArgument> ();
+                                       ArrayBuilder<CustomAttributeArgument> elements = default;
                                        foreach (XPathNavigator elementNav in arrayArgumentIterator) {
                                                if (ReadCustomAttributeArgument (elementNav, memberWithAttribute) is CustomAttributeArgument arg) {
                                                        // To match Cecil, elements of a list that are subclasses of the list type must be boxed in the base type
-                                                       //      e.g. object[] { 73 } translates to Cecil.CAA { Type: object[] : Value: CAA{ Type: object, Value: CAA{ Type: int, Value: 73} } }
+                                                       // e.g. object[] { 73 } translates to Cecil.CAA { Type: object[] : Value: CAA{ Type: object, Value: CAA{ Type: int, Value: 73} } }
                                                        if (arg.Type == elementType) {
                                                                elements.Add (arg);
                                                        }
@@ -543,25 +543,25 @@ namespace Mono.Linker.Steps
                        }
                        sb.Append (method.Name);
                        if (method.HasGenericParameters) {
-                               sb.Append ("<");
+                               sb.Append ('<');
                                for (int i = 0; i < method.GenericParameters.Count; i++) {
                                        if (i > 0)
-                                               sb.Append (",");
+                                               sb.Append (',');
 
                                        sb.Append (method.GenericParameters[i].Name);
                                }
-                               sb.Append (">");
+                               sb.Append ('>');
                        }
-                       sb.Append ("(");
+                       sb.Append ('(');
                        if (method.HasMetadataParameters ()) {
                                for (int i = 0; i < method.Parameters.Count; i++) {
                                        if (i > 0)
-                                               sb.Append (",");
+                                               sb.Append (',');
 
                                        sb.Append (method.Parameters[i].ParameterType.FullName);
                                }
                        }
-                       sb.Append (")");
+                       sb.Append (')');
                        return sb.ToString ();
                }
 #pragma warning restore RS0030
index 1c319a2..6b10b06 100644 (file)
@@ -37,4 +37,4 @@ namespace Mono.Linker.Steps
                        context.Annotations.SetMembersPreserve (type, members);
                }
        }
-}
\ No newline at end of file
+}
index 26bafe5..ce7a505 100644 (file)
@@ -2103,7 +2103,7 @@ namespace Mono.Linker.Steps
 
                                if (property.Name == "TargetTypeName") {
                                        string targetTypeName = (string) property.Argument.Value;
-                                       TypeName typeName = TypeParser.ParseTypeName (targetTypeName);
+                                       TypeName? typeName = TypeParser.ParseTypeName (targetTypeName);
                                        if (typeName is AssemblyQualifiedTypeName assemblyQualifiedTypeName) {
                                                AssemblyDefinition? assembly = Context.TryResolve (assemblyQualifiedTypeName.AssemblyName.Name);
                                                return assembly == null ? null : Context.TryResolve (assembly, targetTypeName);
index 52bf746..c172871 100644 (file)
@@ -36,7 +36,7 @@ namespace Mono.Linker.Steps
                public virtual void Initialize (LinkContext context, MarkContext markContext)
                {
                        InitializeSubSteps (context);
-                       markContext.RegisterMarkAssemblyAction (assembly => BrowseAssembly (assembly));
+                       markContext.RegisterMarkAssemblyAction (BrowseAssembly);
                }
 
                static bool HasSubSteps (List<ISubStep> substeps) => substeps?.Count > 0;
index 590d498..5cf6f0e 100644 (file)
@@ -42,7 +42,7 @@ namespace Mono.Linker.Steps
 
        public class OutputStep : BaseStep
        {
-               private Dictionary<UInt16, TargetArchitecture>? architectureMap;
+               private Dictionary<ushort, TargetArchitecture>? architectureMap;
 
                private enum NativeOSOverride
                {
@@ -63,7 +63,7 @@ namespace Mono.Linker.Steps
                TargetArchitecture CalculateArchitecture (TargetArchitecture readyToRunArch)
                {
                        if (architectureMap == null) {
-                               architectureMap = new Dictionary<UInt16, TargetArchitecture> ();
+                               architectureMap = new Dictionary<ushort, TargetArchitecture> ();
                                foreach (var os in Enum.GetValues (typeof (NativeOSOverride))) {
                                        ushort osVal = (ushort) (NativeOSOverride) os;
                                        foreach (var arch in Enum.GetValues (typeof (TargetArchitecture))) {
@@ -95,7 +95,7 @@ namespace Mono.Linker.Steps
                {
                        if (Context.AssemblyListFile != null) {
                                using (var w = File.CreateText (Context.AssemblyListFile)) {
-                                       w.WriteLine ("[" + String.Join (", ", assembliesWritten.Select (a => "\"" + a + "\"").ToArray ()) + "]");
+                                       w.WriteLine ("[" + string.Join (", ", assembliesWritten.Select (a => "\"" + a + "\"").ToArray ()) + "]");
                                }
                        }
                }
index d540fad..f9c65d9 100644 (file)
@@ -26,4 +26,4 @@ namespace Mono.Linker.Steps
                        Directory.CreateDirectory (Context.OutputDirectory);
                }
        }
-}
\ No newline at end of file
+}
index 6184a30..d189d6d 100644 (file)
@@ -251,7 +251,7 @@ namespace Mono.Linker.Steps
                protected virtual void ProcessField (TypeDefinition type, XPathNavigator nav)
                {
                        string signature = GetSignature (nav);
-                       if (!String.IsNullOrEmpty (signature)) {
+                       if (!string.IsNullOrEmpty (signature)) {
                                FieldDefinition? field = GetField (type, signature);
                                if (field == null) {
                                        LogWarning (nav, DiagnosticId.XmlCouldNotFindFieldOnType, signature, type.GetDisplayName ());
@@ -262,7 +262,7 @@ namespace Mono.Linker.Steps
                        }
 
                        string name = GetName (nav);
-                       if (!String.IsNullOrEmpty (name)) {
+                       if (!string.IsNullOrEmpty (name)) {
                                bool foundMatch = false;
                                if (type.HasFields) {
                                        foreach (FieldDefinition field in type.Fields) {
@@ -305,7 +305,7 @@ namespace Mono.Linker.Steps
                protected virtual void ProcessMethod (TypeDefinition type, XPathNavigator nav, object? customData)
                {
                        string signature = GetSignature (nav);
-                       if (!String.IsNullOrEmpty (signature)) {
+                       if (!string.IsNullOrEmpty (signature)) {
                                MethodDefinition? method = GetMethod (type, signature);
                                if (method == null) {
                                        LogWarning (nav, DiagnosticId.XmlCouldNotFindMethodOnType, signature, type.GetDisplayName ());
@@ -316,7 +316,7 @@ namespace Mono.Linker.Steps
                        }
 
                        string name = GetAttribute (nav, NameAttributeName);
-                       if (!String.IsNullOrEmpty (name)) {
+                       if (!string.IsNullOrEmpty (name)) {
                                bool foundMatch = false;
                                if (type.HasMethods) {
                                        foreach (MethodDefinition method in type.Methods) {
@@ -349,7 +349,7 @@ namespace Mono.Linker.Steps
                protected virtual void ProcessEvent (TypeDefinition type, XPathNavigator nav, object? customData)
                {
                        string signature = GetSignature (nav);
-                       if (!String.IsNullOrEmpty (signature)) {
+                       if (!string.IsNullOrEmpty (signature)) {
                                EventDefinition? @event = GetEvent (type, signature);
                                if (@event == null) {
                                        LogWarning (nav, DiagnosticId.XmlCouldNotFindEventOnType, signature, type.GetDisplayName ());
@@ -360,7 +360,7 @@ namespace Mono.Linker.Steps
                        }
 
                        string name = GetAttribute (nav, NameAttributeName);
-                       if (!String.IsNullOrEmpty (name)) {
+                       if (!string.IsNullOrEmpty (name)) {
                                bool foundMatch = false;
                                foreach (EventDefinition @event in type.Events) {
                                        if (@event.Name == name) {
@@ -401,7 +401,7 @@ namespace Mono.Linker.Steps
                protected virtual void ProcessProperty (TypeDefinition type, XPathNavigator nav, object? customData)
                {
                        string signature = GetSignature (nav);
-                       if (!String.IsNullOrEmpty (signature)) {
+                       if (!string.IsNullOrEmpty (signature)) {
                                PropertyDefinition? property = GetProperty (type, signature);
                                if (property == null) {
                                        LogWarning (nav, DiagnosticId.XmlCouldNotFindPropertyOnType, signature, type.GetDisplayName ());
@@ -412,7 +412,7 @@ namespace Mono.Linker.Steps
                        }
 
                        string name = GetAttribute (nav, NameAttributeName);
-                       if (!String.IsNullOrEmpty (name)) {
+                       if (!string.IsNullOrEmpty (name)) {
                                bool foundMatch = false;
                                foreach (PropertyDefinition property in type.Properties) {
                                        if (property.Name == name) {
index 8dfc6af..6ed5959 100644 (file)
@@ -7,7 +7,7 @@ namespace Mono.Linker.Steps
        {
                protected override void Process ()
                {
-                       // Flush all cached messages before the sweep and clean steps are run to be confident 
+                       // Flush all cached messages before the sweep and clean steps are run to be confident
                        // that we have all the information needed to gracefully generate the string.
                        Context.FlushCachedWarnings ();
                }
index 5ac867a..575e115 100644 (file)
@@ -75,4 +75,4 @@ namespace Mono.Linker.Steps
                        Annotations.Mark (ca, new DependencyInfo (DependencyKind.DisablePrivateReflection, ca));
                }
        }
-}
\ No newline at end of file
+}
index 73f01eb..3512ad7 100644 (file)
@@ -80,4 +80,4 @@ namespace Mono.Linker.Steps
                        return false;
                }
        }
-}
\ No newline at end of file
+}
index a42d74f..ba697d8 100644 (file)
@@ -143,8 +143,8 @@ namespace Mono.Linker.Steps
                                                // rewrite the copy to save to update the scopes not to point
                                                // forwarding assembly (facade).
                                                //
-                                               //              foo.dll -> facade.dll    -> lib.dll
-                                               //              copy    |  copy (delete) |  link
+                                               //      foo.dll -> facade.dll    -> lib.dll
+                                               //      copy    |  copy (delete) |  link
                                                //
                                                Annotations.SetAction (assembly, AssemblyAction.Save);
                                                continue;
@@ -452,16 +452,16 @@ namespace Mono.Linker.Steps
                                // We can't rely on the context resolution cache anymore, since it may remember methods which are already removed
                                // So call the direct Resolve here and avoid the cache.
                                // We want to remove a method from the list of Overrides if:
-                               //      Resolve() is null
-                               //              This can happen for a couple of reasons, but it indicates the method isn't in the final assembly.
-                               //              Resolve also may return a removed value if method.Overrides[i] is a MethodDefinition. In this case, Resolve short circuits and returns `this`.
-                               //      OR
-                               //      ov.DeclaringType is null
-                               //              ov.DeclaringType may be null if Resolve short circuited and returned a removed method. In this case, we want to remove the override.
-                               //      OR
-                               //      ov is in a `link` scope and is unmarked
-                               //              ShouldRemove returns true if the method is unmarked, but we also We need to make sure the override is in a link scope.
-                               //              Only things in a link scope are marked, so ShouldRemove is only valid for items in a `link` scope.
+                               //  Resolve() is null
+                               //    This can happen for a couple of reasons, but it indicates the method isn't in the final assembly.
+                               //    Resolve also may return a removed value if method.Overrides[i] is a MethodDefinition. In this case, Resolve short circuits and returns `this`.
+                               // OR
+                               // ov.DeclaringType is null
+                               //    ov.DeclaringType may be null if Resolve short circuited and returned a removed method. In this case, we want to remove the override.
+                               // OR
+                               // ov is in a `link` scope and is unmarked
+                               //    ShouldRemove returns true if the method is unmarked, but we also We need to make sure the override is in a link scope.
+                               //    Only things in a link scope are marked, so ShouldRemove is only valid for items in a `link` scope.
 #pragma warning disable RS0030 // Cecil's Resolve is banned - it's necessary when the metadata graph isn't stable
                                if (method.Overrides[i].Resolve () is not MethodDefinition ov || ov.DeclaringType is null || (IsLinkScope (ov.DeclaringType.Scope) && ShouldRemove (ov)))
                                        method.Overrides.RemoveAt (i);
index 699d9aa..da84281 100644 (file)
@@ -31,7 +31,6 @@
 
 namespace Mono.Linker
 {
-
        public enum AssemblyAction
        {
                // Ignore the assembly
@@ -47,8 +46,8 @@ namespace Mono.Linker
                Link,
                // Remove the assembly from the output
                Delete,
-               // Save the assembly/symbols in memory without trimming it. 
-               // E.g. useful to remove unneeded assembly references (as done in SweepStep), 
+               // Save the assembly/symbols in memory without trimming it.
+               // E.g. useful to remove unneeded assembly references (as done in SweepStep),
                //  resolving [TypeForwardedTo] attributes (like PCL) to their final location
                Save,
                // Keep all types, methods, and fields but add System.Runtime.BypassNGenAttribute to unmarked methods.
index 3cfc113..05e58ed 100644 (file)
@@ -154,7 +154,7 @@ namespace Mono.Linker
                public static readonly DependencyInfo AlreadyMarked = new DependencyInfo (DependencyKind.AlreadyMarked, null);
                public static readonly DependencyInfo DisablePrivateReflectionRequirement = new DependencyInfo (DependencyKind.DisablePrivateReflectionRequirement, null);
                public bool Equals (DependencyInfo other) => (Kind, Source) == (other.Kind, other.Source);
-               public override bool Equals (Object? obj) => obj is DependencyInfo info && this.Equals (info);
+               public override bool Equals (object? obj) => obj is DependencyInfo info && this.Equals (info);
                public override int GetHashCode () => (Kind, Source).GetHashCode ();
                public static bool operator == (DependencyInfo lhs, DependencyInfo rhs) => lhs.Equals (rhs);
                public static bool operator != (DependencyInfo lhs, DependencyInfo rhs) => !lhs.Equals (rhs);
index 0bccf90..eed05fc 100644 (file)
@@ -137,7 +137,7 @@ namespace Mono.Linker
                        }
                }
 
-               private int _nodeIndex = 0;
+               private int _nodeIndex;
 
                void AddNode (string node)
                {
index 802b119..60e8724 100644 (file)
@@ -122,7 +122,7 @@ namespace Mono.Linker
 
                                        // If the containing type is nested within other types.
                                        // e.g. A<T>.B<U>.M<V>(T t, U u, V v) should be M(`0, `1, ``0).
-                                       // Roslyn needs to add generic arities of parents, but the innermost type redeclares 
+                                       // Roslyn needs to add generic arities of parents, but the innermost type redeclares
                                        // all generic parameters so we don't need to add them.
                                        builder.Append ('`');
                                }
@@ -155,7 +155,7 @@ namespace Mono.Linker
                                        builder.Append ('.');
                                }
 
-                               if (!String.IsNullOrEmpty (typeReference.Namespace))
+                               if (!string.IsNullOrEmpty (typeReference.Namespace))
                                        builder.Append (typeReference.Namespace).Append ('.');
 
                                // This includes '`n' for mangled generic types
index fe599d0..6b7d96a 100644 (file)
@@ -147,7 +147,7 @@ namespace Mono.Linker
                                (name, arity) = ParseTypeOrNamespaceName (id, ref index, nameBuilder);
                                // if we are at the end of the dotted name and still haven't resolved it to
                                // a type, there are no results.
-                               if (String.IsNullOrEmpty (name))
+                               if (string.IsNullOrEmpty (name))
                                        return;
 
                                // no more dots, so don't loop any more
@@ -161,7 +161,7 @@ namespace Mono.Linker
                                var typeOrNamespaceName = nameBuilder.ToString ();
                                GetMatchingTypes (module, declaringType: containingType, name: typeOrNamespaceName, arity: arity, results: results, resolver);
                                Debug.Assert (results.Count <= 1);
-                               if (results.Any ()) {
+                               if (results.Count > 0) {
                                        // the name resolved to a type
                                        var result = results.Single ();
                                        Debug.Assert (result is TypeDefinition);
@@ -376,7 +376,7 @@ namespace Mono.Linker
                        // loop for dotted names
                        while (true) {
                                var name = ParseName (id, ref index);
-                               if (String.IsNullOrEmpty (name))
+                               if (string.IsNullOrEmpty (name))
                                        return;
 
                                nameBuilder.Append (name);
@@ -505,7 +505,7 @@ namespace Mono.Linker
                                return;
 
                        foreach (var nestedType in declaringType.NestedTypes) {
-                               Debug.Assert (String.IsNullOrEmpty (nestedType.Namespace));
+                               Debug.Assert (string.IsNullOrEmpty (nestedType.Namespace));
                                if (nestedType.Name != name)
                                        continue;
 
index ebaa189..65c918f 100644 (file)
@@ -152,7 +152,7 @@ namespace Mono.Linker
                                                numBackslash /= 2;
                                        }
                                        if (numBackslash > 0)
-                                               argBuilder.Append (new String ('\\', numBackslash));
+                                               argBuilder.Append (new string ('\\', numBackslash));
                                        if (cur < 0 || (!inquote && char.IsWhiteSpace ((char) cur)))
                                                break;
                                        if (copyChar)
@@ -843,7 +843,7 @@ namespace Mono.Linker
 
                private static IEnumerable<int> ProcessWarningCodes (string value)
                {
-                       string Unquote (string arg)
+                       static string Unquote (string arg)
                        {
                                if (arg.Length > 1 && arg[0] == '"' && arg[arg.Length - 1] == '"')
                                        return arg.Substring (1, arg.Length - 2);
index 9b89da7..495d8a2 100644 (file)
@@ -71,7 +71,7 @@ namespace Mono.Linker
                        // Don't honor the Condition until we have figured out the behavior for DynamicDependencyAttribute:
                        // https://github.com/dotnet/linker/issues/1231
                        // if (!ShouldProcess (context, customAttribute))
-                       //      return null;
+                       //   return null;
 
                        var dynamicDependency = GetDynamicDependency (customAttribute);
                        if (dynamicDependency != null)
@@ -129,4 +129,4 @@ namespace Mono.Linker
                        return true;
                }
        }
-}
\ No newline at end of file
+}
index 89a1373..84bc8d2 100644 (file)
@@ -41,7 +41,7 @@ namespace Mono.Linker
 
                public static string GetAttribute (XPathNavigator nav, string attribute)
                {
-                       return nav.GetAttribute (attribute, String.Empty);
+                       return nav.GetAttribute (attribute, string.Empty);
                }
        }
 }
index ec3e8ff..90bd6ab 100644 (file)
@@ -246,7 +246,7 @@ namespace Mono.Linker
 
                public void SetFeatureValue (string feature, bool value)
                {
-                       Debug.Assert (!String.IsNullOrEmpty (feature));
+                       Debug.Assert (!string.IsNullOrEmpty (feature));
                        FeatureSettings[feature] = value;
                }
 
index f4cb817..5c29cad 100644 (file)
@@ -289,10 +289,10 @@ namespace Mono.Linker
                        string origin = Origin?.ToString () ?? originApp;
 
                        StringBuilder sb = new StringBuilder ();
-                       sb.Append (origin).Append (":");
+                       sb.Append (origin).Append (':');
 
                        if (!string.IsNullOrEmpty (SubCategory))
-                               sb.Append (" ").Append (SubCategory);
+                               sb.Append (' ').Append (SubCategory);
 
                        string cat;
                        switch (Category) {
@@ -309,14 +309,14 @@ namespace Mono.Linker
                        }
 
                        if (!string.IsNullOrEmpty (cat)) {
-                               sb.Append (" ")
+                               sb.Append (' ')
                                        .Append (cat)
                                        .Append (" IL")
                                        // Warning and error messages always have a code.
                                        .Append (Code!.Value.ToString ("D4"))
                                        .Append (": ");
                        } else {
-                               sb.Append (" ");
+                               sb.Append (' ');
                        }
 
                        if (Origin?.Provider != null) {
index 402e529..6cc1352 100644 (file)
@@ -106,11 +106,11 @@ namespace Mono.Linker
 
                        StringBuilder sb = new StringBuilder (fileName);
                        if (sourceLine != 0) {
-                               sb.Append ("(").Append (sourceLine);
+                               sb.Append ('(').Append (sourceLine);
                                if (sourceColumn != 0)
-                                       sb.Append (",").Append (sourceColumn);
+                                       sb.Append (',').Append (sourceColumn);
 
-                               sb.Append (")");
+                               sb.Append (')');
                        }
 
                        return sb.ToString ();
index ebdb7ff..aae0266 100644 (file)
@@ -42,7 +42,7 @@ namespace Mono.Linker
                        }
 
                        // Append parameters
-                       sb.Append ("(");
+                       sb.Append ('(');
                        if (method.HasMetadataParameters ()) {
 #pragma warning disable RS0030 // MethodReference.Parameters is banned -- it's best to leave this as is for now
                                for (int i = 0; i < method.Parameters.Count - 1; i++)
@@ -51,7 +51,7 @@ namespace Mono.Linker
 #pragma warning restore RS0030 // Do not used banned APIs
                        }
 
-                       sb.Append (")");
+                       sb.Append (')');
 
                        // Insert generic parameters
                        if (method.HasGenericParameters) {
index 9042bf3..1df8846 100644 (file)
@@ -45,4 +45,4 @@ namespace Mono.Linker
                        return string.Compare (this.EntryPoint, other.EntryPoint, StringComparison.Ordinal);
                }
        }
-}
\ No newline at end of file
+}
index 3808c59..a5d270e 100644 (file)
@@ -9,7 +9,7 @@ using Mono.Collections.Generic;
 namespace Mono.Linker
 {
        /// <summary>
-       /// This attribute name will be the name hardcoded in linker which will remove all 
+       /// This attribute name will be the name hardcoded in linker which will remove all
        /// attribute usages but not the attribute definition
        /// </summary>
        [AttributeUsage (
index fb33253..939c8f5 100644 (file)
@@ -29,4 +29,4 @@ namespace Mono.Linker
                        return (td.Attributes & TypeAttributes.Serializable) != 0;
                }
        }
-}
\ No newline at end of file
+}
index b28509c..cd42971 100644 (file)
@@ -35,7 +35,7 @@ namespace Mono.Linker
                        if (string.IsNullOrEmpty (typeNameString))
                                return false;
 
-                       TypeName parsedTypeName;
+                       TypeName? parsedTypeName;
                        try {
                                parsedTypeName = TypeParser.ParseTypeName (typeNameString);
                        } catch (ArgumentException) {
@@ -89,7 +89,7 @@ namespace Mono.Linker
                        typeResolutionRecords = null;
                        return false;
 
-                       bool TryResolveTypeName (AssemblyDefinition assemblyDefinition, TypeName typeName, [NotNullWhen (true)] out TypeReference? typeReference, List<TypeResolutionRecord> typeResolutionRecords)
+                       bool TryResolveTypeName (AssemblyDefinition assemblyDefinition, TypeName? typeName, [NotNullWhen (true)] out TypeReference? typeReference, List<TypeResolutionRecord> typeResolutionRecords)
                        {
                                typeReference = null;
                                if (assemblyDefinition == null)
@@ -115,7 +115,7 @@ namespace Mono.Linker
                        return typeReference != null;
                }
 
-               TypeReference? ResolveTypeName (AssemblyDefinition assembly, TypeName typeName, List<TypeResolutionRecord> typeResolutionRecords)
+               TypeReference? ResolveTypeName (AssemblyDefinition assembly, TypeName? typeName, List<TypeResolutionRecord> typeResolutionRecords)
                {
                        if (typeName is AssemblyQualifiedTypeName assemblyQualifiedTypeName) {
                                // In this case we ignore the assembly parameter since the type name has assembly in it
@@ -167,4 +167,4 @@ namespace Mono.Linker
                        return resolvedType;
                }
        }
-}
\ No newline at end of file
+}
index 844f8bd..7ae2584 100644 (file)
@@ -359,4 +359,4 @@ namespace Mono.Linker
                protected abstract void ProcessExportedType (ExportedType exportedType);
        }
 
-}
\ No newline at end of file
+}
index 2aff747..6dac894 100644 (file)
@@ -19,7 +19,7 @@ namespace Mono.Linker
                public class Suppression
                {
                        public SuppressMessageInfo SuppressMessageInfo { get; }
-                       public bool Used { get; set; } = false;
+                       public bool Used { get; set; }
                        public CustomAttribute OriginAttribute { get; }
                        public ICustomAttributeProvider Provider { get; }
 
@@ -294,7 +294,7 @@ namespace Mono.Linker
                                if (!TryDecodeSuppressMessageAttributeData (instance, out info))
                                        continue;
 
-                               var scope = info.Scope?.ToLower ();
+                               var scope = info.Scope?.ToLowerInvariant ();
                                if (info.Target == null && (scope == "module" || scope == null)) {
                                        yield return new Suppression (info, originAttribute: instance, provider);
                                        continue;
index e7fa4c1..a76f3af 100644 (file)
@@ -9,4 +9,4 @@ namespace Mono.Linker
                ILLink5 = 5,
                Latest = 9999,
        }
-}
\ No newline at end of file
+}
index f9e1f6a..bf88c68 100644 (file)
@@ -82,7 +82,7 @@ namespace TLens.Analyzers
                public override void PrintResults (int maxCount)
                {
                        var static_entries = fields.Where (l => l.Value == Access.Write && l.Key.IsStatic).
-                               OrderBy (l => l.Key, new FieldTypeSizeComparer ()).
+                               OrderBy (l => l.Key, default (FieldTypeSizeComparer)).
                                ThenBy (l => l.Key.DeclaringType.FullName).
                                Take (maxCount);
                        if (static_entries.Any ()) {
@@ -100,7 +100,7 @@ namespace TLens.Analyzers
                        }
 
                        var instance_entries = fields.Where (l => l.Value == Access.Write && !l.Key.IsStatic).
-                               OrderBy (l => l.Key, new FieldTypeSizeComparer ()).
+                               OrderBy (l => l.Key, default (FieldTypeSizeComparer)).
                                ThenBy (l => l.Key.DeclaringType.FullName).
                                Take (maxCount);
                        if (instance_entries.Any ()) {
index 00b79fe..c286139 100644 (file)
@@ -62,7 +62,7 @@ namespace TLens.Analyzers
                        PrintHeader ("User operators used for null checks");
 
                        foreach (var e in entries) {
-                               Console.WriteLine ($"User operator '{e.Key.ToDisplay ()}' was called {e.Value.Redundant} [{e.Value.Ratio.ToString ("0%")}] times with null values");
+                               Console.WriteLine ($"User operator '{e.Key.ToDisplay ()}' was called {e.Value.Redundant} [{e.Value.Ratio:0%}] times with null values");
                        }
                }
        }
index 5eb9451..f702c8f 100644 (file)
@@ -17,7 +17,7 @@ namespace TLens
                        if (showSize) {
                                str.Append (" [size: ");
                                str.Append (method.GetEstimatedSize ());
-                               str.Append ("]");
+                               str.Append (']');
                        }
 
                        return str.ToString ();