提交 ba60d323 编写于 作者: C Cyrus Najmabadi

Add support for ranges.

上级 7bc67891
......@@ -47,14 +47,21 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
Diagnostic diagnostic, SyntaxEditor editor, CancellationToken cancellationToken)
{
var invocation = (InvocationExpressionSyntax)diagnostic.Location.FindNode(getInnermostNodeForTie: true, cancellationToken);
var start = (ExpressionSyntax)diagnostic.AdditionalLocations[0].FindNode(getInnermostNodeForTie: true, cancellationToken);
var end = (ExpressionSyntax)diagnostic.AdditionalLocations[1].FindNode(getInnermostNodeForTie: true, cancellationToken);
ExpressionSyntax start = null, end = null;
var startFromEnd = diagnostic.Properties.ContainsKey(CSharpUseRangeOperatorDiagnosticAnalyzer.StartFromEnd);
var endFromEnd = diagnostic.Properties.ContainsKey(CSharpUseRangeOperatorDiagnosticAnalyzer.EndFromEnd);
if (!diagnostic.Properties.ContainsKey(CSharpUseRangeOperatorDiagnosticAnalyzer.OmitStart))
{
start =(ExpressionSyntax)diagnostic.AdditionalLocations[0].FindNode(getInnermostNodeForTie: true, cancellationToken);
start = MakeIndexExpression(start,
diagnostic.Properties.ContainsKey(CSharpUseRangeOperatorDiagnosticAnalyzer.StartFromEnd));
}
start = MakeIndexExpression(start, startFromEnd);
end = MakeIndexExpression(end, endFromEnd);
if (!diagnostic.Properties.ContainsKey(CSharpUseRangeOperatorDiagnosticAnalyzer.OmitEnd))
{
end = (ExpressionSyntax)diagnostic.AdditionalLocations[1].FindNode(getInnermostNodeForTie: true, cancellationToken);
end = MakeIndexExpression(end,
diagnostic.Properties.ContainsKey(CSharpUseRangeOperatorDiagnosticAnalyzer.EndFromEnd));
}
var argList = invocation.ArgumentList;
var elementAccess = SyntaxFactory.ElementAccessExpression(
......
......@@ -15,6 +15,8 @@ internal class CSharpUseRangeOperatorDiagnosticAnalyzer : AbstractCodeStyleDiagn
{
public const string StartFromEnd = nameof(StartFromEnd);
public const string EndFromEnd = nameof(EndFromEnd);
public const string OmitStart = nameof(OmitStart);
public const string OmitEnd = nameof(OmitEnd);
public CSharpUseRangeOperatorDiagnosticAnalyzer()
: base(IDEDiagnosticIds.UseRangeOperatorDiagnosticId,
......@@ -124,16 +126,28 @@ protected override void InitializeWorker(AnalysisContext context)
// var end = range.End.FromEnd ? array.Length - range.End.Value : range.End.Value;
var properties = ImmutableDictionary<string, string>.Empty;
if (IsFromEnd(invocation.Instance, startOperation, stringLength))
if (IsFromEnd(stringLength, invocation.Instance, ref startOperation))
{
properties = properties.Add(StartFromEnd, StartFromEnd);
}
if (IsFromEnd(invocation.Instance, endOperation, stringLength))
if (IsFromEnd(stringLength, invocation.Instance, ref endOperation))
{
properties = properties.Add(EndFromEnd, EndFromEnd);
}
if (IsInstanceLengthCheck(stringLength, invocation.Instance, endOperation))
{
properties = properties.Add(OmitEnd, OmitEnd);
}
if (startOperation.ConstantValue.HasValue &&
startOperation.ConstantValue.Value is 0)
{
properties = properties.Add(OmitStart, OmitStart);
}
var additionalLocations = ImmutableArray.Create(
startOperation.Syntax.GetLocation(),
endOperation.Syntax.GetLocation());
......@@ -147,18 +161,33 @@ protected override void InitializeWorker(AnalysisContext context)
properties));
}
private bool IsFromEnd(IOperation instance, IOperation rangeOperation, IPropertySymbol stringLength)
private bool IsFromEnd(
IPropertySymbol stringLength, IOperation stringInstance, ref IOperation rangeOperation)
{
var syntaxFacts = CSharpSyntaxFactsService.Instance;
// check if its the form: `stringExpr.Length - value`
return
rangeOperation is IBinaryOperation binaryOperation &&
if (rangeOperation is IBinaryOperation binaryOperation &&
binaryOperation.OperatorKind == BinaryOperatorKind.Subtract &&
binaryOperation.LeftOperand is IPropertyReferenceOperation leftPropertyRef &&
stringLength.Equals(leftPropertyRef.Property) &&
leftPropertyRef.Instance != null &&
syntaxFacts.AreEquivalent(instance.Syntax, leftPropertyRef.Instance.Syntax);
IsInstanceLengthCheck(stringLength, stringInstance, binaryOperation.LeftOperand))
{
rangeOperation = binaryOperation.RightOperand;
return true;
}
return false;
}
/// <summary>
/// Checks if this is an expression `expr.Length` where `expr` is equivalent to
/// the instance we were calling .Substring off of.
/// </summary>
private bool IsInstanceLengthCheck(IPropertySymbol stringLength, IOperation stringInstance, IOperation operation)
{
var syntaxFacts = CSharpSyntaxFactsService.Instance;
return
operation is IPropertyReferenceOperation propertyRef &&
stringLength.Equals(propertyRef.Property) &&
propertyRef.Instance != null &&
syntaxFacts.AreEquivalent(stringInstance.Syntax, propertyRef.Instance.Syntax);
}
private static bool IsStringIndexer(IPropertySymbol property)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册