-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Extract Method Bug With Method Directly in Namespace #53031
Conversation
src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.vb
Outdated
Show resolved
Hide resolved
src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.vb
Outdated
Show resolved
Hide resolved
src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionValidator.cs
Outdated
Show resolved
Hide resolved
Bonjour! |
src/EditorFeatures/CSharpTest/CodeActions/ExtractMethod/ExtractMethodTests.cs
Show resolved
Hide resolved
{ | ||
return new SelectionInfo | ||
{ | ||
Status = new OperationStatus(OperationStatusFlag.None, CSharpFeaturesResources.No_valid_selection_to_perform_extraction), |
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 think we might want to condier a better string message here. SPecifically "Selection was not contained inside a type"
also, do we ahve tests for extracing from local functions inside the root namespace? we don't want to break that (if that works today. ) if it doesn't work prior to your change, tehn no worries.
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.
"Selection was not contained inside a type"
This may not be a problem for top level statements right?
"Also, do we ahve tests for extracing from local functions inside the root namespace?"
Is that valid?
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.
yup. top level functions are a thing :)
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.
top level functions seem to have been added in C# 9? How can I test if it works?
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 are no tests for extracting from the root namespace, and I tested it and it has the same error as the bug linked.
src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.vb
Outdated
Show resolved
Hide resolved
I should take a look at this soon |
/*var rootGlobalStatement = commonRoot.FirstAncestorOrSelf<SyntaxNode>(node => node is GlobalStatementSyntax); | ||
var commonRootContainer = commonRoot.FirstAncestorOrSelf<SyntaxNode>(node => node is TypeDeclarationSyntax); | ||
|
||
if (commonRootContainer is null && rootGlobalStatement is null) | ||
{ | ||
return new SelectionInfo | ||
{ | ||
Status = new OperationStatus(OperationStatusFlag.None, FeaturesResources.Selection_not_contained_inside_a_type), | ||
OriginalSpan = adjustedSpan, | ||
FirstTokenInOriginalSpan = firstTokenInSelection, | ||
LastTokenInOriginalSpan = lastTokenInSelection | ||
}; | ||
}*/ |
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.
Remove this
n is AccessorDeclarationSyntax || | ||
n is BlockSyntax || | ||
n is GlobalStatementSyntax) | ||
if (n is BaseMethodDeclarationSyntax or AccessorDeclarationSyntax or BlockSyntax or GlobalStatementSyntax) |
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.
if (n is BaseMethodDeclarationSyntax or AccessorDeclarationSyntax or BlockSyntax or GlobalStatementSyntax) | |
if (n is BaseMethodDeclarationSyntax or | |
AccessorDeclarationSyntax or | |
BlockSyntax or | |
GlobalStatementSyntax) |
@@ -9188,13 +9188,13 @@ private static K NewMethod() | |||
public async Task Script_ArgumentException() | |||
{ | |||
var code = @"using System; | |||
public static void GetNonVirtualMethod<TDelegate>( Type type, string name) | |||
static void GetNonVirtualMethod<TDelegate>( Type type, string name) |
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.
please don't update test cases. instead still record the change in behavior for this case, and add a new test for the differnet case you carea bout.
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.
to be honest, I do not know why I even touched this method
if (node.FromScript() || node.GetAncestor<TypeDeclarationSyntax>() != null) | ||
{ | ||
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.
these checks need comments.
{ | ||
Contract.ThrowIfNull(node); | ||
|
||
if (IsContainedDirectlyInNamespace(node)) |
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.
if (IsContainedDirectlyInNamespace(node)) | |
return !IsContainedDirectlyInNamespace(node); |
immediateParent = true; | ||
} | ||
|
||
n = n.Parent!; |
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 do not know what is going on here. in english what are you trying to express :)
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.
if I am a method, or a block, etc. and my immediate parent is a namespace, then bail and do not allow that as a valid selection. Still need to make sure I am handling everything that shouldn't be directly in a namespace
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.
would it suffice to just ask: did i hit a namespace, but i did not hit a type? that seems simpler. or, put another way:
first look if we're contained by a type. if so, great.
then look to see if we're contained by a namespace. if so, bad.
otherwise, we must be global. if so, great.
@@ -332,21 +332,6 @@ | |||
<target state="translated">選取範圍無效</target> | |||
<note /> | |||
</trans-unit> | |||
<trans-unit id="Selection_doesn_t_contain_any_valid_token"> |
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 you make the loc change in a separate PR?
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.
public static bool ContainedInValidType(this SyntaxNode node) | ||
{ | ||
Contract.ThrowIfNull(node); | ||
var typeContainer = node.FirstAncestorOrSelf<TypeDeclarationSyntax>(); |
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.
var typeContainer = node.FirstAncestorOrSelf<TypeDeclarationSyntax>(); | |
foreach (var ancestor in node.AncestorsAndSelf()) | |
{ | |
if (ancestor is TypeDeclarationSyntax) | |
return true; | |
if (ancestor is NamespaceDeclarationSyntax) | |
return false; | |
} | |
return true; |
Current changes look good, pending test passing and conflict resolution |
…/roslyn into bug/44214_extractmethod
#44214
Hello!
I worked on a bug in which, if you paste a method directly into a namespace and highlight an expression in the method, ExtractMethod crashes. To fix this, I look at the
GetValidSelectionAsync
methods in C# and VB. This callsGetInitialSelectionInfo()
which returns valid or invalid selections. I added a check to see if the highlighted expression is contained within some block that methods could be contained in, Classes, Records, Structs, Modules, etc. I was going to make this change inUnderValidContext()
but the existing code works to short-circuit if the higlighted code is an ExpressionSyntax.Please let me know if there is a better way to design this that fits with the design of the existing extractmethod code better!