提交 0408978b 编写于 作者: C CyrusNajmabadi

Don't off ?. if it's going to be used in an Expression-Tree.

上级 5961e610
......@@ -338,5 +338,27 @@ void Foo()
}
class C { public void M(string s) { } }");
}
[WorkItem(17623, "https://github.com/dotnet/roslyn/issues/17623")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseNullPropagation)]
public async Task TestInExpressionTree()
{
await TestMissingInRegularAndScriptAsync(
@"
using System;
using System.Linq.Expressions;
class Program
{
void Main(string s)
{
Method<string>(t => [||]s != null ? s.ToString() : null); // works
}
public void Method<T>(Expression<Func<T, string>> functor)
{
}
}");
}
}
}
\ No newline at end of file
......@@ -37,15 +37,25 @@ protected AbstractUseNullPropagationDiagnosticAnalyzer()
public override DiagnosticAnalyzerCategory GetAnalyzerCategory() => DiagnosticAnalyzerCategory.SemanticDocumentAnalysis;
protected abstract TSyntaxKind GetSyntaxKindToAnalyze();
protected abstract ISyntaxFactsService GetSyntaxFactsService();
protected abstract bool IsEquals(TBinaryExpressionSyntax condition);
protected abstract bool IsNotEquals(TBinaryExpressionSyntax condition);
protected abstract bool ShouldAnalyze(ParseOptions options);
protected abstract ISyntaxFactsService GetSyntaxFactsService();
protected abstract ISemanticFactsService GetSemanticFactsService();
protected override void InitializeWorker(AnalysisContext context)
=> context.RegisterSyntaxNodeAction(AnalyzeSyntax, GetSyntaxKindToAnalyze());
{
context.RegisterCompilationStartAction(startContext =>
{
var expressionTypeOpt = startContext.Compilation.GetTypeByMetadataName("System.Linq.Expressions.Expression`1");
startContext.RegisterSyntaxNodeAction(
c => AnalyzeSyntax(c, expressionTypeOpt), GetSyntaxKindToAnalyze());
});
private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
}
private void AnalyzeSyntax(SyntaxNodeAnalysisContext context, INamedTypeSymbol expressionTypeOpt)
{
var conditionalExpression = (TConditionalExpressionSyntax)context.Node;
if (!ShouldAnalyze(conditionalExpression.SyntaxTree.Options))
......@@ -102,7 +112,7 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
return;
}
// Needs to be of the forme:
// Needs to be of the form:
// x == null ? null : ... or
// x != null ? ... : null;
if (isEquals && !syntaxFacts.IsNullLiteralExpression(whenTrueNode))
......@@ -124,6 +134,14 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
return;
}
// ?. is not available in expression-trees. Disallow the fix in that case.
var semanticFacts = GetSemanticFactsService();
var semanticModel = context.SemanticModel;
if (semanticFacts.IsInExpressionTree(semanticModel, conditionNode, expressionTypeOpt, cancellationToken))
{
return;
}
var locations = ImmutableArray.Create(
conditionalExpression.GetLocation(),
conditionPartToCheck.GetLocation(),
......@@ -162,26 +180,22 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
private static SyntaxNode Unwrap(ISyntaxFactsService syntaxFacts, SyntaxNode node)
{
var invocation = node as TInvocationExpression;
if (invocation != null)
if (node is TInvocationExpression invocation)
{
return syntaxFacts.GetExpressionOfInvocationExpression(invocation);
}
var memberAccess = node as TMemberAccessExpression;
if (memberAccess != null)
if (node is TMemberAccessExpression memberAccess)
{
return syntaxFacts.GetExpressionOfMemberAccessExpression(memberAccess);
}
var conditionalAccess = node as TConditionalAccessExpression;
if (conditionalAccess != null)
if (node is TConditionalAccessExpression conditionalAccess)
{
return syntaxFacts.GetExpressionOfConditionalAccessExpression(conditionalAccess);
}
var elementAccess = node as TElementAccessExpression;
if (elementAccess != null)
if (node is TElementAccessExpression elementAccess)
{
return syntaxFacts.GetExpressionOfElementAccessExpression(elementAccess);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册