-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Add type inference for Select-Object command #7171
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
…rred types This reduces allocations and makes the code easier to debug.
|
|
||
| return expression != null && | ||
| SafeExprEvaluator.TrySafeEval(expression, ExecutionContext, out value) && | ||
| SafeExprEvaluator.TrySafeEval(expression, ExecutionContext, out var 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.
The PR contains so many style changes that makes it unreasonably large.
Let's leave only significant changes - it will greatly facilitate and speed up the code viewing. Please move style changes in another PR.
BrucePay
left a comment
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.
Over all it looks good. I'm still a bit curious about the change from IEnumerable -> List. Also, i think the comments that talk about 'yield' need to be updated.
| var list = value as IList; | ||
| if (list != null && list.Count > 0) | ||
| if (value is IList list && list.Count > 0) | ||
| { |
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.
Extra line?
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.
fixing.
| var psMethod = member as PSMethod; | ||
| var methodCacheEntry = psMethod?.adapterData as DotNetAdapter.MethodCacheEntry; | ||
| return methodCacheEntry != null && methodCacheEntry.methodInformationStructures[0].method.IsConstructor; | ||
| return psMethod?.adapterData is DotNetAdapter.MethodCacheEntry methodCacheEntry && methodCacheEntry.methodInformationStructures[0].method.IsConstructor; |
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 is so much going on in this statement that's hard to read. The original code was much easier to follow.
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.
Agree! A bit to fast there :)
|
|
||
| private IEnumerable<PSTypeName> InferTypesFrom(CommandAst commandAst) | ||
| private void InferTypesFrom(CommandAst commandAst, List<PSTypeName> inferredTypes) | ||
| { |
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 should validate that this input is not null.
| } | ||
| yield break; // yield break; | ||
| // Get-CimInstance/New-CimInstance - yields a CimInstance with ETS type based on its arguments for -Namespace and -ClassName parameters | ||
| InferTypesFromCimCommand(pseudoBinding, inferredTypes); |
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.
Since this is no longer and IEnumerable, saying "yield" is a bit weird. Perhaps
Get-CimInstance/New-CimInstance - return a CimInstance with ETS type based on its arguments for -Namespace and -ClassName parameters
| if (pseudoBinding.BoundArguments.TryGetValue("Property", out _) | ||
| || pseudoBinding.BoundArguments.TryGetValue("ExcludeProperty", out _)) | ||
| { | ||
| return; |
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 the argument to -Property is a set of literal strings (most common case), then you could infer the "type" of the output object from them.
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.
Yes. I discussed this a bit with Jason.
We don't currently have a good representation for this, but I would like to have that.
Same thing when you create a PSCustomObject from a hashtable.
But maybe something like "PSObject#Prop1/Prop2/Prop3"
It wouldn't say anything about the types of the properties, but that could maybe be encoded as well.
|
|
||
| private IEnumerable<PSTypeName> InferTypesFrom(CommandAst commandAst) | ||
| private void InferTypesFrom(CommandAst commandAst, List<PSTypeName> inferredTypes) | ||
| { |
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.
Why the change from IEnumerable to List?
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 don't understand too why we add the allocations.
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.
Mostly debugability. It was a nightmare with all the nested state machines.
But since you have an allocation and virtual dispatch on every generated statemachine class that is generated when we use yield, my guess is that we actually have fewer allocations now.
And in general, I think the code got simpler. Several instances of loops that just yielded the loop object that just disappeared.
If you want to do the exercise, try debugging a tab completion before and after 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.
Yes, debugging can be a headache here.
As for allocations my understanding is that it depends on how we access the object - if we use IEnumerable interface we allocate in both cases, if we cast to a collection we don't allocate I believe.
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.
But there is no underlying collection to cast to. All the methods here that yield only has the generated state machine classes.
|
I don't think the Travis build failure has anything to do with this PR. |
|
@powercode Please look CodeFactor issues. |
|
@powercode As for CodeFactor issues. Really our policy is flexible:
Thanks again for your contribution! |
|
Restart CI Travis Linux. |
|
@TravisEz13 this looks ready; pls take a look when you can. |
PR Summary
Add type inference for Select-Object command
Fixes #7170
PR Checklist
This change add type inference for Select-Object in the cases when no projection is done.
I.E. when neither
-Propertyor-ExcludePropertyis specified..h,.cpp,.cs,.ps1and.psm1files have the correct copyright header][feature]if the change is significant or affects feature tests]