SlickEdit Product Discussion > SlickEdit 2022 v27 Beta Discussion

PowerShell String quoting problem

(1/3) > >>

As I started writing this, I expected Slick was just having problems with escaping ... but, it turned out more complicated.

I think that PowerShell string parsing is itself broken, but in this case Slick is different - it doesn't know about a special case.

This code:

--- Code: ---$a="power'string'shell"
$b = "'$($a.replace(`"'`", `"''`"))'"
Write-Ouput "Result is $b"

--- End code ---
The 3rd line is colored as a string in Slickedit.

Inside a "$()" subexpression it turns out you don't need to escape quotes -

--- Code: ---$b = "'$($a.replace("'", "''"))'"

--- End code ---
works fine - and Slickedit handles this.

Oddly, PowerShell accepts the back-tick double-quote (`") though...

--- Code: ---"...$("hello")..."     #OK
"...$(`"hello")..."  #Also OK (?) - ignoring the back-tick?
"...$(`"hello`")..."  #Also OK (?) - ignoring the back-tick?
"...$(`"hello`n")..." # Treats `n as newline.
--- End code ---

The following is really confusing

--- Code: ---"$(`"hello``"...``" ")"

--- End code ---
is equivalent to

--- Code: ---$("hello`"...`" ")
--- End code ---
Double back-tick double-quote (``") inside the subexpression escapes the special case I guess.

I think that PowerShell accepts the Back-tick DoubleQuote as a special hack in case people expect to need to escape the double quotes inside the sub expression, when it isn't necessary.
I hate special hacks like this in PowerShell.

Thanks for the great test cases. The problem with all of these is the same. SlickEdit needs to handle backtick differently when inside a "...$()..." subexpression.

Like you said, this was a stupid unnecessary and even inconsistent hack. This has to be special cased ONLY for a "..." string but not a @"..."@ string.

The fix for this will look a bit ugly because we will need a "PowerShell Base" profile which will have to be used as a base class profile for PowerShell and a new "PowerShell String Subexpression" profile. The Base won't define backtick but the parent profiles will need different definitions for backtick. Due to the length of match difference, it has to be done this way.

I've found some further issues.

--- Code: ---# this works fine as expected
echo "$( echo "hello" )"

--- End code ---

--- Code: ---# this does not compile
echo "$( echo "hello)" )"

--- End code ---

SlickEdit has a very simple way to handle this. PowerShell has made some very poor choices in their implementation. Very different than most modern interpolated strings. We do see some languages take this approach but this is not done in the better languages.

Clearly there are some ugly hacks in there...

Seems like at some level of parsing it understands that nested ")" is inside quotes, and at another level it doesn't - since it interacts with the opening "$(", but yet it still will print - if you balance it.

its interesting though that the interactive PS prompt coloring seems to have the same hacks.
Maybe the PowerShell engine interface supports this?

--- Code: ---PS C:\> echo "$( echo "hell(o""""""" 5+5)")"
hell(o"" 5+5)

--- End code ---
From 7 to 10 double quotes (") in that statement will print 2 double-quotes!
With 11 double-quotes you get three output!
With 15 double-quotes you get four output!

Thanks for pointing this out. I didn't notice. This is some more really hacky stuff (no other languages do this). The color coding engine doesn't support this type of nesting and it would be very difficult to add. For now, we'll have to settle for incorrect color coding if the user makes a mistake with nesting parens or braces. User will know somethings wrong when they try to run the code.


[0] Message Index

[#] Next page

Go to full version