diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/EquatableAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/EquatableAnalyzer.cs index 1b1446937b..a736646794 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/EquatableAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/EquatableAnalyzer.cs @@ -49,9 +49,8 @@ public override void Initialize(AnalysisContext context) private static void OnCompilationStart(CompilationStartAnalysisContext context) { - INamedTypeSymbol? objectType = context.Compilation.GetSpecialType(SpecialType.System_Object); INamedTypeSymbol? equatableType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIEquatable1); - if (objectType != null && equatableType != null) + if (equatableType != null) { context.RegisterSymbolAction(c => AnalyzeSymbol(c, equatableType), SymbolKind.NamedType); } diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/PassSystemUriObjectsInsteadOfStrings.cs b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/PassSystemUriObjectsInsteadOfStrings.cs index 6f713228b9..10eaaf3846 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/PassSystemUriObjectsInsteadOfStrings.cs +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/PassSystemUriObjectsInsteadOfStrings.cs @@ -43,15 +43,14 @@ public override void Initialize(AnalysisContext context) context.RegisterCompilationStartAction(c => { - INamedTypeSymbol? @string = c.Compilation.GetSpecialType(SpecialType.System_String); INamedTypeSymbol? uri = c.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemUri); - if (@string == null || uri == null) + if (uri == null) { // we don't have required types return; } - var analyzer = new PerCompilationAnalyzer(c.Compilation, @string, uri, GetInvocationExpression); + var analyzer = new PerCompilationAnalyzer(c.Compilation, uri, GetInvocationExpression); c.RegisterOperationAction(analyzer.Analyze, OperationKind.Invocation); }); } @@ -62,18 +61,15 @@ private sealed class PerCompilationAnalyzer { // this type will be created per compilation private readonly Compilation _compilation; - private readonly INamedTypeSymbol _string; private readonly INamedTypeSymbol _uri; private readonly Func _expressionGetter; public PerCompilationAnalyzer( Compilation compilation, - INamedTypeSymbol @string, INamedTypeSymbol uri, Func expressionGetter) { _compilation = compilation; - _string = @string; _uri = uri; _expressionGetter = expressionGetter; } @@ -105,7 +101,7 @@ public void Analyze(OperationAnalysisContext context) return; } - var stringParameters = method.Parameters.GetParametersOfType(_string); + var stringParameters = method.Parameters.GetParametersOfType(SpecialType.System_String); if (!stringParameters.Any()) { // no string parameter. not interested. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriParametersShouldNotBeStrings.cs b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriParametersShouldNotBeStrings.cs index 9dc8df4b03..ed229d6194 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriParametersShouldNotBeStrings.cs +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriParametersShouldNotBeStrings.cs @@ -41,29 +41,26 @@ public override void Initialize(AnalysisContext context) context.RegisterCompilationStartAction(c => { - var @string = c.Compilation.GetSpecialType(SpecialType.System_String); var uri = c.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemUri); var attribute = c.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemAttribute); - if (@string == null || uri == null || attribute == null) + if (uri == null || attribute == null) { // we don't have required types return; } - var analyzer = new PerCompilationAnalyzer(@string, uri, attribute); + var analyzer = new PerCompilationAnalyzer(uri, attribute); c.RegisterSymbolAction(analyzer.Analyze, SymbolKind.Method); }); } private class PerCompilationAnalyzer { - private readonly INamedTypeSymbol _string; private readonly INamedTypeSymbol _uri; private readonly INamedTypeSymbol _attribute; - public PerCompilationAnalyzer(INamedTypeSymbol @string, INamedTypeSymbol uri, INamedTypeSymbol attribute) + public PerCompilationAnalyzer(INamedTypeSymbol uri, INamedTypeSymbol attribute) { - _string = @string; _uri = uri; _attribute = attribute; } @@ -87,7 +84,7 @@ public void Analyze(SymbolAnalysisContext context) return; } - var stringParameters = method.Parameters.GetParametersOfType(_string); + var stringParameters = method.Parameters.GetParametersOfType(SpecialType.System_String); if (!stringParameters.Any()) { // no string parameter. not interested. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriPropertiesShouldNotBeStrings.cs b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriPropertiesShouldNotBeStrings.cs index 9afbb671ba..f601238cd0 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriPropertiesShouldNotBeStrings.cs +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriPropertiesShouldNotBeStrings.cs @@ -40,27 +40,24 @@ public override void Initialize(AnalysisContext context) context.RegisterCompilationStartAction(c => { - var @string = c.Compilation.GetSpecialType(SpecialType.System_String); var attribute = c.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemAttribute); - if (@string == null || attribute == null) + if (attribute == null) { // we don't have required types return; } - var analyzer = new PerCompilationAnalyzer(@string, attribute); + var analyzer = new PerCompilationAnalyzer(attribute); c.RegisterSymbolAction(analyzer.Analyze, SymbolKind.Property); }); } private class PerCompilationAnalyzer { - private readonly INamedTypeSymbol _string; private readonly INamedTypeSymbol _attribute; - public PerCompilationAnalyzer(INamedTypeSymbol @string, INamedTypeSymbol attribute) + public PerCompilationAnalyzer(INamedTypeSymbol attribute) { - _string = @string; _attribute = attribute; } @@ -83,7 +80,7 @@ public void Analyze(SymbolAnalysisContext context) return; } - if (property.Type?.Equals(_string) != true) + if (property.Type?.SpecialType != SpecialType.System_String) { // not expected type return; diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriReturnValuesShouldNotBeStrings.cs b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriReturnValuesShouldNotBeStrings.cs index 94a8a000d2..3cb08492c0 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriReturnValuesShouldNotBeStrings.cs +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/UriReturnValuesShouldNotBeStrings.cs @@ -40,27 +40,24 @@ public override void Initialize(AnalysisContext context) context.RegisterCompilationStartAction(c => { - var @string = c.Compilation.GetSpecialType(SpecialType.System_String); var uri = c.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemUri); - if (@string == null || uri == null) + if (uri == null) { // we don't have required types return; } - var analyzer = new PerCompilationAnalyzer(@string, uri); + var analyzer = new PerCompilationAnalyzer(uri); c.RegisterSymbolAction(analyzer.Analyze, SymbolKind.Method); }); } private class PerCompilationAnalyzer { - private readonly INamedTypeSymbol _string; private readonly INamedTypeSymbol _uri; - public PerCompilationAnalyzer(INamedTypeSymbol @string, INamedTypeSymbol uri) + public PerCompilationAnalyzer(INamedTypeSymbol uri) { - _string = @string; _uri = uri; } @@ -83,7 +80,7 @@ public void Analyze(SymbolAnalysisContext context) return; } - if (method.IsAccessorMethod() || method.ReturnType?.Equals(_string) != true) + if (method.IsAccessorMethod() || method.ReturnType?.SpecialType != SpecialType.System_String) { // return type must be string and it must be not an accessor method return; diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/AvoidZeroLengthArrayAllocations.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/AvoidZeroLengthArrayAllocations.Fixer.cs index 729c669fe2..d0d13398f6 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/AvoidZeroLengthArrayAllocations.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/AvoidZeroLengthArrayAllocations.Fixer.cs @@ -6,7 +6,6 @@ using System.Threading; using System.Threading.Tasks; using Analyzer.Utilities; -using Analyzer.Utilities.Extensions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Editing; @@ -51,7 +50,7 @@ private static async Task ConvertToArrayEmptyAsync(Document document, SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); SyntaxGenerator generator = editor.Generator; - INamedTypeSymbol? arrayTypeSymbol = semanticModel.Compilation.GetOrCreateTypeByMetadataName(AvoidZeroLengthArrayAllocationsAnalyzer.ArrayTypeName); + INamedTypeSymbol? arrayTypeSymbol = semanticModel.Compilation.GetSpecialType(SpecialType.System_Array); if (arrayTypeSymbol == null) { return document; diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/AvoidZeroLengthArrayAllocations.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/AvoidZeroLengthArrayAllocations.cs index f5de9ddbe6..4e15b77896 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/AvoidZeroLengthArrayAllocations.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/AvoidZeroLengthArrayAllocations.cs @@ -18,9 +18,6 @@ public abstract class AvoidZeroLengthArrayAllocationsAnalyzer : DiagnosticAnalyz { internal const string RuleId = "CA1825"; - /// The name of the array type. - internal const string ArrayTypeName = "System.Array"; // using instead of GetSpecialType to make more testable - /// The name of the Empty method on System.Array. internal const string ArrayEmptyMethodName = "Empty"; @@ -52,24 +49,24 @@ public sealed override void Initialize(AnalysisContext context) // Only if it is, register the syntax node action provided by the derived implementations. context.RegisterCompilationStartAction(ctx => { - INamedTypeSymbol? typeSymbol = ctx.Compilation.GetOrCreateTypeByMetadataName(ArrayTypeName); - if (typeSymbol != null && typeSymbol.DeclaredAccessibility == Accessibility.Public) + INamedTypeSymbol typeSymbol = ctx.Compilation.GetSpecialType(SpecialType.System_Array); + if (typeSymbol.DeclaredAccessibility == Accessibility.Public) { if (typeSymbol.GetMembers(ArrayEmptyMethodName).FirstOrDefault() is IMethodSymbol methodSymbol && methodSymbol.DeclaredAccessibility == Accessibility.Public && - methodSymbol.IsStatic && methodSymbol.Arity == 1 && methodSymbol.Parameters.IsEmpty) + methodSymbol.IsStatic && methodSymbol.Arity == 1 && methodSymbol.Parameters.IsEmpty) { - ctx.RegisterOperationAction(AnalyzeOperation, OperationKind.ArrayCreation); + ctx.RegisterOperationAction(c => AnalyzeOperation(c, methodSymbol), OperationKind.ArrayCreation); } } }); } - private void AnalyzeOperation(OperationAnalysisContext context) + private void AnalyzeOperation(OperationAnalysisContext context, IMethodSymbol arrayEmptyMethodSymbol) { - AnalyzeOperation(context, IsAttributeSyntax); + AnalyzeOperation(context, arrayEmptyMethodSymbol, IsAttributeSyntax); } - private static void AnalyzeOperation(OperationAnalysisContext context, Func isAttributeSytnax) + private static void AnalyzeOperation(OperationAnalysisContext context, IMethodSymbol arrayEmptyMethodSymbol, Func isAttributeSytnax) { IArrayCreationOperation arrayCreationExpression = (IArrayCreationOperation)context.Operation; @@ -108,14 +105,7 @@ private static void AnalyzeOperation(OperationAnalysisContext context, Func().FirstOrDefault(); diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/PreferStringContainsOverIndexOfAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/PreferStringContainsOverIndexOfAnalyzer.cs index 1c819966ec..5a544ab759 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/PreferStringContainsOverIndexOfAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/PreferStringContainsOverIndexOfAnalyzer.cs @@ -38,8 +38,8 @@ public override void Initialize(AnalysisContext context) context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.RegisterCompilationStartAction(context => { - if (!context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemString, out INamedTypeSymbol? stringType) || - !context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemChar, out INamedTypeSymbol? charType) || + if (context.Compilation.GetSpecialType(SpecialType.System_String) is not INamedTypeSymbol stringType || + context.Compilation.GetSpecialType(SpecialType.System_Char) is not INamedTypeSymbol charType || !context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemStringComparison, out INamedTypeSymbol? stringComparisonType)) { return; diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SpecifyIFormatProvider.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SpecifyIFormatProvider.cs index cfda110f65..3f24b35380 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SpecifyIFormatProvider.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SpecifyIFormatProvider.cs @@ -82,10 +82,6 @@ protected override void InitializeWorker(CompilationStartAnalysisContext context var objectType = context.Compilation.GetSpecialType(SpecialType.System_Object); var stringType = context.Compilation.GetSpecialType(SpecialType.System_String); - if (objectType == null || stringType == null) - { - return; - } var charType = context.Compilation.GetSpecialType(SpecialType.System_Char); var boolType = context.Compilation.GetSpecialType(SpecialType.System_Boolean); diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SpecifyStringComparison.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SpecifyStringComparison.cs index d9a44c68cb..3eb393cd5c 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SpecifyStringComparison.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SpecifyStringComparison.cs @@ -54,7 +54,7 @@ protected override void InitializeWorker(CompilationStartAnalysisContext context var stringType = context.Compilation.GetSpecialType(SpecialType.System_String); // Without these symbols the rule cannot run - if (stringComparisonType == null || stringType == null) + if (stringComparisonType == null) { return; } diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/TestForNaNCorrectly.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/TestForNaNCorrectly.Fixer.cs index 9dc9de9ddb..5ec70bc652 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/TestForNaNCorrectly.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/TestForNaNCorrectly.Fixer.cs @@ -37,16 +37,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) } SemanticModel model = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); - - INamedTypeSymbol? systemSingleType = model.Compilation.GetSpecialType(SpecialType.System_Single); - INamedTypeSymbol? systemDoubleType = model.Compilation.GetSpecialType(SpecialType.System_Double); - - if (systemSingleType == null || systemDoubleType == null) - { - return; - } - - FixResolution? resolution = TryGetFixResolution(binaryExpressionSyntax, model, systemSingleType, systemDoubleType, context.CancellationToken); + FixResolution? resolution = TryGetFixResolution(binaryExpressionSyntax, model, context.CancellationToken); if (resolution != null) { @@ -58,19 +49,19 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) } } - private FixResolution? TryGetFixResolution(SyntaxNode binaryExpressionSyntax, SemanticModel model, INamedTypeSymbol systemSingleType, INamedTypeSymbol systemDoubleType, CancellationToken cancellationToken) + private FixResolution? TryGetFixResolution(SyntaxNode binaryExpressionSyntax, SemanticModel model, CancellationToken cancellationToken) { bool isEqualsOperator = IsEqualsOperator(binaryExpressionSyntax); SyntaxNode leftOperand = GetLeftOperand(binaryExpressionSyntax); SyntaxNode rightOperand = GetRightOperand(binaryExpressionSyntax); - ITypeSymbol? systemTypeLeft = TryGetSystemTypeForNanConstantExpression(leftOperand, model, systemSingleType, systemDoubleType, cancellationToken); + ITypeSymbol? systemTypeLeft = TryGetSystemTypeForNanConstantExpression(leftOperand, model, cancellationToken); if (systemTypeLeft != null) { return new FixResolution(binaryExpressionSyntax, systemTypeLeft, rightOperand, isEqualsOperator); } - ITypeSymbol? systemTypeRight = TryGetSystemTypeForNanConstantExpression(rightOperand, model, systemSingleType, systemDoubleType, cancellationToken); + ITypeSymbol? systemTypeRight = TryGetSystemTypeForNanConstantExpression(rightOperand, model, cancellationToken); if (systemTypeRight != null) { return new FixResolution(binaryExpressionSyntax, systemTypeRight, leftOperand, isEqualsOperator); @@ -79,17 +70,12 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) return null; } - private static ITypeSymbol? TryGetSystemTypeForNanConstantExpression(SyntaxNode expressionSyntax, SemanticModel model, INamedTypeSymbol systemSingleType, INamedTypeSymbol systemDoubleType, CancellationToken cancellationToken) + private static ITypeSymbol? TryGetSystemTypeForNanConstantExpression(SyntaxNode expressionSyntax, SemanticModel model, CancellationToken cancellationToken) { - if (model.GetSymbolInfo(expressionSyntax, cancellationToken).Symbol is IFieldSymbol fieldSymbol) + var symbol = model.GetSymbolInfo(expressionSyntax, cancellationToken).Symbol; + if (symbol is IFieldSymbol { HasConstantValue: true, Name: "NaN", Type: { SpecialType: SpecialType.System_Single or SpecialType.System_Double } type }) { - if (fieldSymbol.Type.Equals(systemSingleType) || fieldSymbol.Type.Equals(systemDoubleType)) - { - if (fieldSymbol.HasConstantValue && fieldSymbol.Name == "NaN") - { - return fieldSymbol.Type; - } - } + return type; } return null; diff --git a/src/PerformanceSensitiveAnalyzers/CSharp/CodeFixes/AvoidAllocationWithArrayEmptyCodeFix.cs b/src/PerformanceSensitiveAnalyzers/CSharp/CodeFixes/AvoidAllocationWithArrayEmptyCodeFix.cs index 6c04c2ff8c..70377db71f 100644 --- a/src/PerformanceSensitiveAnalyzers/CSharp/CodeFixes/AvoidAllocationWithArrayEmptyCodeFix.cs +++ b/src/PerformanceSensitiveAnalyzers/CSharp/CodeFixes/AvoidAllocationWithArrayEmptyCodeFix.cs @@ -1,13 +1,10 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. -using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; using System.Linq; using System.Threading; using System.Threading.Tasks; -using Analyzer.Utilities; -using Analyzer.Utilities.Extensions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; @@ -166,19 +163,18 @@ private static async Task TransformAsync(Document contextDocument, Syn private static bool IsCopyConstructor(SemanticModel semanticModel, ObjectCreationExpressionSyntax objectCreation) => objectCreation.ArgumentList?.Arguments.Count > 0 && semanticModel.GetSymbolInfo(objectCreation).Symbol is IMethodSymbol methodSymbol && - methodSymbol.Parameters.Any(x => x.Type is INamedTypeSymbol namedType && ImplementsGenericICollectionInterface(namedType, semanticModel)); + methodSymbol.Parameters.Any(x => x.Type is INamedTypeSymbol namedType && ImplementsGenericICollectionInterface(namedType)); private static bool IsInitializationBlockEmpty(InitializerExpressionSyntax initializer) => initializer == null || initializer.Expressions.Count == 0; private static bool IsCollectionType(SemanticModel semanticModel, ObjectCreationExpressionSyntax objectCreationExpressionSyntax) => semanticModel.GetTypeInfo(objectCreationExpressionSyntax).Type is INamedTypeSymbol createdType && - (createdType.TypeKind == TypeKind.Array || ImplementsGenericICollectionInterface(createdType, semanticModel)); + (createdType.TypeKind == TypeKind.Array || ImplementsGenericICollectionInterface(createdType)); - private static bool ImplementsGenericICollectionInterface(INamedTypeSymbol typeSymbol, SemanticModel semanticModel) + private static bool ImplementsGenericICollectionInterface(INamedTypeSymbol typeSymbol) { - var genericICollectionType = semanticModel.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsGenericICollection1); - return typeSymbol.ConstructedFrom.Interfaces.Any(x => x.ConstructedFrom.Equals(genericICollectionType)); + return typeSymbol.ConstructedFrom.Interfaces.Any(x => x.ConstructedFrom.SpecialType == SpecialType.System_Collections_Generic_ICollection_T); } private static bool IsPropertyTypeReadonlySequence(SemanticModel semanticModel, PropertyDeclarationSyntax propertyDeclaration) @@ -196,7 +192,7 @@ private static bool IsExpectedParameterReadonlySequence(SyntaxNode node, Semanti methodSymbol.Parameters.Length > argumentIndex) { var parameterType = methodSymbol.Parameters[argumentIndex].Type; - if (IsTypeReadonlySequence(semanticModel, parameterType)) + if (IsTypeReadonlySequence(parameterType)) { return true; } @@ -209,10 +205,10 @@ private static bool IsExpectedParameterReadonlySequence(SyntaxNode node, Semanti private static bool IsTypeReadonlySequence(SemanticModel semanticModel, TypeSyntax typeSyntax) { var returnType = ModelExtensions.GetTypeInfo(semanticModel, typeSyntax).Type; - return IsTypeReadonlySequence(semanticModel, returnType); + return IsTypeReadonlySequence(returnType); } - private static bool IsTypeReadonlySequence(SemanticModel semanticModel, ITypeSymbol type) + private static bool IsTypeReadonlySequence(ITypeSymbol type) { if (type.Kind == SymbolKind.ArrayType) { @@ -221,15 +217,12 @@ private static bool IsTypeReadonlySequence(SemanticModel semanticModel, ITypeSym return type is INamedTypeSymbol namedType && namedType.IsGenericType && - GetReadonlySequenceTypes(semanticModel).Any(readonlySequence => namedType.ConstructedFrom.Equals(readonlySequence)); + _readonlySequenceSpecialTypes.Any(readonlySequence => namedType.ConstructedFrom.SpecialType == readonlySequence); } - private static readonly ImmutableArray _readonlySequenceTypeNames = ImmutableArray.Create( - WellKnownTypeNames.SystemCollectionsGenericIEnumerable1, - WellKnownTypeNames.SystemCollectionsGenericIReadOnlyList1, - WellKnownTypeNames.SystemCollectionsGenericIReadOnlyCollection1); - - private static IEnumerable GetReadonlySequenceTypes(SemanticModel semanticModel) - => _readonlySequenceTypeNames.Select(name => semanticModel.Compilation.GetOrCreateTypeByMetadataName(name)); + private static readonly ImmutableArray _readonlySequenceSpecialTypes = ImmutableArray.Create( + SpecialType.System_Collections_Generic_IEnumerable_T, + SpecialType.System_Collections_Generic_IReadOnlyList_T, + SpecialType.System_Collections_Generic_IReadOnlyCollection_T); } } diff --git a/src/Utilities/Compiler/Extensions/ISymbolExtensions.cs b/src/Utilities/Compiler/Extensions/ISymbolExtensions.cs index d028103bdc..b1779e5482 100644 --- a/src/Utilities/Compiler/Extensions/ISymbolExtensions.cs +++ b/src/Utilities/Compiler/Extensions/ISymbolExtensions.cs @@ -286,6 +286,14 @@ public static IEnumerable GetParametersOfType(this IEnumerable return parameters.Where(p => p.Type.Equals(type)); } + /// + /// Gets the parameters whose type is equal to the given special type. + /// + public static IEnumerable GetParametersOfType(this IEnumerable parameters, SpecialType specialType) + { + return parameters.Where(p => p.Type.SpecialType == specialType); + } + /// /// Check whether given overloads has any overload whose parameters has the given type as its parameter type. /// diff --git a/src/Utilities/Compiler/FxCopWellKnownDiagnosticTags.cs b/src/Utilities/Compiler/FxCopWellKnownDiagnosticTags.cs index 015f5dfbaa..246a92eb30 100644 --- a/src/Utilities/Compiler/FxCopWellKnownDiagnosticTags.cs +++ b/src/Utilities/Compiler/FxCopWellKnownDiagnosticTags.cs @@ -1,8 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. -using System; -using System.Diagnostics; -using System.Linq; using Microsoft.CodeAnalysis; namespace Analyzer.Utilities @@ -16,12 +13,5 @@ internal static class FxCopWellKnownDiagnosticTags public static readonly string[] PortedFxCopDataflowRule = new string[] { PortedFromFxCop, WellKnownDiagnosticTagsExtensions.Dataflow, WellKnownDiagnosticTags.Telemetry }; public static readonly string[] PortedFxCopDataflowRuleEnabledInAggressiveMode = new string[] { PortedFromFxCop, WellKnownDiagnosticTagsExtensions.Dataflow, WellKnownDiagnosticTags.Telemetry, WellKnownDiagnosticTagsExtensions.EnabledRuleInAggressiveMode }; - - public static bool IsPortedFxCopRule(DiagnosticDescriptor diagnosticDescriptor) - { - var result = diagnosticDescriptor.CustomTags.Any(t => t == PortedFromFxCop); - Debug.Assert(!result || diagnosticDescriptor.Id.StartsWith("CA", StringComparison.OrdinalIgnoreCase)); - return result; - } } } \ No newline at end of file diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs index d258115ea3..1d8ce6f835 100644 --- a/src/Utilities/Compiler/WellKnownTypeNames.cs +++ b/src/Utilities/Compiler/WellKnownTypeNames.cs @@ -54,13 +54,13 @@ internal static class WellKnownTypeNames public const string MicrosoftCodeAnalysisDiagnosticsSyntaxNodeAnalysisContext = "Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext"; public const string MicrosoftCodeAnalysisDiagnosticsSyntaxTreeAnalysisContext = "Microsoft.CodeAnalysis.Diagnostics.SyntaxTreeAnalysisContext"; public const string MicrosoftCodeAnalysisHostMefMefConstruction = "Microsoft.CodeAnalysis.Host.Mef.MefConstruction"; - public const string MicrosoftCodeAnalysisLocalizableString = "Microsoft.CodeAnalysis.LocalizableString"; public const string MicrosoftCodeAnalysisLocalizableResourceString = "Microsoft.CodeAnalysis.LocalizableResourceString"; + public const string MicrosoftCodeAnalysisLocalizableString = "Microsoft.CodeAnalysis.LocalizableString"; public const string MicrosoftCodeAnalysisSharedCollectionsTemporaryArrayExtensions = "Microsoft.CodeAnalysis.Shared.Collections.TemporaryArrayExtensions"; public const string MicrosoftCodeAnalysisSymbolKind = "Microsoft.CodeAnalysis.SymbolKind"; + public const string MicrosoftCodeAnalysisVisualBasicExtensions = "Microsoft.CodeAnalysis.VisualBasicExtensions"; public const string MicrosoftCodeAnalysisVisualBasicVisualBasicCompilation = "Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilation"; public const string MicrosoftCodeAnalysisVisualBasicVisualBasicExtensions = "Microsoft.CodeAnalysis.VisualBasic.VisualBasicExtensions"; - public const string MicrosoftCodeAnalysisVisualBasicExtensions = "Microsoft.CodeAnalysis.VisualBasicExtensions"; public const string MicrosoftEntityFrameworkCoreEntityFrameworkQueryableExtensions = "Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions"; public const string MicrosoftEntityFrameworkCoreRelationalQueryableExtensions = "Microsoft.EntityFrameworkCore.RelationalQueryableExtensions"; public const string MicrosoftExtensionsLoggingILogger = "Microsoft.Extensions.Logging.ILogger"; @@ -147,10 +147,10 @@ internal static class WellKnownTypeNames public const string SystemCollectionsImmutableImmutableList1 = "System.Collections.Immutable.ImmutableList`1"; public const string SystemCollectionsImmutableImmutableSortedDictionary2 = "System.Collections.Immutable.ImmutableSortedDictionary`2"; public const string SystemCollectionsImmutableImmutableSortedSet1 = "System.Collections.Immutable.ImmutableSortedSet`1"; - public const string SystemCollectionsSpecializedNameValueCollection = "System.Collections.Specialized.NameValueCollection"; public const string SystemCollectionsObjectModelReadOnlyCollection1 = "System.Collections.ObjectModel.ReadOnlyCollection`1"; public const string SystemCollectionsObjectModelReadOnlyDictionary2 = "System.Collections.ObjectModel.ReadOnlyDictionary`2"; public const string SystemCollectionsObjectModelReadOnlyObservableCollection1 = "System.Collections.ObjectModel.ReadOnlyObservableCollection`1"; + public const string SystemCollectionsSpecializedNameValueCollection = "System.Collections.Specialized.NameValueCollection"; public const string SystemComponentModelComponent = "System.ComponentModel.Component"; public const string SystemComponentModelCompositionExportAttribute = "System.ComponentModel.Composition.ExportAttribute"; public const string SystemComponentModelCompositionImportingConstructorAttribute = "System.ComponentModel.Composition.ImportingConstructorAttribute"; @@ -179,8 +179,8 @@ internal static class WellKnownTypeNames public const string SystemDateTime = "System.DateTime"; public const string SystemDateTimeOffset = "System.DateTimeOffset"; public const string SystemDecimal = "System.Decimal"; - public const string SystemDiagnosticsCodeAnalysisNotNullAttribute = "System.Diagnostics.CodeAnalysis.NotNullAttribute"; public const string SystemDiagnosticContractsContract = "System.Diagnostics.Contracts.Contract"; + public const string SystemDiagnosticsCodeAnalysisNotNullAttribute = "System.Diagnostics.CodeAnalysis.NotNullAttribute"; public const string SystemDiagnosticsConditionalAttribute = "System.Diagnostics.ConditionalAttribute"; public const string SystemDiagnosticsContractsPureAttribute = "System.Diagnostics.Contracts.PureAttribute"; public const string SystemDiagnosticsDebug = "System.Diagnostics.Debug"; @@ -364,10 +364,10 @@ internal static class WellKnownTypeNames public const string SystemThreadingInterlocked = "System.Threading.Interlocked"; public const string SystemThreadingMonitor = "System.Threading.Monitor"; public const string SystemThreadingSpinLock = "System.Threading.SpinLock"; - public const string SystemThreadingTasksTaskCompletionSource1 = "System.Threading.Tasks.TaskCompletionSource`1"; public const string SystemThreadingTasksTask = "System.Threading.Tasks.Task"; public const string SystemThreadingTasksTask1 = "System.Threading.Tasks.Task`1"; public const string SystemThreadingTasksTaskCompletionSource = "System.Threading.Tasks.TaskCompletionSource"; + public const string SystemThreadingTasksTaskCompletionSource1 = "System.Threading.Tasks.TaskCompletionSource`1"; public const string SystemThreadingTasksTaskContinuationOptions = "System.Threading.Tasks.TaskContinuationOptions"; public const string SystemThreadingTasksTaskCreationOptions = "System.Threading.Tasks.TaskCreationOptions"; public const string SystemThreadingTasksTaskFactory = "System.Threading.Tasks.TaskFactory";