diff --git a/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertToBlockScopedNamespaceDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertToBlockScopedNamespaceDiagnosticAnalyzer.cs index 1d5539926ec85..4b6d0dfef636e 100644 --- a/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertToBlockScopedNamespaceDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertToBlockScopedNamespaceDiagnosticAnalyzer.cs @@ -68,7 +68,7 @@ private void AnalyzeNamespace(SyntaxNodeAnalysisContext context) diagnosticLocation, severity, ImmutableArray.Create(declaration.GetLocation()), - ImmutableDictionary.Empty); + ImmutableDictionary.Empty); } } } diff --git a/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertToFileScopedNamespaceDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertToFileScopedNamespaceDiagnosticAnalyzer.cs index d5a62dd630240..2f8ed54e81d6f 100644 --- a/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertToFileScopedNamespaceDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertToFileScopedNamespaceDiagnosticAnalyzer.cs @@ -70,7 +70,7 @@ private void AnalyzeNamespace(SyntaxNodeAnalysisContext context) diagnosticLocation, severity, ImmutableArray.Create(declaration.GetLocation()), - ImmutableDictionary.Empty); + ImmutableDictionary.Empty); } } } diff --git a/src/Analyzers/CSharp/Analyzers/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorDiagnosticAnalyzer.cs index 30287bc049515..34fd781be78a6 100644 --- a/src/Analyzers/CSharp/Analyzers/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorDiagnosticAnalyzer.cs @@ -14,8 +14,8 @@ namespace Microsoft.CodeAnalysis.CSharp.UseIsNullCheck internal class CSharpUseIsNullCheckForCastAndEqualityOperatorDiagnosticAnalyzer : AbstractBuiltInCodeStyleDiagnosticAnalyzer { - private static readonly ImmutableDictionary s_properties = - ImmutableDictionary.Empty.Add(UseIsNullConstants.Kind, UseIsNullConstants.CastAndEqualityKey); + private static readonly ImmutableDictionary s_properties = + ImmutableDictionary.Empty.Add(UseIsNullConstants.Kind, UseIsNullConstants.CastAndEqualityKey); public CSharpUseIsNullCheckForCastAndEqualityOperatorDiagnosticAnalyzer() : base(IDEDiagnosticIds.UseIsNullCheckDiagnosticId, diff --git a/src/Analyzers/CSharp/Analyzers/UsePatternCombinators/CSharpUsePatternCombinatorsDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UsePatternCombinators/CSharpUsePatternCombinatorsDiagnosticAnalyzer.cs index 32ed3acded379..574dc7b83c156 100644 --- a/src/Analyzers/CSharp/Analyzers/UsePatternCombinators/CSharpUsePatternCombinatorsDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UsePatternCombinators/CSharpUsePatternCombinatorsDiagnosticAnalyzer.cs @@ -24,7 +24,7 @@ internal sealed class CSharpUsePatternCombinatorsDiagnosticAnalyzer : private static readonly LocalizableResourceString s_safePatternTitle = new(nameof(CSharpAnalyzersResources.Use_pattern_matching), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)); private static readonly LocalizableResourceString s_unsafePatternTitle = new(nameof(CSharpAnalyzersResources.Use_pattern_matching_may_change_code_meaning), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)); - private static readonly ImmutableDictionary s_safeProperties = ImmutableDictionary.Empty.Add(SafeKey, ""); + private static readonly ImmutableDictionary s_safeProperties = ImmutableDictionary.Empty.Add(SafeKey, ""); private static readonly DiagnosticDescriptor s_unsafeDescriptor = CreateDescriptorWithId( IDEDiagnosticIds.UsePatternCombinatorsDiagnosticId, EnforceOnBuildValues.UsePatternCombinators, diff --git a/src/Analyzers/Core/Analyzers/AbstractCodeQualityDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/AbstractCodeQualityDiagnosticAnalyzer.cs index d044fe182f8c5..fc9a416b416d0 100644 --- a/src/Analyzers/Core/Analyzers/AbstractCodeQualityDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/AbstractCodeQualityDiagnosticAnalyzer.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeStyle; @@ -55,7 +53,7 @@ protected static DiagnosticDescriptor CreateDescriptor( bool isUnnecessary, bool isEnabledByDefault = true, bool isConfigurable = true, - LocalizableString description = null) + LocalizableString? description = null) #pragma warning disable RS0030 // Do not used banned APIs => new( id, title, messageFormat, diff --git a/src/Analyzers/Core/Analyzers/AbstractParenthesesDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/AbstractParenthesesDiagnosticAnalyzer.cs index 86ac62500bfd4..006957cb9a605 100644 --- a/src/Analyzers/Core/Analyzers/AbstractParenthesesDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/AbstractParenthesesDiagnosticAnalyzer.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Options; diff --git a/src/Analyzers/Core/Analyzers/AddRequiredParentheses/AbstractAddRequiredParenthesesDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/AddRequiredParentheses/AbstractAddRequiredParenthesesDiagnosticAnalyzer.cs index c60d59b53fc0b..93d00393d172d 100644 --- a/src/Analyzers/Core/Analyzers/AddRequiredParentheses/AbstractAddRequiredParenthesesDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/AddRequiredParentheses/AbstractAddRequiredParenthesesDiagnosticAnalyzer.cs @@ -19,7 +19,7 @@ internal abstract class AbstractAddRequiredParenthesesDiagnosticAnalyzer< where TBinaryLikeExpressionSyntax : TExpressionSyntax where TLanguageKindEnum : struct { - private static readonly Dictionary<(bool includeInFixAll, string equivalenceKey), ImmutableDictionary> s_cachedProperties = + private static readonly Dictionary<(bool includeInFixAll, string equivalenceKey), ImmutableDictionary> s_cachedProperties = new(); private readonly IPrecedenceService _precedenceService; @@ -38,7 +38,7 @@ static AbstractAddRequiredParenthesesDiagnosticAnalyzer() { foreach (var includeInFixAll in includeArray) { - var properties = ImmutableDictionary.Empty; + var properties = ImmutableDictionary.Empty; if (includeInFixAll) { properties = properties.Add(AddRequiredParenthesesConstants.IncludeInFixAll, ""); @@ -54,7 +54,7 @@ static AbstractAddRequiredParenthesesDiagnosticAnalyzer() private static string GetEquivalenceKey(PerLanguageOption2> parentPrecedence) => parentPrecedence.Name; - private static ImmutableDictionary GetProperties(bool includeInFixAll, string equivalenceKey) + private static ImmutableDictionary GetProperties(bool includeInFixAll, string equivalenceKey) => s_cachedProperties[(includeInFixAll, equivalenceKey)]; protected abstract int GetPrecedence(TBinaryLikeExpressionSyntax binaryLike); diff --git a/src/Analyzers/Core/Analyzers/AddRequiredParentheses/AddRequiredParenthesesConstants.cs b/src/Analyzers/Core/Analyzers/AddRequiredParentheses/AddRequiredParenthesesConstants.cs index cd8c91ac747c0..a40c765ed1170 100644 --- a/src/Analyzers/Core/Analyzers/AddRequiredParentheses/AddRequiredParenthesesConstants.cs +++ b/src/Analyzers/Core/Analyzers/AddRequiredParentheses/AddRequiredParenthesesConstants.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - namespace Microsoft.CodeAnalysis.AddRequiredParentheses { internal static class AddRequiredParenthesesConstants diff --git a/src/Analyzers/Core/Analyzers/Helpers/DeserializationConstructorCheck.cs b/src/Analyzers/Core/Analyzers/Helpers/DeserializationConstructorCheck.cs index 949403c077648..1d41379bdfc4c 100644 --- a/src/Analyzers/Core/Analyzers/Helpers/DeserializationConstructorCheck.cs +++ b/src/Analyzers/Core/Analyzers/Helpers/DeserializationConstructorCheck.cs @@ -2,17 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.Shared.Utilities { internal readonly struct DeserializationConstructorCheck { - private readonly INamedTypeSymbol _iSerializableType; - private readonly INamedTypeSymbol _serializationInfoType; - private readonly INamedTypeSymbol _streamingContextType; + private readonly INamedTypeSymbol? _iSerializableType; + private readonly INamedTypeSymbol? _serializationInfoType; + private readonly INamedTypeSymbol? _streamingContextType; public DeserializationConstructorCheck(Compilation compilation) { diff --git a/src/Analyzers/Core/Analyzers/Helpers/DiagnosticHelper.cs b/src/Analyzers/Core/Analyzers/Helpers/DiagnosticHelper.cs index 87908bb9732ee..b53dcd6787287 100644 --- a/src/Analyzers/Core/Analyzers/Helpers/DiagnosticHelper.cs +++ b/src/Analyzers/Core/Analyzers/Helpers/DiagnosticHelper.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -41,8 +39,8 @@ public static Diagnostic Create( DiagnosticDescriptor descriptor, Location location, ReportDiagnostic effectiveSeverity, - IEnumerable additionalLocations, - ImmutableDictionary properties, + IEnumerable? additionalLocations, + ImmutableDictionary? properties, params object[] messageArgs) { if (descriptor == null) @@ -92,7 +90,7 @@ public static Diagnostic CreateWithLocationTags( { if (additionalUnnecessaryLocations.IsEmpty) { - return Create(descriptor, location, effectiveSeverity, additionalLocations, ImmutableDictionary.Empty, messageArgs); + return Create(descriptor, location, effectiveSeverity, additionalLocations, ImmutableDictionary.Empty, messageArgs); } var tagIndices = ImmutableDictionary>.Empty @@ -103,7 +101,7 @@ public static Diagnostic CreateWithLocationTags( effectiveSeverity, additionalLocations.AddRange(additionalUnnecessaryLocations), tagIndices, - ImmutableDictionary.Empty, + ImmutableDictionary.Empty, messageArgs); } @@ -136,12 +134,12 @@ public static Diagnostic CreateWithLocationTags( ReportDiagnostic effectiveSeverity, ImmutableArray additionalLocations, ImmutableArray additionalUnnecessaryLocations, - ImmutableDictionary properties, + ImmutableDictionary properties, params object[] messageArgs) { if (additionalUnnecessaryLocations.IsEmpty) { - return Create(descriptor, location, effectiveSeverity, additionalLocations, ImmutableDictionary.Empty, messageArgs); + return Create(descriptor, location, effectiveSeverity, additionalLocations, ImmutableDictionary.Empty, messageArgs); } var tagIndices = ImmutableDictionary>.Empty @@ -182,14 +180,14 @@ private static Diagnostic CreateWithLocationTags( ReportDiagnostic effectiveSeverity, IEnumerable additionalLocations, IDictionary> tagIndices, - ImmutableDictionary properties, + ImmutableDictionary properties, params object[] messageArgs) { Contract.ThrowIfTrue(additionalLocations.IsEmpty()); Contract.ThrowIfTrue(tagIndices.IsEmpty()); - properties ??= ImmutableDictionary.Empty; - properties = properties.AddRange(tagIndices.Select(kvp => new KeyValuePair(kvp.Key, EncodeIndices(kvp.Value, additionalLocations.Count())))); + properties ??= ImmutableDictionary.Empty; + properties = properties.AddRange(tagIndices.Select(kvp => new KeyValuePair(kvp.Key, EncodeIndices(kvp.Value, additionalLocations.Count())))); return Create(descriptor, location, effectiveSeverity, additionalLocations, properties, messageArgs); @@ -230,8 +228,8 @@ public static Diagnostic CreateWithMessage( DiagnosticDescriptor descriptor, Location location, ReportDiagnostic effectiveSeverity, - IEnumerable additionalLocations, - ImmutableDictionary properties, + IEnumerable? additionalLocations, + ImmutableDictionary? properties, LocalizableString message) { if (descriptor == null) @@ -257,7 +255,7 @@ public static Diagnostic CreateWithMessage( properties); } - public static string GetHelpLinkForDiagnosticId(string id) + public static string? GetHelpLinkForDiagnosticId(string id) { if (id == "RE0001") { @@ -332,7 +330,7 @@ void IObjectWritable.WriteTo(ObjectWriter writer) } } - protected override string GetText(IFormatProvider formatProvider) + protected override string GetText(IFormatProvider? formatProvider) { var messageFormat = _messageFormat.ToString(formatProvider); return messageFormat != null ? @@ -340,7 +338,7 @@ protected override string GetText(IFormatProvider formatProvider) string.Empty; } - protected override bool AreEqual(object other) + protected override bool AreEqual(object? other) { return other is LocalizableStringWithArguments otherResourceString && _messageFormat.Equals(otherResourceString._messageFormat) && diff --git a/src/Analyzers/Core/Analyzers/IDEDiagnosticIdToOptionMappingHelper.cs b/src/Analyzers/Core/Analyzers/IDEDiagnosticIdToOptionMappingHelper.cs index b7fa423faef0d..7d5cf8bebc633 100644 --- a/src/Analyzers/Core/Analyzers/IDEDiagnosticIdToOptionMappingHelper.cs +++ b/src/Analyzers/Core/Analyzers/IDEDiagnosticIdToOptionMappingHelper.cs @@ -2,12 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Collections.Concurrent; using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.CodeAnalysis.Options; @@ -23,7 +22,7 @@ internal static class IDEDiagnosticIdToOptionMappingHelper private static readonly ConcurrentDictionary> s_diagnosticIdToOptionMap = new(); private static readonly ConcurrentDictionary>> s_diagnosticIdToLanguageSpecificOptionsMap = new(); - public static bool TryGetMappedOptions(string diagnosticId, string language, out ImmutableHashSet options) + public static bool TryGetMappedOptions(string diagnosticId, string language, [NotNullWhen(true)] out ImmutableHashSet? options) => s_diagnosticIdToOptionMap.TryGetValue(diagnosticId, out options) || (s_diagnosticIdToLanguageSpecificOptionsMap.TryGetValue(language, out var map) && map.TryGetValue(diagnosticId, out options)); diff --git a/src/Analyzers/Core/Analyzers/IDEDiagnosticIds.cs b/src/Analyzers/Core/Analyzers/IDEDiagnosticIds.cs index 551c36c740958..60673a45856a5 100644 --- a/src/Analyzers/Core/Analyzers/IDEDiagnosticIds.cs +++ b/src/Analyzers/Core/Analyzers/IDEDiagnosticIds.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using Microsoft.CodeAnalysis.Formatting; namespace Microsoft.CodeAnalysis.Diagnostics diff --git a/src/Analyzers/Core/Analyzers/NamingStyle/NamingStyleDiagnosticAnalyzerBase.cs b/src/Analyzers/Core/Analyzers/NamingStyle/NamingStyleDiagnosticAnalyzerBase.cs index 3a6e82d88639d..f0884382b3d8e 100644 --- a/src/Analyzers/Core/Analyzers/NamingStyle/NamingStyleDiagnosticAnalyzerBase.cs +++ b/src/Analyzers/Core/Analyzers/NamingStyle/NamingStyleDiagnosticAnalyzerBase.cs @@ -159,7 +159,7 @@ void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext) return null; } - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(); builder[nameof(NamingStyle)] = applicableRule.NamingStyle.CreateXElement().ToString(); builder["OptionName"] = nameof(NamingStyleOptions.NamingPreferences); builder["OptionLanguage"] = compilation.Language; diff --git a/src/Analyzers/Core/Analyzers/OrderModifiers/AbstractOrderModifiersDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/OrderModifiers/AbstractOrderModifiersDiagnosticAnalyzer.cs index a9d22a3f18020..4663d2ff4c60b 100644 --- a/src/Analyzers/Core/Analyzers/OrderModifiers/AbstractOrderModifiersDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/OrderModifiers/AbstractOrderModifiersDiagnosticAnalyzer.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Generic; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Diagnostics; diff --git a/src/Analyzers/Core/Analyzers/OrderModifiers/OrderModifiersHelpers.cs b/src/Analyzers/Core/Analyzers/OrderModifiers/OrderModifiersHelpers.cs index 454b5f44e7c90..9f43976bed603 100644 --- a/src/Analyzers/Core/Analyzers/OrderModifiers/OrderModifiersHelpers.cs +++ b/src/Analyzers/Core/Analyzers/OrderModifiers/OrderModifiersHelpers.cs @@ -2,10 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Threading; namespace Microsoft.CodeAnalysis.OrderModifiers @@ -17,7 +16,7 @@ internal abstract class AbstractOrderModifiersHelpers /// /// Reference type so we can read/write atomically. /// - private Tuple> _lastParsed; + private Tuple>? _lastParsed; protected abstract int GetKeywordKind(string trimmed); @@ -41,7 +40,7 @@ public static bool IsOrdered(Dictionary preferredOrder, SyntaxTokenLis return true; } - public bool TryGetOrComputePreferredOrder(string value, out Dictionary preferredOrder) + public bool TryGetOrComputePreferredOrder(string value, [NotNullWhen(true)] out Dictionary? preferredOrder) { if (string.IsNullOrWhiteSpace(value)) { @@ -66,7 +65,7 @@ public bool TryGetOrComputePreferredOrder(string value, out Dictionary return true; } - protected virtual bool TryParse(string value, out Dictionary parsed) + protected virtual bool TryParse(string value, [NotNullWhen(true)] out Dictionary? parsed) { var result = new Dictionary(); diff --git a/src/Analyzers/Core/Analyzers/QualifyMemberAccess/AbstractQualifyMemberAccessDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/QualifyMemberAccess/AbstractQualifyMemberAccessDiagnosticAnalyzer.cs index 74c175fc6bcdf..5274b582473cd 100644 --- a/src/Analyzers/Core/Analyzers/QualifyMemberAccess/AbstractQualifyMemberAccessDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/QualifyMemberAccess/AbstractQualifyMemberAccessDiagnosticAnalyzer.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Diagnostics; @@ -87,51 +85,37 @@ private void AnalyzeOperation(OperationAnalysisContext context) } } - private void AnalyzeOperation(OperationAnalysisContext context, IOperation operation, IOperation instanceOperation) + private void AnalyzeOperation(OperationAnalysisContext context, IOperation operation, IOperation? instanceOperation) { // this is a static reference so we don't care if it's qualified if (instanceOperation == null) - { return; - } // if we're not referencing `this.` or `Me.` (e.g., a parameter, local, etc.) if (instanceOperation.Kind != OperationKind.InstanceReference) - { return; - } // We shouldn't qualify if it is inside a property pattern - if (context.Operation.Parent.Kind == OperationKind.PropertySubpattern) - { + if (context.Operation.Parent?.Kind == OperationKind.PropertySubpattern) return; - } // Initializer lists are IInvocationOperation which if passed to GetApplicableOptionFromSymbolKind // will incorrectly fetch the options for method call. // We still want to handle InstanceReferenceKind.ContainingTypeInstance if ((instanceOperation as IInstanceReferenceOperation)?.ReferenceKind == InstanceReferenceKind.ImplicitReceiver) - { return; - } // If we can't be qualified (e.g., because we're already qualified with `base.`), we're done. if (!CanMemberAccessBeQualified(context.ContainingSymbol, instanceOperation.Syntax)) - { return; - } // if we can't find a member then we can't do anything. Also, we shouldn't qualify // accesses to static members. if (IsStaticMemberOrIsLocalFunction(operation)) - { return; - } if (instanceOperation.Syntax is not TSimpleNameSyntax simpleName) - { return; - } var applicableOption = QualifyMembersHelpers.GetApplicableOptionFromSymbolKind(operation); var optionValue = context.GetOption(applicableOption, context.Operation.Syntax.Language); diff --git a/src/Analyzers/Core/Analyzers/RemoveUnnecessaryImports/AbstractRemoveUnnecessaryImportsDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/RemoveUnnecessaryImports/AbstractRemoveUnnecessaryImportsDiagnosticAnalyzer.cs index bb8987d95ec05..a20583d5b79a1 100644 --- a/src/Analyzers/Core/Analyzers/RemoveUnnecessaryImports/AbstractRemoveUnnecessaryImportsDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/RemoveUnnecessaryImports/AbstractRemoveUnnecessaryImportsDiagnosticAnalyzer.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -44,71 +42,67 @@ internal abstract class AbstractRemoveUnnecessaryImportsDiagnosticAnalyzer customTags: DiagnosticCustomTags.NotConfigurable); #pragma warning restore RS0030 // Do not used banned APIs - protected abstract LocalizableString GetTitleAndMessageFormatForClassificationIdDescriptor(); - protected abstract ImmutableArray MergeImports(ImmutableArray unnecessaryImports); - protected abstract bool IsRegularCommentOrDocComment(SyntaxTrivia trivia); - protected abstract IUnnecessaryImportsProvider UnnecessaryImportsProvider { get; } - - private DiagnosticDescriptor _unnecessaryClassificationIdDescriptor; - private DiagnosticDescriptor _classificationIdDescriptor; - private DiagnosticDescriptor _unnecessaryGeneratedCodeClassificationIdDescriptor; - private DiagnosticDescriptor _generatedCodeClassificationIdDescriptor; + private readonly DiagnosticDescriptor _unnecessaryClassificationIdDescriptor; + private readonly DiagnosticDescriptor _classificationIdDescriptor; + private readonly DiagnosticDescriptor _unnecessaryGeneratedCodeClassificationIdDescriptor; + private readonly DiagnosticDescriptor _generatedCodeClassificationIdDescriptor; - private void EnsureClassificationIdDescriptors() + protected AbstractRemoveUnnecessaryImportsDiagnosticAnalyzer() { - if (_unnecessaryClassificationIdDescriptor == null) - { - var titleAndMessageFormat = GetTitleAndMessageFormatForClassificationIdDescriptor(); + var titleAndMessageFormat = GetTitleAndMessageFormatForClassificationIdDescriptor(); #pragma warning disable RS0030 // Do not used banned APIs - _unnecessaryClassificationIdDescriptor = - new DiagnosticDescriptor(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId, - titleAndMessageFormat, - titleAndMessageFormat, - DiagnosticCategory.Style, - DiagnosticSeverity.Hidden, - isEnabledByDefault: true, - helpLinkUri: DiagnosticHelper.GetHelpLinkForDiagnosticId(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId), - customTags: DiagnosticCustomTags.Unnecessary.Concat(EnforceOnBuildValues.RemoveUnnecessaryImports.ToCustomTag()).ToArray()); - - _classificationIdDescriptor = - new DiagnosticDescriptor(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId, - titleAndMessageFormat, - titleAndMessageFormat, - DiagnosticCategory.Style, - DiagnosticSeverity.Hidden, - isEnabledByDefault: true, - helpLinkUri: DiagnosticHelper.GetHelpLinkForDiagnosticId(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId), - customTags: EnforceOnBuildValues.RemoveUnnecessaryImports.ToCustomTag()); - - _unnecessaryGeneratedCodeClassificationIdDescriptor = - new DiagnosticDescriptor(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId + "_gen", - titleAndMessageFormat, - titleAndMessageFormat, - DiagnosticCategory.Style, - DiagnosticSeverity.Hidden, - isEnabledByDefault: true, - helpLinkUri: DiagnosticHelper.GetHelpLinkForDiagnosticId(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId), - customTags: DiagnosticCustomTags.UnnecessaryAndNotConfigurable); - - _generatedCodeClassificationIdDescriptor = - new DiagnosticDescriptor(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId + "_gen", - titleAndMessageFormat, - titleAndMessageFormat, - DiagnosticCategory.Style, - DiagnosticSeverity.Hidden, - isEnabledByDefault: true, - helpLinkUri: DiagnosticHelper.GetHelpLinkForDiagnosticId(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId), - customTags: DiagnosticCustomTags.NotConfigurable); + _unnecessaryClassificationIdDescriptor = + new DiagnosticDescriptor(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId, + titleAndMessageFormat, + titleAndMessageFormat, + DiagnosticCategory.Style, + DiagnosticSeverity.Hidden, + isEnabledByDefault: true, + helpLinkUri: DiagnosticHelper.GetHelpLinkForDiagnosticId(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId), + customTags: DiagnosticCustomTags.Unnecessary.Concat(EnforceOnBuildValues.RemoveUnnecessaryImports.ToCustomTag()).ToArray()); + + _classificationIdDescriptor = + new DiagnosticDescriptor(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId, + titleAndMessageFormat, + titleAndMessageFormat, + DiagnosticCategory.Style, + DiagnosticSeverity.Hidden, + isEnabledByDefault: true, + helpLinkUri: DiagnosticHelper.GetHelpLinkForDiagnosticId(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId), + customTags: EnforceOnBuildValues.RemoveUnnecessaryImports.ToCustomTag()); + + _unnecessaryGeneratedCodeClassificationIdDescriptor = + new DiagnosticDescriptor(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId + "_gen", + titleAndMessageFormat, + titleAndMessageFormat, + DiagnosticCategory.Style, + DiagnosticSeverity.Hidden, + isEnabledByDefault: true, + helpLinkUri: DiagnosticHelper.GetHelpLinkForDiagnosticId(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId), + customTags: DiagnosticCustomTags.UnnecessaryAndNotConfigurable); + + _generatedCodeClassificationIdDescriptor = + new DiagnosticDescriptor(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId + "_gen", + titleAndMessageFormat, + titleAndMessageFormat, + DiagnosticCategory.Style, + DiagnosticSeverity.Hidden, + isEnabledByDefault: true, + helpLinkUri: DiagnosticHelper.GetHelpLinkForDiagnosticId(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId), + customTags: DiagnosticCustomTags.NotConfigurable); #pragma warning restore RS0030 // Do not used banned APIs - } } + protected abstract LocalizableString GetTitleAndMessageFormatForClassificationIdDescriptor(); + protected abstract ImmutableArray MergeImports(ImmutableArray unnecessaryImports); + protected abstract bool IsRegularCommentOrDocComment(SyntaxTrivia trivia); + protected abstract IUnnecessaryImportsProvider UnnecessaryImportsProvider { get; } + public override ImmutableArray SupportedDiagnostics { get { - EnsureClassificationIdDescriptors(); return ImmutableArray.Create( s_fixableIdDescriptor, _unnecessaryClassificationIdDescriptor, @@ -145,7 +139,6 @@ private void AnalyzeSemanticModel(SemanticModelAnalysisContext context) // for us appropriately. unnecessaryImports = MergeImports(unnecessaryImports); - EnsureClassificationIdDescriptors(); var fadeOut = ShouldFade(context.Options, tree, language, cancellationToken); DiagnosticDescriptor descriptor; @@ -176,7 +169,7 @@ static bool ShouldFade(AnalyzerOptions options, SyntaxTree tree, string language } } - protected virtual Func GetLastTokenDelegateForContiguousSpans() + protected virtual Func? GetLastTokenDelegateForContiguousSpans() => null; // Create one diagnostic for each unnecessary span that will be classified as Unnecessary diff --git a/src/Analyzers/Core/Analyzers/RemoveUnusedParametersAndValues/AbstractRemoveUnusedParametersAndValuesDiagnosticAnalyzer.SymbolStartAnalyzer.BlockAnalyzer.cs b/src/Analyzers/Core/Analyzers/RemoveUnusedParametersAndValues/AbstractRemoveUnusedParametersAndValuesDiagnosticAnalyzer.SymbolStartAnalyzer.BlockAnalyzer.cs index 25c131192aa8c..f110f9e90fdb9 100644 --- a/src/Analyzers/Core/Analyzers/RemoveUnusedParametersAndValues/AbstractRemoveUnusedParametersAndValuesDiagnosticAnalyzer.SymbolStartAnalyzer.BlockAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/RemoveUnusedParametersAndValues/AbstractRemoveUnusedParametersAndValuesDiagnosticAnalyzer.SymbolStartAnalyzer.BlockAnalyzer.cs @@ -613,7 +613,7 @@ bool ShouldReportUnusedValueDiagnostic( ISymbol symbol, IOperation unreadWriteOperation, SymbolUsageResult resultFromFlowAnalysis, - out ImmutableDictionary? properties) + out ImmutableDictionary? properties) { Debug.Assert(symbol is not ILocalSymbol local || !local.IsRef); diff --git a/src/Analyzers/Core/Analyzers/SimplifyBooleanExpression/AbstractSimplifyConditionalDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/SimplifyBooleanExpression/AbstractSimplifyConditionalDiagnosticAnalyzer.cs index 06fca2e8fbeda..400f515c55b20 100644 --- a/src/Analyzers/Core/Analyzers/SimplifyBooleanExpression/AbstractSimplifyConditionalDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/SimplifyBooleanExpression/AbstractSimplifyConditionalDiagnosticAnalyzer.cs @@ -23,19 +23,19 @@ internal abstract class AbstractSimplifyConditionalDiagnosticAnalyzer< where TExpressionSyntax : SyntaxNode where TConditionalExpressionSyntax : TExpressionSyntax { - private static readonly ImmutableDictionary s_takeCondition - = ImmutableDictionary.Empty; - private static readonly ImmutableDictionary s_negateCondition + private static readonly ImmutableDictionary s_takeCondition + = ImmutableDictionary.Empty; + private static readonly ImmutableDictionary s_negateCondition = s_takeCondition.Add(Negate, Negate); - private static readonly ImmutableDictionary s_takeConditionOrWhenFalse + private static readonly ImmutableDictionary s_takeConditionOrWhenFalse = s_takeCondition.Add(Or, Or).Add(WhenFalse, WhenFalse); - private static readonly ImmutableDictionary s_negateConditionAndWhenFalse + private static readonly ImmutableDictionary s_negateConditionAndWhenFalse = s_negateCondition.Add(And, And).Add(WhenFalse, WhenFalse); - private static readonly ImmutableDictionary s_negateConditionOrWhenTrue + private static readonly ImmutableDictionary s_negateConditionOrWhenTrue = s_negateCondition.Add(Or, Or).Add(WhenTrue, WhenTrue); - private static readonly ImmutableDictionary s_takeConditionAndWhenTrue + private static readonly ImmutableDictionary s_takeConditionAndWhenTrue = s_takeCondition.Add(And, And).Add(WhenTrue, WhenTrue); - private static readonly ImmutableDictionary s_takeConditionAndWhenFalse + private static readonly ImmutableDictionary s_takeConditionAndWhenFalse = s_takeCondition.Add(And, And).Add(WhenFalse, WhenFalse); protected AbstractSimplifyConditionalDiagnosticAnalyzer() @@ -141,7 +141,7 @@ private void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context) // local functions - void ReportDiagnostic(ImmutableDictionary properties) + void ReportDiagnostic(ImmutableDictionary properties) => context.ReportDiagnostic(DiagnosticHelper.Create( Descriptor, conditionalExpression.GetLocation(), diff --git a/src/Analyzers/Core/Analyzers/SimplifyInterpolation/AbstractSimplifyInterpolationDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/SimplifyInterpolation/AbstractSimplifyInterpolationDiagnosticAnalyzer.cs index aaedb6caad853..34cbe384700fd 100644 --- a/src/Analyzers/Core/Analyzers/SimplifyInterpolation/AbstractSimplifyInterpolationDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/SimplifyInterpolation/AbstractSimplifyInterpolationDiagnosticAnalyzer.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Diagnostics; diff --git a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/ObjectCreationExpressionAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/ObjectCreationExpressionAnalyzer.cs index 7095342b9bbed..42cb24ce89e3b 100644 --- a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/ObjectCreationExpressionAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/ObjectCreationExpressionAnalyzer.cs @@ -2,13 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.UseCollectionInitializer { @@ -57,7 +57,7 @@ private static readonly ObjectPool matches) { - var containingBlock = _containingStatement.Parent; + var containingBlock = _containingStatement.GetRequiredParent(); var foundStatement = false; var seenInvocation = false; @@ -85,32 +85,18 @@ protected override void AddMatches(ArrayBuilder matc return; } - SyntaxNode instance = null; - if (!seenIndexAssignment) - { - if (TryAnalyzeAddInvocation(statement, out instance)) - { - seenInvocation = true; - } - } + SyntaxNode? instance = null; + if (!seenIndexAssignment && TryAnalyzeAddInvocation(statement, out instance)) + seenInvocation = true; - if (!seenInvocation) - { - if (TryAnalyzeIndexAssignment(statement, out instance)) - { - seenIndexAssignment = true; - } - } + if (!seenInvocation && TryAnalyzeIndexAssignment(statement, out instance)) + seenIndexAssignment = true; if (instance == null) - { return; - } if (!ValuePatternMatches((TExpressionSyntax)instance)) - { return; - } matches.Add(statement); } @@ -135,86 +121,64 @@ protected override bool ShouldAnalyze() private bool TryAnalyzeIndexAssignment( TExpressionStatementSyntax statement, - out SyntaxNode instance) + [NotNullWhen(true)] out SyntaxNode? instance) { instance = null; if (!_syntaxFacts.SupportsIndexingInitializer(statement.SyntaxTree.Options)) - { return false; - } if (!_syntaxFacts.IsSimpleAssignmentStatement(statement)) - { return false; - } _syntaxFacts.GetPartsOfAssignmentStatement(statement, out var left, out var right); if (!_syntaxFacts.IsElementAccessExpression(left)) - { return false; - } // If we're initializing a variable, then we can't reference that variable on the right // side of the initialization. Rewriting this into a collection initializer would lead // to a definite-assignment error. if (ExpressionContainsValuePatternOrReferencesInitializedSymbol(right)) - { return false; - } instance = _syntaxFacts.GetExpressionOfElementAccessExpression(left); - return true; + return instance != null; } private bool TryAnalyzeAddInvocation( TExpressionStatementSyntax statement, - out SyntaxNode instance) + [NotNullWhen(true)] out SyntaxNode? instance) { instance = null; if (_syntaxFacts.GetExpressionOfExpressionStatement(statement) is not TInvocationExpressionSyntax invocationExpression) - { return false; - } var arguments = _syntaxFacts.GetArgumentsOfInvocationExpression(invocationExpression); if (arguments.Count < 1) - { return false; - } foreach (var argument in arguments) { if (!_syntaxFacts.IsSimpleArgument(argument)) - { return false; - } var argumentExpression = _syntaxFacts.GetExpressionOfArgument(argument); if (ExpressionContainsValuePatternOrReferencesInitializedSymbol(argumentExpression)) - { return false; - } } if (_syntaxFacts.GetExpressionOfInvocationExpression(invocationExpression) is not TMemberAccessExpressionSyntax memberAccess) - { return false; - } if (!_syntaxFacts.IsSimpleMemberAccessExpression(memberAccess)) - { return false; - } _syntaxFacts.GetPartsOfMemberAccessExpression(memberAccess, out var localInstance, out var memberName); _syntaxFacts.GetNameAndArityOfSimpleName(memberName, out var name, out var arity); - if (arity != 0 || !name.Equals(WellKnownMemberNames.CollectionInitializerAddMethodName)) - { + if (arity != 0 || !Equals(name, WellKnownMemberNames.CollectionInitializerAddMethodName)) return false; - } instance = localInstance; return true; diff --git a/src/Analyzers/Core/Analyzers/UseCompoundAssignment/AbstractUseCompoundAssignmentDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseCompoundAssignment/AbstractUseCompoundAssignmentDiagnosticAnalyzer.cs index 76ddfc484e7a3..af90b5a3c4339 100644 --- a/src/Analyzers/Core/Analyzers/UseCompoundAssignment/AbstractUseCompoundAssignmentDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseCompoundAssignment/AbstractUseCompoundAssignmentDiagnosticAnalyzer.cs @@ -149,7 +149,7 @@ private void AnalyzeAssignment(SyntaxNodeAnalysisContext context) assignmentToken.GetLocation(), option.Notification.Severity, additionalLocations: ImmutableArray.Create(assignment.GetLocation()), - properties: ImmutableDictionary.Create() + properties: ImmutableDictionary.Create() .Add(UseCompoundAssignmentUtilities.Increment, UseCompoundAssignmentUtilities.Increment))); return; } @@ -160,7 +160,7 @@ private void AnalyzeAssignment(SyntaxNodeAnalysisContext context) assignmentToken.GetLocation(), option.Notification.Severity, additionalLocations: ImmutableArray.Create(assignment.GetLocation()), - properties: ImmutableDictionary.Create() + properties: ImmutableDictionary.Create() .Add(UseCompoundAssignmentUtilities.Decrement, UseCompoundAssignmentUtilities.Decrement))); return; } diff --git a/src/Analyzers/Core/Analyzers/UseCompoundAssignment/UseCompoundAssignmentUtilities.cs b/src/Analyzers/Core/Analyzers/UseCompoundAssignment/UseCompoundAssignmentUtilities.cs index 0536463b38e31..3d18f82d82c01 100644 --- a/src/Analyzers/Core/Analyzers/UseCompoundAssignment/UseCompoundAssignmentUtilities.cs +++ b/src/Analyzers/Core/Analyzers/UseCompoundAssignment/UseCompoundAssignmentUtilities.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; using System.Diagnostics; using System.Linq; @@ -21,7 +19,7 @@ internal static class UseCompoundAssignmentUtilities public static void GenerateMaps( ImmutableArray<(TSyntaxKind exprKind, TSyntaxKind assignmentKind, TSyntaxKind tokenKind)> kinds, out ImmutableDictionary binaryToAssignmentMap, - out ImmutableDictionary assignmentToTokenMap) + out ImmutableDictionary assignmentToTokenMap) where TSyntaxKind : struct { var binaryToAssignmentBuilder = ImmutableDictionary.CreateBuilder(); var assignmentToTokenBuilder = ImmutableDictionary.CreateBuilder(); diff --git a/src/Analyzers/Core/Analyzers/UseConditionalExpression/ForAssignment/AbstractUseConditionalExpressionForAssignmentDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseConditionalExpression/ForAssignment/AbstractUseConditionalExpressionForAssignmentDiagnosticAnalyzer.cs index f409af33e37ee..95dc54f63bef9 100644 --- a/src/Analyzers/Core/Analyzers/UseConditionalExpression/ForAssignment/AbstractUseConditionalExpressionForAssignmentDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseConditionalExpression/ForAssignment/AbstractUseConditionalExpressionForAssignmentDiagnosticAnalyzer.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; diff --git a/src/Analyzers/Core/Analyzers/UseExplicitTupleName/UseExplicitTupleNameDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseExplicitTupleName/UseExplicitTupleNameDiagnosticAnalyzer.cs index 5b4d2e71931dd..2c9f69c11ce95 100644 --- a/src/Analyzers/Core/Analyzers/UseExplicitTupleName/UseExplicitTupleNameDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseExplicitTupleName/UseExplicitTupleNameDiagnosticAnalyzer.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; using System.Linq; using System.Threading; @@ -58,10 +56,10 @@ private void AnalyzeOperation(OperationAnalysisContext context) if (namedField != null) { var memberAccessSyntax = fieldReferenceOperation.Syntax; - var nameNode = memberAccessSyntax.ChildNodesAndTokens().Reverse().FirstOrDefault(); + var nameNode = memberAccessSyntax.ChildNodesAndTokens().Reverse().FirstOrDefault().AsNode(); if (nameNode != null) { - var properties = ImmutableDictionary.Empty.Add( + var properties = ImmutableDictionary.Empty.Add( nameof(ElementName), namedField.Name); context.ReportDiagnostic(DiagnosticHelper.Create( Descriptor, @@ -75,7 +73,7 @@ private void AnalyzeOperation(OperationAnalysisContext context) } } - private static IFieldSymbol GetNamedField( + private static IFieldSymbol? GetNamedField( INamedTypeSymbol containingType, IFieldSymbol unnamedField, CancellationToken cancellationToken) { foreach (var member in containingType.GetMembers()) diff --git a/src/Analyzers/Core/Analyzers/UseInferredMemberName/AbstractUseInferredMemberNameDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseInferredMemberName/AbstractUseInferredMemberNameDiagnosticAnalyzer.cs index 2322940d7c53b..f657ef7d025f3 100644 --- a/src/Analyzers/Core/Analyzers/UseInferredMemberName/AbstractUseInferredMemberNameDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseInferredMemberName/AbstractUseInferredMemberNameDiagnosticAnalyzer.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; using System.Threading; using Microsoft.CodeAnalysis.CodeStyle; diff --git a/src/Analyzers/Core/Analyzers/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsDiagnosticAnalyzer.cs index 62530ec8162f3..b842fa5fc362d 100644 --- a/src/Analyzers/Core/Analyzers/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsDiagnosticAnalyzer.cs @@ -104,7 +104,7 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context, IMethodSymbol refe return; } - var properties = ImmutableDictionary.Empty.Add( + var properties = ImmutableDictionary.Empty.Add( UseIsNullConstants.Kind, UseIsNullConstants.ReferenceEqualsKey); var genericParameterSymbol = GetGenericParameterSymbol(syntaxFacts, semanticModel, arguments[0], arguments[1], cancellationToken); diff --git a/src/Analyzers/Core/Analyzers/UseIsNullCheck/UseIsNullConstants.cs b/src/Analyzers/Core/Analyzers/UseIsNullCheck/UseIsNullConstants.cs index 08e46e4b5ff41..cfba4fe5746ee 100644 --- a/src/Analyzers/Core/Analyzers/UseIsNullCheck/UseIsNullConstants.cs +++ b/src/Analyzers/Core/Analyzers/UseIsNullCheck/UseIsNullConstants.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - namespace Microsoft.CodeAnalysis.UseIsNullCheck { internal static class UseIsNullConstants diff --git a/src/Analyzers/Core/Analyzers/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs index ea9f9e977b8c3..e498e23f805fc 100644 --- a/src/Analyzers/Core/Analyzers/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs @@ -170,7 +170,7 @@ private void AnalyzeSyntax( conditionPartToCheck.GetLocation(), whenPartToCheck.GetLocation()); - var properties = ImmutableDictionary.Empty; + var properties = ImmutableDictionary.Empty; var whenPartIsNullable = semanticModel.GetTypeInfo(whenPartMatch).Type?.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T; if (whenPartIsNullable) { diff --git a/src/Analyzers/Core/Analyzers/UseSystemHashCode/UseSystemHashCodeDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseSystemHashCode/UseSystemHashCodeDiagnosticAnalyzer.cs index c2a60e3112539..20ea5247730cd 100644 --- a/src/Analyzers/Core/Analyzers/UseSystemHashCode/UseSystemHashCodeDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseSystemHashCode/UseSystemHashCodeDiagnosticAnalyzer.cs @@ -78,7 +78,7 @@ private void AnalyzeOperationBlock(Analyzer analyzer, OperationBlockAnalysisCont owningSymbol.Locations[0], option.Notification.Severity, new[] { operationLocation, declarationLocation }, - ImmutableDictionary.Empty)); + ImmutableDictionary.Empty)); } } } diff --git a/src/Analyzers/Core/Analyzers/UseThrowExpression/AbstractUseThrowExpressionDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseThrowExpression/AbstractUseThrowExpressionDiagnosticAnalyzer.cs index 4b513c65bd2ee..35874a59db62a 100644 --- a/src/Analyzers/Core/Analyzers/UseThrowExpression/AbstractUseThrowExpressionDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseThrowExpression/AbstractUseThrowExpressionDiagnosticAnalyzer.cs @@ -2,15 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.Threading; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.UseThrowExpression { @@ -68,14 +68,18 @@ protected override void InitializeWorker(AnalysisContext context) }); } - private void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol expressionTypeOpt) + private void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol? expressionTypeOpt) { var cancellationToken = context.CancellationToken; var throwOperation = (IThrowOperation)context.Operation; + if (throwOperation.Exception == null) + return; + var throwStatementSyntax = throwOperation.Syntax; var semanticModel = context.Operation.SemanticModel; + Contract.ThrowIfNull(semanticModel); var ifOperation = GetContainingIfOperation( semanticModel, throwOperation, cancellationToken); @@ -83,9 +87,7 @@ private void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol // This throw statement isn't parented by an if-statement. Nothing to // do here. if (ifOperation == null) - { return; - } if (ifOperation.WhenFalse != null) { @@ -95,24 +97,16 @@ private void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol var option = context.GetOption(_preferThrowExpressionOption); if (!option.Value) - { return; - } if (IsInExpressionTree(semanticModel, throwStatementSyntax, expressionTypeOpt, cancellationToken)) - { return; - } if (ifOperation.Parent is not IBlockOperation containingBlock) - { return; - } if (!TryDecomposeIfCondition(ifOperation, out var localOrParameter)) - { return; - } if (!TryFindAssignmentExpression(containingBlock, ifOperation, localOrParameter, out var expressionStatement, out var assignmentExpression)) @@ -121,9 +115,7 @@ private void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol } if (!localOrParameter.GetSymbolType().CanAddNullCheck()) - { return; - } // We found an assignment using this local/parameter. Now, just make sure there // were no intervening accesses between the check and the assignment. @@ -172,11 +164,12 @@ private static bool ValueIsAccessed(SemanticModel semanticModel, IConditionalOpe exprDataFlow.WrittenInside.Contains(localOrParameter); } - protected abstract bool IsInExpressionTree(SemanticModel semanticModel, SyntaxNode node, INamedTypeSymbol expressionTypeOpt, CancellationToken cancellationToken); + protected abstract bool IsInExpressionTree(SemanticModel semanticModel, SyntaxNode node, INamedTypeSymbol? expressionTypeOpt, CancellationToken cancellationToken); private bool TryFindAssignmentExpression( IBlockOperation containingBlock, IConditionalOperation ifOperation, ISymbol localOrParameter, - out IExpressionStatementOperation expressionStatement, out IAssignmentOperation assignmentExpression) + [NotNullWhen(true)] out IExpressionStatementOperation? expressionStatement, + [NotNullWhen(true)] out IAssignmentOperation? assignmentExpression) { var ifOperationIndex = containingBlock.Operations.IndexOf(ifOperation); @@ -216,7 +209,7 @@ private bool TryFindAssignmentExpression( private bool TryDecomposeIfCondition( IConditionalOperation ifStatement, - out ISymbol localOrParameter) + [NotNullWhen(true)] out ISymbol? localOrParameter) { localOrParameter = null; @@ -247,7 +240,8 @@ private bool TryDecomposeIfCondition( } private bool TryGetLocalOrParameterSymbol( - IOperation operation, out ISymbol localOrParameter) + IOperation operation, + [NotNullWhen(true)] out ISymbol? localOrParameter) { if (operation is IConversionOperation conversion && conversion.IsImplicit) { @@ -274,12 +268,12 @@ private static bool IsNull(IOperation operation) operation.ConstantValue.Value == null; } - private static IConditionalOperation GetContainingIfOperation( + private static IConditionalOperation? GetContainingIfOperation( SemanticModel semanticModel, IThrowOperation throwOperation, CancellationToken cancellationToken) { var throwStatement = throwOperation.Syntax; - var containingOperation = semanticModel.GetOperation(throwStatement.Parent, cancellationToken); + var containingOperation = semanticModel.GetOperation(throwStatement.GetRequiredParent(), cancellationToken); if (containingOperation is IBlockOperation block) { @@ -292,7 +286,7 @@ private static IConditionalOperation GetContainingIfOperation( // C# may have an intermediary block between the throw-statement // and the if-statement. Walk up one operation higher in that case. - containingOperation = semanticModel.GetOperation(throwStatement.Parent.Parent, cancellationToken); + containingOperation = semanticModel.GetOperation(throwStatement.GetRequiredParent().GetRequiredParent(), cancellationToken); } if (containingOperation is IConditionalOperation conditionalOperation) diff --git a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs index a19a96a57c085..07598618f853f 100644 --- a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs +++ b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs @@ -98,7 +98,7 @@ private static async Task IsApplicableConstructorAsync(IMethodSymbol const if (constructorParams.Length == 2) { - var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); var deserializationConstructorCheck = new DeserializationConstructorCheck(compilation); if (deserializationConstructorCheck.IsDeserializationConstructor(constructor)) { diff --git a/src/Features/Core/Portable/SimplifyThisOrMe/AbstractSimplifyThisOrMeDiagnosticAnalyzer.cs b/src/Features/Core/Portable/SimplifyThisOrMe/AbstractSimplifyThisOrMeDiagnosticAnalyzer.cs index 4a10a37a66066..54d3b446aad75 100644 --- a/src/Features/Core/Portable/SimplifyThisOrMe/AbstractSimplifyThisOrMeDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/SimplifyThisOrMe/AbstractSimplifyThisOrMeDiagnosticAnalyzer.cs @@ -97,7 +97,7 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context) var severity = optionValue.Notification.Severity; var tree = model.SyntaxTree; - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(); // used so we can provide a link in the preview to the options page. This value is // hard-coded there to be the one that will go to the code-style page. diff --git a/src/Features/Core/Portable/SimplifyTypeNames/SimplifyTypeNamesDiagnosticAnalyzerBase.cs b/src/Features/Core/Portable/SimplifyTypeNames/SimplifyTypeNamesDiagnosticAnalyzerBase.cs index 9ee94966b1a4d..31c955c328795 100644 --- a/src/Features/Core/Portable/SimplifyTypeNames/SimplifyTypeNamesDiagnosticAnalyzerBase.cs +++ b/src/Features/Core/Portable/SimplifyTypeNames/SimplifyTypeNamesDiagnosticAnalyzerBase.cs @@ -176,7 +176,7 @@ internal static Diagnostic CreateDiagnostic(SemanticModel model, OptionSet optio } var tree = model.SyntaxTree; - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(); builder["OptionName"] = nameof(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInMemberAccess); // TODO: need the actual one builder["OptionLanguage"] = model.Language; var diagnostic = DiagnosticHelper.Create(descriptor, tree.GetLocation(issueSpan), severity, additionalLocations: null, builder.ToImmutable());