未验证 提交 f4ace052 编写于 作者: D David 提交者: GitHub

Merge pull request #45401 from...

Merge pull request #45401 from dotnet/merges/release/dev16.8-preview1-to-release/dev16.8-preview1-vs-deps

Merge release/dev16.8-preview1 to release/dev16.8-preview1-vs-deps
......@@ -38,6 +38,8 @@ protected override void InitializeWorker(AnalysisContext context)
private void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
var expression = (ExpressionSyntax)context.Node;
if (expression.GetDiagnostics().Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error))
return;
// Bail if this is not a topmost expression
// to avoid overlapping diagnostics.
......@@ -45,16 +47,20 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context)
return;
var syntaxTree = expression.SyntaxTree;
var cancellationToken = context.CancellationToken;
if (!((CSharpParseOptions)syntaxTree.Options).LanguageVersion.IsCSharp9OrAbove())
return;
var cancellationToken = context.CancellationToken;
var styleOption = context.Options.GetOption(CSharpCodeStyleOptions.PreferPatternMatching, syntaxTree, cancellationToken);
if (!styleOption.Value)
return;
var operation = context.SemanticModel.GetOperation(expression, cancellationToken);
var semanticModel = context.SemanticModel;
var expressionTypeOpt = semanticModel.Compilation.GetTypeByMetadataName("System.Linq.Expressions.Expression`1");
if (expression.IsInExpressionTree(semanticModel, expressionTypeOpt, cancellationToken))
return;
var operation = semanticModel.GetOperation(expression, cancellationToken);
if (operation is null)
return;
......
......@@ -30,7 +30,10 @@ internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProvider
=> (new CSharpUsePatternCombinatorsDiagnosticAnalyzer(), new CSharpUsePatternCombinatorsCodeFixProvider());
private Task TestAllMissingOnExpressionAsync(string expression, ParseOptions parseOptions = null, bool enabled = true)
=> TestMissingAsync(FromExpression(expression), new TestParameters(
=> TestMissingAsync(FromExpression(expression), parseOptions, enabled);
private Task TestMissingAsync(string initialMarkup, ParseOptions parseOptions = null, bool enabled = true)
=> TestMissingAsync(initialMarkup, new TestParameters(
parseOptions: parseOptions ?? CSharp9, options: enabled ? null : s_disabled));
private Task TestAllAsync(string initialMarkup, string expectedMarkup)
......@@ -47,29 +50,32 @@ private static string FromExpression(string expression)
using System.Collections.Generic;
class C
{
bool field = {|FixAllInDocument:EXPRESSION|};
bool Method() => EXPRESSION;
bool Prop1 => EXPRESSION;
bool Prop2 { get } = EXPRESSION;
void If() { if (EXPRESSION) ; }
void Argument1() => Test(EXPRESSION);
void Argument2() => Test(() => EXPRESSION);
void Argument3() => Test(_ => EXPRESSION);
void For() { for (; EXPRESSION; ); }
void Local() { var local = EXPRESSION; }
void Conditional() { _ = EXPRESSION ? EXPRESSION : EXPRESSION; }
void Assignment() { _ = EXPRESSION; }
void Do() { do ; while (EXPRESSION); }
void While() { while (EXPRESSION) ; }
bool When() => o switch { _ when EXPRESSION => EXPRESSION };
bool Return() { return EXPRESSION; }
IEnumerable<bool> YieldReturn() { yield return EXPRESSION; }
Func<object, bool> SimpleLambda() => o => EXPRESSION;
Func<bool> ParenthesizedLambda() => () => EXPRESSION;
void LocalFunc() { bool LocalFunction() => EXPRESSION; }
int i;
int? nullable;
object o;
static bool field = {|FixAllInDocument:EXPRESSION|};
static bool Method() => EXPRESSION;
static bool Prop1 => EXPRESSION;
static bool Prop2 { get; } = EXPRESSION;
static void If() { if (EXPRESSION) ; }
static void Argument1() => Test(EXPRESSION);
static void Argument2() => Test(() => EXPRESSION);
static void Argument3() => Test(_ => EXPRESSION);
static void Test(bool b) {}
static void Test(Func<bool> b) {}
static void Test(Func<object, bool> b) {}
static void For() { for (; EXPRESSION; ); }
static void Local() { var local = EXPRESSION; }
static void Conditional() { _ = EXPRESSION ? EXPRESSION : EXPRESSION; }
static void Assignment() { _ = EXPRESSION; }
static void Do() { do ; while (EXPRESSION); }
static void While() { while (EXPRESSION) ; }
static bool When() => o switch { _ when EXPRESSION => EXPRESSION };
static bool Return() { return EXPRESSION; }
static IEnumerable<bool> YieldReturn() { yield return EXPRESSION; }
static Func<object, bool> SimpleLambda() => o => EXPRESSION;
static Func<bool> ParenthesizedLambda() => () => EXPRESSION;
static void LocalFunc() { bool LocalFunction() => EXPRESSION; }
static int i;
static int? nullable;
static object o;
}
";
return initialMarkup.Replace("EXPRESSION", expression);
......@@ -88,6 +94,7 @@ public async Task TestMissingOnExpression(string expression)
await TestAllMissingOnExpressionAsync(expression);
}
[InlineData("i == default || i > default(int)", "i is default(int) or > (default(int))")]
[InlineData("!(o is C c)", "o is not C c")]
[InlineData("o is int ii && o is long jj", "o is int ii and long jj")]
[InlineData("!(o is C)", "o is not C")]
......@@ -217,6 +224,20 @@ bool M1(int v)
{
return v is 0 or 1 or 2;
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUsePatternCombinators)]
public async Task TestMissingInExpressionTree()
{
await TestMissingAsync(
@"using System.Linq;
class C
{
void M0(IQueryable<int> q)
{
q.Where(item => item == 1 [||]|| item == 2);
}
}");
}
}
......
......@@ -89,7 +89,7 @@ private static PatternSyntax AsPatternSyntax(AnalyzedPattern pattern)
Token(p.Token.LeadingTrivia, p.IsDisjunctive ? SyntaxKind.OrKeyword : SyntaxKind.AndKeyword,
TriviaList(p.Token.GetAllTrailingTrivia())),
AsPatternSyntax(p.Right).Parenthesize()),
Constant p => ConstantPattern(p.ExpressionSyntax.Parenthesize()),
Constant p => ConstantPattern(AsExpressionSyntax(p)),
Source p => p.PatternSyntax,
Type p => TypePattern(p.TypeSyntax),
Relational p => RelationalPattern(Token(MapToSyntaxKind(p.OperatorKind)), p.Value.Parenthesize()),
......@@ -98,6 +98,22 @@ private static PatternSyntax AsPatternSyntax(AnalyzedPattern pattern)
};
}
private static ExpressionSyntax AsExpressionSyntax(Constant constant)
{
var expr = constant.ExpressionSyntax;
if (expr.IsKind(SyntaxKind.DefaultLiteralExpression))
{
// default literals are not permitted in patterns
var convertedType = constant.Target.SemanticModel.GetTypeInfo(expr).ConvertedType;
if (convertedType != null)
{
return DefaultExpression(convertedType.GenerateTypeSyntax());
}
}
return expr.Parenthesize();
}
private class MyCodeAction : CodeAction.DocumentChangeAction
{
public MyCodeAction(Func<CancellationToken, Task<Document>> createChangedDocument)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册