-
Notifications
You must be signed in to change notification settings - Fork 8k
WIP: Correct completions for quoting and escaping #10226
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
Conversation
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.
The pattern quote == string.Empty ? (char)0 : quote[0]
is used 16 time - it should be moved in QuoteArgument() method.
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 be acceptable to rewrite HandleSingleAndDoubleQuote()
:
PowerShell/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs
Lines 6489 to 6519 in 8f5b2c2
internal static string HandleDoubleAndSingleQuote(ref string wordToComplete) | |
{ | |
string quote = string.Empty; | |
if (!string.IsNullOrEmpty(wordToComplete) && (wordToComplete[0].IsSingleQuote() || wordToComplete[0].IsDoubleQuote())) | |
{ | |
char frontQuote = wordToComplete[0]; | |
int length = wordToComplete.Length; | |
if (length == 1) | |
{ | |
wordToComplete = string.Empty; | |
quote = frontQuote.IsSingleQuote() ? "'" : "\""; | |
} | |
else if (length > 1) | |
{ | |
if ((wordToComplete[length - 1].IsDoubleQuote() && frontQuote.IsDoubleQuote()) || (wordToComplete[length - 1].IsSingleQuote() && frontQuote.IsSingleQuote())) | |
{ | |
wordToComplete = wordToComplete.Substring(1, length - 2); | |
quote = frontQuote.IsSingleQuote() ? "'" : "\""; | |
} | |
else if (!wordToComplete[length - 1].IsDoubleQuote() && !wordToComplete[length - 1].IsSingleQuote()) | |
{ | |
wordToComplete = wordToComplete.Substring(1); | |
quote = frontQuote.IsSingleQuote() ? "'" : "\""; | |
} | |
} | |
} | |
return quote; | |
} |
with this:
internal static char HandleDoubleAndSingleQuote(ref string wordToComplete)
{
char quote = (char)0;
if (!string.IsNullOrEmpty(wordToComplete) && (wordToComplete[0].IsSingleQuote() || wordToComplete[0].IsDoubleQuote()))
{
quote = wordToComplete[0].IsSingleQuote() ? '\'' : '"';
int length = wordToComplete.Length;
wordToComplete = length == 1 ? string.Empty :
(quote.IsSingleQuote() ? wordToComplete[length - 1].IsSingleQuote() : wordToComplete[length - 1].IsDoubleQuote()) ?
wordToComplete.Substring(1, length - 2) : wordToComplete.Substring(1);
}
return quote;
}
and then eliminate the kludge? This would change the entire code over to using char
to pass the quote.
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.
You check quote == 0 only once in "QuoteArgument". I guess you could use quote.Empty and don't use the zero value.
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.
It comes down to, do you use a string to store just three values, empty, '
or "
. or is there a better way? Using a string means you have to use [0] references to get at the character (after you've confirmed that the string isn't empty) for using IsSingleQuote
and IsDoubleQuote
.
In a sense, its a glorified enum. Is(Single/Double)Quote's are overkill because at this point it can only contain 3 values, not any of the other 7 quotes (at least as defined by HandleSingleAndDoubleQuote).
src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs
Outdated
Show resolved
Hide resolved
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 add comment why we need the change.
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.
per 033ef6c:
allow completion starting with `$:`
Enhances variable completion allowing completions to start with `$:`
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 issue #10239.
src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs
Outdated
Show resolved
Hide resolved
src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs
Outdated
Show resolved
Hide resolved
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 use for
cycle.
Is there a lint I am supposed to be using? I don't think any of the CodeFactor / Codacy issues would be there if there if I had the linting warnings. I didn't find any references to a lint in the contributing guide. |
Noting, this PR may conflict with #7407, as this PR attempts to do some of the same things, but not exclusively to file paths. |
Broken TestsTwo test patterns are currently broke. The reason for this is that this PR implements a more specific Patterns failing:
Both test patterns involve command completions, so the quoting of the path resulted in the completion using the invoke operator Tests Needed
We'll keep adding to this list to track the tests fixed, needed and added. |
CodeFactor is based on StyleCop - you can run it locally. Usually we don't request to fix style issue which is not in your code. If there is a lot of style issues please pull new PR to ifx them - we don't want to mess fuctional and style changes in one PR. |
@kwkam Could you please review the PR too? |
I did notice that a lot of the style errors were not from my code changes (at first I thought they were all in my code, probably because it showed new issues first), and that would make it difficult to let a format-document command run, but it would sure help if I could format-selection and get the easy ones taken care of, and then a lint would show the other suggestions. That's how the TS/JS repositories I have contributed to work, and its all in VS Code. I was able to turn on the 'editor settings' feature of the C# extension and it did change some of the formatting, but it still doesn't warn me that this repository would prefer all IF statements braced, comments spaced out, statements after IF statements spaced out, etc... |
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'm considering putting the call to GenerateVariableCompletionText inside AddUniqueVariable, because if the variable is not unique, there is no reason to determine if it needs braced.
I think I need to have an exception in the argument quoting/bareword checker for commands, as they have a slightly different bareword syntax and I am not accounting for that. |
fa084e0
to
755d95b
Compare
That's weird, the Windows test must be skipping the completion tests, because its not failing them, where as the MacOS and Linux tests are failing completion tests (which are currently expected at this time). |
@msftrncs It is Newline difference. |
@msftrncs Have you plans to continue? |
I do, having trouble dedicating time. I do have new commits for improved use of the parser to determine when quoting is required, specially for command name values. |
Create method QuoteMemberName, determines if a supplied member name requires quoting to be used by an accessor, returning the member name and escaped if required.
Utilize QuoteMemberName from CodeGenerator class to complete member names so completions are quoted and escaped as required. Fixes PowerShell#10198
Created new private method GenerateVariableCompletionText to handle correct patterning of `$` and `@` variable completions, bracing when required, escaping when braced, and adding leading `:` under certain circumstances. Primary improvement is regarding detecting the need to use braces. Fixes PowerShell#10006
Enhances variable completion allowing completions to start with `$:`
Its purpose has been removed by prior commits, and future use could be misleading.
Add methods QuoteArgument and EscapeDoubleQuotedStringContent to assist generating argument completions that are correctly quoted and escaped. Includes private method to determine if argument content cannot be used bareword.
Enhance all argument completers to use QuoteArgument code generator to insure consistent quoting and escaping by all argument completion completers. Fixes PowerShell#9881 Fixes PowerShell#7569
Include in ShouldArgumentNotBeBareword, returning `true` when argument would appear to be a parameter name, which will cause such arguments values to require quoting or escaping.
GenerateVariableCompletionText failed to scan entire variable name for `:`, if a character requiring a brace was found first. Optimized character look to skip first character without using substring.
Revision to base the passed parameters for the current quote character to be type string instead of char, the way the previous code worked.
Optimize HandleDoubleAndSingleQuote() method, reducing redundant and unneccessary operations.
corrected where completions of commands for an argument would incorrectly include an `&`.
755d95b
to
ccbc5d2
Compare
I see 9-11 tests fails. Is it expected? |
c02b24e
to
e9f343e
Compare
Yes and no, I expected the '$' tests to fail, because an ending I also have not yet handled testing, as I am not sure how much of these changes can be specifically tested. |
Implement a xRequiresQuote in CodeGen, similar to the previous CompletionRequiresQuote, but in 3 parts, and with much more thorough checks for parsing conditions that indicate the value needs to be quoted.
e9f343e
to
f80e711
Compare
At this time, I do expect the completion tests that involve a |
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
FYI #9881 this seems to be fixed as of version 7.4.0 |
Sorry, I'm closing it, because it's a long time ago. If there is something that has not been fixed yet in recent version, it is better to open a new PR. Thanks! |
PR Summary
Correct completions (Tab/Intellisense) for quoting and escaping for the various kinds of completions available.
PR Context
Completers of all types seem to have inconsistent quoting and escaping behaviors that often left the resulting completion still unusable, most specially when the completion contained:
This PR, through a series of commits, brings unity to the completers, implementing methods that were already available in the code and additional methods, where by each type of completer (variable name, member name, argument) utilizes a common quoting and escaping method.
Fix #10006 - Variable (
$
and@
) name bracing and escaping and empty scope prefixingFix #10239 - Variable completion has no results with input
$:
Fix #10198 - Member name completion quoting and escaping
Fix #9881 - General argument completion quoting and escaping
Fix #10218 - Argument completion of
ValidateSetAttribute
values quoting and escapingFix #7569 -
\\Server\Share With Space
quoting and escapingThis PR is still WIP, as it lacks any changes for testing, and it is unknown if it causes any tests to fail.
To quote @bergmeister, be gentle. :) This is my first work in C#.
@rkeithhill, from dahlbyk/posh-git#683 (comment), this includes such a method,
[System.Management.Automation.Language.CodeGeneration]::QuoteArgument()
.PR Checklist
.h
,.cpp
,.cs
,.ps1
and.psm1
files have the correct copyright headerWIP:
or[ WIP ]
to the beginning of the title (theWIP
bot will keep its status check atPending
while the prefix is present) and remove the prefix when the PR is ready.