-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Additional extract method cleanup. #76611
Additional extract method cleanup. #76611
Conversation
public override bool ContainsNonReturnExitPointsStatements(ImmutableArray<SyntaxNode> jumpsOutOfRegion) | ||
=> jumpsOutOfRegion.Any(n => n is not ReturnStatementSyntax); | ||
public override bool ContainsNonReturnExitPointsStatements(ImmutableArray<SyntaxNode> exitPoints) | ||
=> exitPoints.Any(n => n is not ReturnStatementSyntax); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renaming to 'exitPoints' for consistency.
.CastArray<StatementSyntax>(); | ||
} | ||
public override ImmutableArray<StatementSyntax> GetOuterReturnStatements(SyntaxNode commonRoot, ImmutableArray<SyntaxNode> exitPoints) | ||
=> exitPoints.OfType<ReturnStatementSyntax>().ToImmutableArray().CastArray<StatementSyntax>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the prior logic was just completely unneccessary. it seems like it was written thinking that it would be passed all return-like statements in a span (for example, a return-statement inside an inner lambda), versus only the return statements out of that span. As such, it did all this complex work to filter down to only the actual return-statements returning from the span. Except that's what 'exit points' already gives you (plus things like goto/break/continue). So this can just be written to filter down to ReturnStatements and be done.
// make sure this method doesn't have return type. | ||
return method.ReturnType is PredefinedTypeSyntax p && | ||
p.Keyword.Kind() == SyntaxKind.VoidKeyword; | ||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
none of hte above logic was relevant. we already ensured that all return-statements were not returning an expression (meaning they're all of the form return;
). In which case one of two things are true:
- we're in a non-expr-returning function-like construct, which is fine.
- we're in a expr-returning function, and hte code is in error, which is also fine, we can proceed just fine, since we go into 'best effort mode' anyways and have already warned in that case.
In other words, we want to warn when the user's code was correct, but we don't know how to extract properly.
@ToddGrun @JoeRobich ptal. |
ISymbol symbol, ITypeSymbol type, VariableStyle style, bool variableDeclared) | ||
{ | ||
return CreateFromSymbolCommon(symbol, type, style); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was a virtual to allow VB to specialize behavior. but that specialization could be pulled up to the caller.
@@ -712,7 +712,7 @@ [.. variableInfos.Select(v => Argument(v.ReturnBehavior == ReturnBehavior.Initia | |||
} | |||
} | |||
|
|||
protected override async Task<GeneratedCode> CreateGeneratedCodeAsync( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this type existed to hold onto a document and SyntaxAnnotations. but the syntax annotations could be static-readonlys. so no need for this wrapper.
} | ||
|
||
// let's see whether this interface has coclass attribute | ||
return info.ConvertedType.HasAttribute(coclassSymbol); | ||
public override SyntaxNode GetOutermostCallSiteContainerToProcess(CancellationToken cancellationToken) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this wasa method in the base class that specialized itself for the expr vs statement case. but we have thse subclasses for that purpose. so i broke the method up and moved each part to the right subclass.
ParenthesizedLambdaExpressionSyntax lambda => lambda.AsyncKeyword.Kind() == SyntaxKind.AsyncKeyword, | ||
SimpleLambdaExpressionSyntax lambda => lambda.AsyncKeyword.Kind() == SyntaxKind.AsyncKeyword, | ||
AnonymousMethodExpressionSyntax anonymous => anonymous.AsyncKeyword.Kind() == SyntaxKind.AsyncKeyword, | ||
LocalFunctionStatementSyntax localFunction => localFunction.Modifiers.Any(SyntaxKind.AsyncKeyword), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added this for completeness. figuring out how to add a test for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just making sure that the lambda syntaxes were intentionally changed to always return false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lambdas are subclasses of AnonymousFunctionExpressionSyntax .
@@ -52,9 +52,6 @@ public static async Task<CSharpSelectionResult> CreateAsync( | |||
: new StatementResult(newDocument, selectionType, finalSpan); | |||
} | |||
|
|||
protected override ISyntaxFacts SyntaxFacts | |||
=> CSharpSyntaxFacts.Instance; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
never used. removed.
ISymbol symbol, | ||
ITypeSymbol type, | ||
VariableStyle style) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved from protected helper below to private local funciton here.
var visited = new HashSet<ITypeSymbol>(); | ||
var candidates = SpecializedCollections.EmptyEnumerable<ITypeParameterSymbol>(); | ||
using var _1 = PooledHashSet<ITypeSymbol>.GetInstance(out var visited); | ||
using var _2 = PooledHashSet<ITypeParameterSymbol>.GetInstance(out var candidates); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
switched to pooling, sets, and no longer concatting ienumerables.
Contract.ThrowIfTrue(IsExtractMethodOnExpression); | ||
|
||
return GetFirstTokenInSelection().GetRequiredParent().AncestorsAndSelf().First(n => | ||
n is AccessorDeclarationSyntax or | ||
LocalFunctionStatementSyntax or | ||
BaseMethodDeclarationSyntax or | ||
AccessorDeclarationSyntax or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicate in list.
internal sealed class InsertionPoint | ||
{ | ||
private readonly SyntaxAnnotation _annotation; | ||
private readonly Lazy<SyntaxNode?> _context; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unneeded type that existed to just hang onto an object and an annotation. like other places here and in previous prs, the annotation becomes static as there is only one of them ever.
@@ -36,7 +35,7 @@ protected sealed class AnalyzerResult( | |||
{ | |||
public ImmutableArray<ITypeParameterSymbol> MethodTypeParametersInDeclaration { get; } = typeParametersInDeclaration; | |||
public ImmutableArray<ITypeParameterSymbol> MethodTypeParametersInConstraintList { get; } = typeParametersInConstraintList; | |||
public ImmutableArray<VariableInfo> VariablesToUseAsReturnValue { get; } = variablesToUseAsReturnValue; | |||
public ImmutableArray<VariableInfo> VariablesToUseAsReturnValue { get; } = variables.WhereAsArray(v => v.UseAsReturnValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of making the callers do this, it is done once at this final position.
{ | ||
if (!symbolMap.TryGetValue(symbol, out var tokens)) | ||
var tokens = symbolMap[symbol]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair. but yeah, that is the semantics. it maps 'not there' to 'empty'
@@ -165,10 +166,10 @@ SyntaxNode InsertLocalFunction() | |||
|
|||
SyntaxNode InsertNormalMethod() | |||
{ | |||
var syntaxKinds = document.GetLanguageService<ISyntaxKindsService>(); | |||
var syntaxKinds = document.GetRequiredLanguageService<ISyntaxKindsService>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, i think i started removing nullability, then added back as it was too large.
@@ -29,6 +29,8 @@ internal abstract partial class MethodExtractor( | |||
ExtractMethodGenerationOptions options, | |||
bool localFunction) | |||
{ | |||
public static readonly SyntaxAnnotation InsertionPointAnnotation = new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure. can do in followup.
@@ -167,7 +165,7 @@ bool CanAddTo(Document document, SyntaxNode insertionPointNode, out OperationSta | |||
return (formattedDocument, finalInvocationNameToken == default ? null : finalInvocationNameToken); | |||
} | |||
|
|||
private static async Task<(SemanticDocument analyzedDocument, InsertionPoint insertionPoint)> GetAnnotatedDocumentAndInsertionPointAsync( | |||
private static async Task<SemanticDocument> GetAnnotatedDocumentAndInsertionPointAsync( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure. can do in followup.
|
||
public int CompareTo(ParameterVariableSymbol other) | ||
protected static int DefaultCompareTo(ISymbol left, ISymbol right) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i prefered forcing the subclasses to have to override, and decide what behavior they want :)
{ | ||
return 0; | ||
} | ||
var locationLeft = left.Locations.First(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair.
|
||
for (var i = 0; i < typeArguments.Count; i++) | ||
for (var i = 0; i < typeArguments.Length; i++) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return firstStatement.GetRequiredParent(); | ||
} | ||
|
||
if (this.IsExtractMethodOnMultipleStatements) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can do in followup. tnx!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No description provided.