未验证 提交 3aae0158 编写于 作者: P Petr Houška 提交者: GitHub

Merge pull request #38322 from petrroll/UseTypeRefa

Remove withinTypeSyntax restriction for UseExplicit/ImplicitType refactoring.
......@@ -92,17 +92,28 @@ static void Main()
[Fact]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMissingSelectionNotType()
[WorkItem(35525, "https://github.com/dotnet/roslyn/issues/35525")]
public async Task TestSelectionNotType()
{
var code = @"
class C
{
static void Main()
{
int [|i|] = 0;
int [|i|] = 0;
}
}";
await TestMissingInRegularAndScriptAsync(code);
var expected = @"
class C
{
static void Main()
{
var i = 0;
}
}";
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -247,6 +258,81 @@ static void Main()
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
[WorkItem(35525, "https://github.com/dotnet/roslyn/issues/35525")]
public async Task TestIntForeachLoop2()
{
var code = @"
class C
{
static void Main()
{
foreach ([|int|] i in new[] { 0 }) { }
}
}";
var expected = @"
class C
{
static void Main()
{
foreach (var i in new[] { 0 }) { }
}
}";
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
[WorkItem(35525, "https://github.com/dotnet/roslyn/issues/35525")]
public async Task TestIntForeachLoop3()
{
var code = @"
class C
{
static void Main()
{
foreach (int [|i|] in new[] { 0 }) { }
}
}";
var expected = @"
class C
{
static void Main()
{
foreach (var i in new[] { 0 }) { }
}
}";
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
[WorkItem(35525, "https://github.com/dotnet/roslyn/issues/35525")]
public async Task TestIntForeachLoop4()
{
var code = @"
class C
{
static void Main()
{
foreach ([|object|] i in new[] { new object() }) { }
}
}";
var expected = @"
class C
{
static void Main()
{
foreach (var i in new[] { new object() }) { }
}
}";
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
public async Task TestIntDeconstruction()
{
......
......@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Utilities;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
......@@ -46,12 +47,6 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte
return;
}
// only allow the refactoring is selection/location intersects with the type node
if (!declaredType.Span.IntersectsWith(textSpan))
{
return;
}
var optionSet = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
var typeStyle = AnalyzeTypeName(declaredType, semanticModel, optionSet, cancellationToken);
if (typeStyle.IsStylePreferred && typeStyle.Severity != ReportDiagnostic.Suppress)
......@@ -82,6 +77,8 @@ private static async Task<SyntaxNode> GetDeclarationAsync(CodeRefactoringContext
// In addition to providing the refactoring when the whole node (i.e. the node that introduces the new variable) in question is selected
// we also want to enable it when only the type node is selected because this refactoring changes the type. We still have to make sure
// we're only working on TypeNodes for in above-mentioned situations.
//
// For foreach we need to guard against selecting just the expression because it is also of type `TypeSyntax`.
var declNode = await context.TryGetRelevantNodeAsync<DeclarationExpressionSyntax>().ConfigureAwait(false);
if (declNode != null)
......@@ -101,9 +98,13 @@ private static async Task<SyntaxNode> GetDeclarationAsync(CodeRefactoringContext
return foreachStatement;
}
var syntaxFacts = context.Document.GetLanguageService<ISyntaxFactsService>();
var typeNode = await context.TryGetRelevantNodeAsync<TypeSyntax>().ConfigureAwait(false);
var typeNodeParent = typeNode?.Parent;
if (typeNodeParent != null && typeNodeParent.IsKind(SyntaxKind.DeclarationExpression, SyntaxKind.VariableDeclaration, SyntaxKind.ForEachStatement))
if (typeNodeParent != null &&
(typeNodeParent.IsKind(SyntaxKind.DeclarationExpression, SyntaxKind.VariableDeclaration) ||
(typeNodeParent.IsKind(SyntaxKind.ForEachStatement) && !syntaxFacts.IsExpressionOfForeach(typeNode))))
{
return typeNodeParent;
}
......
......@@ -1520,6 +1520,9 @@ public SyntaxNode GetExpressionOfInvocationExpression(SyntaxNode node)
public SyntaxNode GetExpressionOfAwaitExpression(SyntaxNode node)
=> ((AwaitExpressionSyntax)node).Expression;
public bool IsExpressionOfForeach(SyntaxNode node)
=> node?.Parent is ForEachStatementSyntax foreachStatement && foreachStatement.Expression == node;
public bool IsPossibleTupleContext(SyntaxTree syntaxTree, int position, CancellationToken cancellationToken)
{
var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);
......
......@@ -141,6 +141,7 @@ internal interface ISyntaxFactsService : ILanguageService
bool IsAwaitExpression(SyntaxNode node);
bool IsExpressionOfAwaitExpression(SyntaxNode node);
SyntaxNode GetExpressionOfAwaitExpression(SyntaxNode node);
bool IsExpressionOfForeach(SyntaxNode node);
bool IsLogicalAndExpression(SyntaxNode node);
bool IsLogicalOrExpression(SyntaxNode node);
......
......@@ -1588,6 +1588,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return DirectCast(node, AwaitExpressionSyntax).Expression
End Function
Public Function IsExpressionOfForeach(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsExpressionOfForeach
Return node IsNot Nothing AndAlso TryCast(node.Parent, ForEachStatementSyntax)?.Expression Is node
End Function
Public Function IsPossibleTupleContext(
syntaxTree As SyntaxTree,
position As Integer,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册