Repository navigation
[WIP] Support ListLiteralExpression '[]' in PowerShell - #5761
Dongbo Wang (daxian-dbw) wants to merge 4 commits into
Conversation
|
Nevermind.. missed the other PR. |
|
Mark Kraus (@markekraus) My first design attempt is to support We need more discussions on the design, and that is why I submitted 2 PRs for the list support: #5762 to add |
Jason Shirk (lzybkr)
left a comment
There was a problem hiding this comment.
Since this is wip, I just did a quick skim.
| return new NewArrayInitInstruction<T>(elementCount); | ||
| } | ||
|
|
||
| protected internal override Instruction NewListInit(int elementCount) |
There was a problem hiding this comment.
I don't think we should add this to the interpreter - this way it stays as close as possible to original and/or the one used for dynamic when now JIT is available.
It is possible to add new instructions without touching the interpreter it that's how you want to do it - see PowerShellLoopExpression for an example.
There was a problem hiding this comment.
The NewListInitInstruction is a minor optimization which can be removed.
But I need to implement LightCompiler.CompileListInitExpression because it's currently not implemented. Are you suggesting to not use ListInitExpression in our compiler generated code?
There was a problem hiding this comment.
I see the method is now implemented: http://source.dot.net/#System.Linq.Expressions/System/Linq/Expressions/Interpreter/LightCompiler.cs,a988c37e1da7a799
I wonder if there is a supported way of invoking the interpreter now? We'd have to make sure they have any of our fixes first, but it'd be nice to not ship two copies of basically the same thing.
There was a problem hiding this comment.
Great, I can use their implementation then.
| } | ||
|
|
||
| /// <summary/> | ||
| public interface ICustomAstVisitor3 : ICustomAstVisitor2 |
There was a problem hiding this comment.
I think numbered interfaces made sense when the release cycle spanned years, but I'm worried we'll end up with ICustomAstVistor9 before too long.
There was a problem hiding this comment.
One (maybe not awesome) idea is to avoid the problem for this feature is to add a bool flag to ArrayLiteralAst - because they should be structurally the same.
The downside to this approach is that some analysis tools that aren't aware of list literals will analyze the ast as an array, e.g. they may incorrectly give warnings about performance.
There was a problem hiding this comment.
I thought about reusing the ArrayLiteralAst, but didn't go that direction for two reasons:
- An explicit
ListLiteralAstis more discoverable. ArrayLiteralAstcan appear on the left side of an assignment. I didn't plan to make[]also assignable. (but I don't object to the idea to make it capable of the same).
I would like to see more discussion on this before updating the code.
| { | ||
| Expression values = Compile(listLiteralAst.Elements[0]); | ||
|
|
||
| if (values.Type == typeof(List<object>)) { return values; } |
There was a problem hiding this comment.
I don't understand this. Does this mean the following would be true?
$x = [1]
$y = [[1]]
$x.Count -eq $y.Count -and $x[0] -eq $y[0]
There was a problem hiding this comment.
Reading more of the implementation, I'm confused now. Is this supposed to emulate ArrayExpressionAst or ArrayLiteralAst - it seems like the former, but it's named like the later.
There was a problem hiding this comment.
This is a change I made that is different from ArrayLiteral -- when there is only one expression element in the ListLiteral, unwrap the value of the expression element like @() does.
This is because I think it may be better for [(dir)] to return a list containing all files than it to return a list containing an object array.
It's just one of my thoughts, not necessarily a right one 😄
There was a problem hiding this comment.
You shouldn't call it a literal if you can't guarantee the number of objects in the result.
There was a problem hiding this comment.
Good point. I will remove that part of logic.
|
|
||
| do { | ||
| if (commaToken != null) { SkipToken(); } | ||
| V3SkipNewlines(); |
There was a problem hiding this comment.
It's probably time to get rid of V3SkipNewlines - I was overly cautious introducing that method and it hasn't been used.
There was a problem hiding this comment.
Will replace V3SkipNewlines with SkipNewlines
| } | ||
| else if (listValues.Count > 0) | ||
| { | ||
| extent = ExtentOf(lBracket, listValues[listValues.Count-1].Extent); |
There was a problem hiding this comment.
This excludes a trailing comma. The simple approach to tracking the end is to just have a variable endExtent and keep updating it with each token that you consume or ast you add to listValues.
There was a problem hiding this comment.
Update to use a endExtent variable.
|
Per the discussions in #5643, it's commonly agreed that we want |
PR Summary
An attempt to address #5643
This design adds the
ListLiteralExpression '[]'to PowerShell, which is similar to theArrayLiteralExpression. They are different in mainly two ways:ListLiteralExpressionalways returns aList<object>ListLiteralExpressionunwraps the value of the expression whileArrayLiteralExpressiondirectly uses the value as the first element of the returned array.Please review with #5762 as a comparison, where list is supported as a
ListExpression '@[]', similar toArrayExpression '@()'.Example
PR Checklist
Note: Please mark anything not applicable to this PR
NA.[feature]if the change is significant or affectes feature testsWIP:to the beginning of the title and remove the prefix when the PR is ready.