Skip to content

Commit 6b25538

Browse files
Continued Extract method cleanup (part 2) (#76585)
2 parents ccbc092 + 3ee94ca commit 6b25538

14 files changed

+364
-432
lines changed

src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ private async Task<ImmutableArray<SyntaxNode>> CreateStatementsOrInitializerToIn
147147
statements = postProcessor.MergeDeclarationStatements(statements);
148148
statements = AddAssignmentStatementToCallSite(statements, cancellationToken);
149149
statements = await AddInvocationAtCallSiteAsync(statements, cancellationToken).ConfigureAwait(false);
150-
statements = AddReturnIfUnreachable(statements);
150+
statements = AddReturnIfUnreachable(statements, cancellationToken);
151151

152152
return statements.CastArray<SyntaxNode>();
153153
}

src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.ExpressionResult.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Threading;
56
using Microsoft.CodeAnalysis.CSharp.Extensions;
67
using Microsoft.CodeAnalysis.CSharp.LanguageService;
78
using Microsoft.CodeAnalysis.CSharp.Symbols;
@@ -45,7 +46,7 @@ public override SyntaxNode GetContainingScope()
4546
return CSharpSyntaxFacts.Instance.GetRootStandaloneExpression(scope);
4647
}
4748

48-
public override (ITypeSymbol? returnType, bool returnsByRef) GetReturnType()
49+
public override (ITypeSymbol? returnType, bool returnsByRef) GetReturnTypeInfo(CancellationToken cancellationToken)
4950
{
5051
if (GetContainingScope() is not ExpressionSyntax node)
5152
{
@@ -59,7 +60,7 @@ public override (ITypeSymbol? returnType, bool returnsByRef) GetReturnType()
5960
{
6061
var variableDeclExpression = node.GetAncestorOrThis<VariableDeclarationSyntax>();
6162
if (variableDeclExpression != null)
62-
return (model.GetTypeInfo(variableDeclExpression.Type).Type, returnsByRef: false);
63+
return (model.GetTypeInfo(variableDeclExpression.Type, cancellationToken).Type, returnsByRef: false);
6364
}
6465

6566
if (node.IsExpressionInCast())
@@ -74,7 +75,7 @@ public override (ITypeSymbol? returnType, bool returnsByRef) GetReturnType()
7475
return (regularType, returnsByRef);
7576

7677
if (node.Parent is CastExpressionSyntax castExpression)
77-
return (model.GetTypeInfo(castExpression).Type, returnsByRef: false);
78+
return (model.GetTypeInfo(castExpression, cancellationToken).Type, returnsByRef: false);
7879
}
7980

8081
return GetRegularExpressionType(model, node);

src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.StatementResult.cs

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
#nullable disable
6-
75
using System.Linq;
6+
using System.Threading;
7+
using Microsoft.CodeAnalysis.CSharp.Extensions;
88
using Microsoft.CodeAnalysis.CSharp.Syntax;
99
using Microsoft.CodeAnalysis.ExtractMethod;
1010
using Microsoft.CodeAnalysis.Shared.Extensions;
@@ -47,20 +47,16 @@ public override SyntaxNode GetContainingScope()
4747
Contract.ThrowIfNull(SemanticDocument);
4848
Contract.ThrowIfTrue(IsExtractMethodOnExpression);
4949

50-
// it contains statements
51-
var firstToken = GetFirstTokenInSelection();
52-
return firstToken.GetAncestors<SyntaxNode>().FirstOrDefault(n =>
53-
{
54-
return n is AccessorDeclarationSyntax or
55-
LocalFunctionStatementSyntax or
56-
BaseMethodDeclarationSyntax or
57-
AccessorDeclarationSyntax or
58-
AnonymousFunctionExpressionSyntax or
59-
CompilationUnitSyntax;
60-
});
50+
return GetFirstTokenInSelection().GetRequiredParent().AncestorsAndSelf().First(n =>
51+
n is AccessorDeclarationSyntax or
52+
LocalFunctionStatementSyntax or
53+
BaseMethodDeclarationSyntax or
54+
AccessorDeclarationSyntax or
55+
AnonymousFunctionExpressionSyntax or
56+
CompilationUnitSyntax);
6157
}
6258

63-
public override (ITypeSymbol returnType, bool returnsByRef) GetReturnType()
59+
public override (ITypeSymbol? returnType, bool returnsByRef) GetReturnTypeInfo(CancellationToken cancellationToken)
6460
{
6561
Contract.ThrowIfTrue(IsExtractMethodOnExpression);
6662

@@ -70,27 +66,22 @@ public override (ITypeSymbol returnType, bool returnsByRef) GetReturnType()
7066
switch (node)
7167
{
7268
case AccessorDeclarationSyntax access:
73-
// property or event case
74-
if (access.Parent == null || access.Parent.Parent == null)
75-
return default;
76-
77-
return semanticModel.GetDeclaredSymbol(access.Parent.Parent) switch
69+
return semanticModel.GetDeclaredSymbol(access.GetRequiredParent().GetRequiredParent(), cancellationToken) switch
7870
{
7971
IPropertySymbol propertySymbol => (propertySymbol.Type, propertySymbol.ReturnsByRef),
8072
IEventSymbol eventSymbol => (eventSymbol.Type, false),
81-
_ => default,
73+
_ => throw ExceptionUtilities.UnexpectedValue(node),
8274
};
8375

8476
case MethodDeclarationSyntax methodDeclaration:
8577
{
86-
return semanticModel.GetDeclaredSymbol(methodDeclaration) is not IMethodSymbol method
87-
? default
88-
: (method.ReturnType, method.ReturnsByRef);
78+
var method = semanticModel.GetRequiredDeclaredSymbol(methodDeclaration, cancellationToken);
79+
return (method.ReturnType, method.ReturnsByRef);
8980
}
9081

9182
case AnonymousFunctionExpressionSyntax function:
9283
{
93-
return semanticModel.GetSymbolInfo(function).Symbol is not IMethodSymbol method
84+
return semanticModel.GetSymbolInfo(function, cancellationToken).Symbol is not IMethodSymbol method
9485
? default
9586
: (method.ReturnType, method.ReturnsByRef);
9687
}

src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.cs

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ internal abstract partial class CSharpSelectionResult(
3232
{
3333
public static async Task<CSharpSelectionResult> CreateAsync(
3434
SemanticDocument document,
35-
SelectionInfo selectionInfo,
35+
FinalSelectionInfo selectionInfo,
3636
bool selectionChanged,
3737
CancellationToken cancellationToken)
3838
{
@@ -210,37 +210,23 @@ public override ImmutableArray<StatementSyntax> GetOuterReturnStatements(SyntaxN
210210
}
211211

212212
public override bool IsFinalSpanSemanticallyValidSpan(
213-
TextSpan textSpan, ImmutableArray<StatementSyntax> returnStatements, CancellationToken cancellationToken)
213+
ImmutableArray<StatementSyntax> returnStatements, CancellationToken cancellationToken)
214214
{
215215
// return statement shouldn't contain any return value
216216
if (returnStatements.Cast<ReturnStatementSyntax>().Any(r => r.Expression != null))
217-
{
218217
return false;
219-
}
220218

221-
var lastToken = this.SemanticDocument.Root.FindToken(textSpan.End);
222-
if (lastToken.Kind() == SyntaxKind.None)
223-
{
224-
return false;
225-
}
226-
227-
var container = lastToken.GetAncestors<SyntaxNode>().FirstOrDefault(n => n.IsReturnableConstruct());
219+
var container = returnStatements.First().AncestorsAndSelf().FirstOrDefault(n => n.IsReturnableConstruct());
228220
if (container == null)
229-
{
230221
return false;
231-
}
232222

233223
var body = container.GetBlockBody();
234224
if (body == null)
235-
{
236225
return false;
237-
}
238226

239227
// make sure that next token of the last token in the selection is the close braces of containing block
240-
if (body.CloseBraceToken != lastToken.GetNextToken(includeZeroWidth: true))
241-
{
228+
if (body.CloseBraceToken != GetLastTokenInSelection().GetNextToken(includeZeroWidth: true))
242229
return false;
243-
}
244230

245231
// alright, for these constructs, it must be okay to be extracted
246232
switch (container.Kind())
@@ -253,9 +239,7 @@ public override bool IsFinalSpanSemanticallyValidSpan(
253239

254240
// now, only method is okay to be extracted out
255241
if (body.Parent is not MethodDeclarationSyntax method)
256-
{
257242
return false;
258-
}
259243

260244
// make sure this method doesn't have return type.
261245
return method.ReturnType is PredefinedTypeSyntax p &&

0 commit comments

Comments
 (0)