Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UseIndexOrRangeOperator
/// </summary>
[DiagnosticAnalyzer(LanguageNames.CSharp)]
[SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "Required to avoid ambiguous reference warnings.")]
internal partial class CSharpUseIndexOperatorDiagnosticAnalyzer : AbstractBuiltInCodeStyleDiagnosticAnalyzer
internal sealed partial class CSharpUseIndexOperatorDiagnosticAnalyzer : AbstractBuiltInCodeStyleDiagnosticAnalyzer
{
public CSharpUseIndexOperatorDiagnosticAnalyzer()
: base(IDEDiagnosticIds.UseIndexOperatorDiagnosticId,
Expand All @@ -56,12 +56,17 @@ public CSharpUseIndexOperatorDiagnosticAnalyzer()

protected override void InitializeWorker(AnalysisContext context)
{
context.RegisterCompilationStartAction(startContext =>
context.RegisterCompilationStartAction(context =>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Below callbacks were originally registered using the AnalysisContext rather than the CompilationStartAnalysisContext

I'm not sure if this makes any different, but we should be using the most-nested context anyway, so shadowing is very intended.

{
var compilation = (CSharpCompilation)context.Compilation;

// Only supported on C# 8 and above.
if (compilation.LanguageVersion < LanguageVersion.CSharp8)
return;

// We're going to be checking every property-reference and invocation in the
// compilation. Cache information we compute in this object so we don't have to
// continually recompute it.
var compilation = startContext.Compilation;
if (!InfoCache.TryCreate(compilation, out var infoCache))
return;

Expand Down Expand Up @@ -171,14 +176,8 @@ private void AnalyzeInvokedMember(
if (subtraction.Syntax is not BinaryExpressionSyntax binaryExpression)
return;

// Only supported on C# 8 and above.
var syntaxTree = binaryExpression.SyntaxTree;
var parseOptions = (CSharpParseOptions)syntaxTree.Options;
if (parseOptions.LanguageVersion < LanguageVersion.CSharp8)
return;

// Don't bother analyzing if the user doesn't like using Index/Range operators.
var option = context.Options.GetOption(CSharpCodeStyleOptions.PreferIndexOperator, syntaxTree, cancellationToken);
var option = context.Options.GetOption(CSharpCodeStyleOptions.PreferIndexOperator, binaryExpression.SyntaxTree, cancellationToken);
if (!option.Value)
return;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UseIndexOrRangeOperator
/// </summary>
[DiagnosticAnalyzer(LanguageNames.CSharp)]
[SuppressMessage("Documentation", "CA1200:Avoid using cref tags with a prefix", Justification = "Required to avoid ambiguous reference warnings.")]
internal partial class CSharpUseRangeOperatorDiagnosticAnalyzer : AbstractBuiltInCodeStyleDiagnosticAnalyzer
internal sealed partial class CSharpUseRangeOperatorDiagnosticAnalyzer : AbstractBuiltInCodeStyleDiagnosticAnalyzer
{
// public const string UseIndexer = nameof(UseIndexer);
public const string ComputedRange = nameof(ComputedRange);
Expand All @@ -55,14 +55,20 @@ public CSharpUseRangeOperatorDiagnosticAnalyzer()

protected override void InitializeWorker(AnalysisContext context)
{
context.RegisterCompilationStartAction(compilationContext =>
context.RegisterCompilationStartAction(context =>
{
var compilation = (CSharpCompilation)context.Compilation;

// Check if we're at least on C# 8
if (compilation.LanguageVersion < LanguageVersion.CSharp8)
return;

// We're going to be checking every invocation in the compilation. Cache information
// we compute in this object so we don't have to continually recompute it.
if (!InfoCache.TryCreate(compilationContext.Compilation, out var infoCache))
if (!InfoCache.TryCreate(context.Compilation, out var infoCache))
return;

compilationContext.RegisterOperationAction(
context.RegisterOperationAction(
c => AnalyzeInvocation(c, infoCache),
OperationKind.Invocation);
});
Expand All @@ -74,6 +80,8 @@ private void AnalyzeInvocation(
var operation = context.Operation;
var syntaxTree = operation.SemanticModel!.SyntaxTree;
var cancellationToken = context.CancellationToken;

// Check if the user wants these operators.
var option = context.Options.GetOption(CSharpCodeStyleOptions.PreferRangeOperator, syntaxTree, cancellationToken);
if (!option.Value)
return;
Expand All @@ -98,12 +106,6 @@ private void AnalyzeInvocation(
return null;
}

// Check if we're at least on C# 8, and that the user wants these operators.
var syntaxTree = invocationSyntax.SyntaxTree;
var parseOptions = (CSharpParseOptions)syntaxTree.Options;
if (parseOptions.LanguageVersion < LanguageVersion.CSharp8)
return null;

// look for `s.Slice(e1, end - e2)` or `s.Slice(e1)`
if (invocation.Instance is null)
return null;
Expand Down