diff --git a/src/NetAnalyzers/CSharp/Microsoft.CodeQuality.Analyzers/QualityGuidelines/CSharpAvoidMultipleEnumerationsAnalyzer.DataFlowOperationVisitor.cs b/src/NetAnalyzers/CSharp/Microsoft.CodeQuality.Analyzers/QualityGuidelines/CSharpAvoidMultipleEnumerationsAnalyzer.DataFlowOperationVisitor.cs deleted file mode 100644 index ae0d6617ee..0000000000 --- a/src/NetAnalyzers/CSharp/Microsoft.CodeQuality.Analyzers/QualityGuidelines/CSharpAvoidMultipleEnumerationsAnalyzer.DataFlowOperationVisitor.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. - -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeQuality.Analyzers.QualityGuidelines.AvoidMultipleEnumerations; -using Microsoft.CodeQuality.Analyzers.QualityGuidelines.AvoidMultipleEnumerations.FlowAnalysis; - -namespace Microsoft.CodeAnalysis.CSharp.NetAnalyzers.Microsoft.CodeQuality.Analyzers.QualityGuidelines -{ - internal partial class CSharpAvoidMultipleEnumerationsAnalyzer - { - private sealed class CSharpInvocationCountValueSetFlowStateDictionaryFlowOperationVisitor : AvoidMultipleEnumerationsFlowStateDictionaryFlowOperationVisitor - { - public CSharpInvocationCountValueSetFlowStateDictionaryFlowOperationVisitor( - GlobalFlowStateDictionaryAnalysisContext context, - WellKnownSymbolsInfo wellKnownSymbolsInfo) : base( - context, - wellKnownSymbolsInfo) - { - } - - protected override bool IsExpressionOfForEachStatement(SyntaxNode node) - => node.Parent is ForEachStatementSyntax forEachStatementSyntax && forEachStatementSyntax.Expression.Equals(node); - } - } -} \ No newline at end of file diff --git a/src/NetAnalyzers/CSharp/Microsoft.CodeQuality.Analyzers/QualityGuidelines/CSharpAvoidMultipleEnumerationsAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.CodeQuality.Analyzers/QualityGuidelines/CSharpAvoidMultipleEnumerationsAnalyzer.cs index e15803139a..74096b5ba7 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.CodeQuality.Analyzers/QualityGuidelines/CSharpAvoidMultipleEnumerationsAnalyzer.cs +++ b/src/NetAnalyzers/CSharp/Microsoft.CodeQuality.Analyzers/QualityGuidelines/CSharpAvoidMultipleEnumerationsAnalyzer.cs @@ -1,19 +1,15 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeQuality.Analyzers.QualityGuidelines.AvoidMultipleEnumerations; -using Microsoft.CodeQuality.Analyzers.QualityGuidelines.AvoidMultipleEnumerations.FlowAnalysis; namespace Microsoft.CodeAnalysis.CSharp.NetAnalyzers.Microsoft.CodeQuality.Analyzers.QualityGuidelines { [DiagnosticAnalyzer(LanguageNames.CSharp)] internal sealed partial class CSharpAvoidMultipleEnumerationsAnalyzer : AvoidMultipleEnumerations { - protected override GlobalFlowStateDictionaryFlowOperationVisitor CreateOperationVisitor( - GlobalFlowStateDictionaryAnalysisContext context, - WellKnownSymbolsInfo wellKnownSymbolsInfo) - => new CSharpInvocationCountValueSetFlowStateDictionaryFlowOperationVisitor( - context, - wellKnownSymbolsInfo); + protected override bool IsExpressionOfForEachStatement(SyntaxNode node) + => node.Parent is ForEachStatementSyntax forEachStatementSyntax && forEachStatementSyntax.Expression.Equals(node); } } \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/QualityGuidelines/AvoidMultipleEnumerations/AvoidMultipleEnumerations.DataFlowOperationVisitor.cs b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/QualityGuidelines/AvoidMultipleEnumerations/AvoidMultipleEnumerations.DataFlowOperationVisitor.cs index 1ddf5fd8b3..7bd4e1a330 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/QualityGuidelines/AvoidMultipleEnumerations/AvoidMultipleEnumerations.DataFlowOperationVisitor.cs +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/QualityGuidelines/AvoidMultipleEnumerations/AvoidMultipleEnumerations.DataFlowOperationVisitor.cs @@ -15,19 +15,20 @@ namespace Microsoft.CodeQuality.Analyzers.QualityGuidelines.AvoidMultipleEnumera { internal partial class AvoidMultipleEnumerations { - internal abstract class AvoidMultipleEnumerationsFlowStateDictionaryFlowOperationVisitor : GlobalFlowStateDictionaryFlowOperationVisitor + internal sealed class AvoidMultipleEnumerationsFlowStateDictionaryFlowOperationVisitor : GlobalFlowStateDictionaryFlowOperationVisitor { + private readonly AvoidMultipleEnumerations _analyzer; private readonly WellKnownSymbolsInfo _wellKnownSymbolsInfo; - protected AvoidMultipleEnumerationsFlowStateDictionaryFlowOperationVisitor( + internal AvoidMultipleEnumerationsFlowStateDictionaryFlowOperationVisitor( + AvoidMultipleEnumerations analyzer, GlobalFlowStateDictionaryAnalysisContext analysisContext, WellKnownSymbolsInfo wellKnownSymbolsInfo) : base(analysisContext) { + _analyzer = analyzer; _wellKnownSymbolsInfo = wellKnownSymbolsInfo; } - protected abstract bool IsExpressionOfForEachStatement(SyntaxNode node); - public override GlobalFlowStateDictionaryAnalysisValue VisitParameterReference(IParameterReferenceOperation operation, object? argument) { var value = base.VisitParameterReference(operation, argument); @@ -361,7 +362,7 @@ private bool IsGetEnumeratorOfForEachLoopInvoked(IOperation operation) // because the Operation in CFG doesn't have that information. (CFG will convert the for each operation to control flow blocks) return operation.Parent is IInvocationOperation invocationOperation && _wellKnownSymbolsInfo.GetEnumeratorMethods.Contains(invocationOperation.TargetMethod.OriginalDefinition) - && IsExpressionOfForEachStatement(invocationOperation.Syntax); + && _analyzer.IsExpressionOfForEachStatement(invocationOperation.Syntax); } } } diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/QualityGuidelines/AvoidMultipleEnumerations/AvoidMultipleEnumerations.cs b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/QualityGuidelines/AvoidMultipleEnumerations/AvoidMultipleEnumerations.cs index 8249d79550..63efe8133b 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/QualityGuidelines/AvoidMultipleEnumerations/AvoidMultipleEnumerations.cs +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/QualityGuidelines/AvoidMultipleEnumerations/AvoidMultipleEnumerations.cs @@ -150,9 +150,7 @@ internal abstract partial class AvoidMultipleEnumerations : DiagnosticAnalyzer // Only available on .net6 or later "TryGetNonEnumeratedCount"); - protected abstract GlobalFlowStateDictionaryFlowOperationVisitor CreateOperationVisitor( - GlobalFlowStateDictionaryAnalysisContext context, - WellKnownSymbolsInfo wellKnownSymbolsInfo); + protected abstract bool IsExpressionOfForEachStatement(SyntaxNode syntax); public override void Initialize(AnalysisContext context) { @@ -300,7 +298,8 @@ private void Analyze( var analysisResult = GlobalFlowStateDictionaryAnalysis.TryGetOrComputeResult( cfg, context.OwningSymbol, - analysisContext => CreateOperationVisitor( + analysisContext => new AvoidMultipleEnumerationsFlowStateDictionaryFlowOperationVisitor( + this, analysisContext, wellKnownSymbolsInfo), wellKnownTypeProvider, diff --git a/src/NetAnalyzers/VisualBasic/Microsoft.CodeQuality.Analyzers/QualityGuidelines/BasicAvoidMultipleEnumerationsAnalyzer.DataFlowOperationVisitor.vb b/src/NetAnalyzers/VisualBasic/Microsoft.CodeQuality.Analyzers/QualityGuidelines/BasicAvoidMultipleEnumerationsAnalyzer.DataFlowOperationVisitor.vb deleted file mode 100644 index 329269c3fb..0000000000 --- a/src/NetAnalyzers/VisualBasic/Microsoft.CodeQuality.Analyzers/QualityGuidelines/BasicAvoidMultipleEnumerationsAnalyzer.DataFlowOperationVisitor.vb +++ /dev/null @@ -1,24 +0,0 @@ -' Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. - -Imports Microsoft.CodeAnalysis -Imports Microsoft.CodeAnalysis.VisualBasic.Syntax -Imports Microsoft.CodeQuality.Analyzers.QualityGuidelines.AvoidMultipleEnumerations -Imports Microsoft.CodeQuality.Analyzers.QualityGuidelines.AvoidMultipleEnumerations.FlowAnalysis - -Namespace Microsoft.CodeQuality.VisualBasic.Analyzers.QualityGuidelines - Partial Friend NotInheritable Class BasicAvoidMultipleEnumerationsAnalyzer - Private Class BasicInvocationCountDataFlowOperationVisitor - Inherits AvoidMultipleEnumerationsFlowStateDictionaryFlowOperationVisitor - - Public Sub New(analysisContext As GlobalFlowStateDictionaryAnalysisContext, - wellKnownSymbolsInfo As WellKnownSymbolsInfo) - MyBase.New(analysisContext, wellKnownSymbolsInfo) - End Sub - - Protected Overrides Function IsExpressionOfForEachStatement(node As SyntaxNode) As Boolean - Dim parent = TryCast(node.Parent, ForEachStatementSyntax) - Return parent IsNot Nothing AndAlso parent.Expression.Equals(node) - End Function - End Class - End Class -End Namespace \ No newline at end of file diff --git a/src/NetAnalyzers/VisualBasic/Microsoft.CodeQuality.Analyzers/QualityGuidelines/BasicAvoidMultipleEnumerationsAnalyzer.vb b/src/NetAnalyzers/VisualBasic/Microsoft.CodeQuality.Analyzers/QualityGuidelines/BasicAvoidMultipleEnumerationsAnalyzer.vb index 32e0569ec5..22bf9c29d1 100644 --- a/src/NetAnalyzers/VisualBasic/Microsoft.CodeQuality.Analyzers/QualityGuidelines/BasicAvoidMultipleEnumerationsAnalyzer.vb +++ b/src/NetAnalyzers/VisualBasic/Microsoft.CodeQuality.Analyzers/QualityGuidelines/BasicAvoidMultipleEnumerationsAnalyzer.vb @@ -2,8 +2,8 @@ Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Diagnostics +Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.CodeQuality.Analyzers.QualityGuidelines.AvoidMultipleEnumerations -Imports Microsoft.CodeQuality.Analyzers.QualityGuidelines.AvoidMultipleEnumerations.FlowAnalysis Namespace Microsoft.CodeQuality.VisualBasic.Analyzers.QualityGuidelines @@ -11,8 +11,9 @@ Namespace Microsoft.CodeQuality.VisualBasic.Analyzers.QualityGuidelines Partial Friend NotInheritable Class BasicAvoidMultipleEnumerationsAnalyzer Inherits AvoidMultipleEnumerations - Protected Overrides Function CreateOperationVisitor(context As GlobalFlowStateDictionaryAnalysisContext, wellKnownSymbolsInfo As WellKnownSymbolsInfo) As GlobalFlowStateDictionaryFlowOperationVisitor - Return New BasicInvocationCountDataFlowOperationVisitor(context, wellKnownSymbolsInfo) + Protected Overrides Function IsExpressionOfForEachStatement(node As SyntaxNode) As Boolean + Dim parent = TryCast(node.Parent, ForEachStatementSyntax) + Return parent IsNot Nothing AndAlso parent.Expression.Equals(node) End Function End Class End Namespace \ No newline at end of file