-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Fix completion of variables with an attribute in the assignment #25016
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5587,16 +5587,40 @@ public override AstVisitAction VisitAssignmentStatement(AssignmentStatementAst a | |
| return AstVisitAction.StopVisit; | ||
| } | ||
|
|
||
| if (assignmentStatementAst.Left is ConvertExpressionAst convertExpression) | ||
| if (assignmentStatementAst.Left is AttributedExpressionAst attributedExpression) | ||
| { | ||
| if (convertExpression.Child is VariableExpressionAst variableExpression) | ||
| var firstConvertExpression = attributedExpression as ConvertExpressionAst; | ||
| ExpressionAst child = attributedExpression.Child; | ||
| while (child is AttributedExpressionAst attributeChild) | ||
| { | ||
| if (firstConvertExpression is null && attributeChild is ConvertExpressionAst convertExpression) | ||
| { | ||
| // Multiple type constraint can be set on a variable like this: [int] [string] $Var1 = 1 | ||
| // But it's the left most type constraint that determines the final type. | ||
| firstConvertExpression = convertExpression; | ||
| } | ||
|
|
||
| child = attributeChild.Child; | ||
| } | ||
|
|
||
| if (child is VariableExpressionAst variableExpression) | ||
| { | ||
| if (variableExpression == CompletionVariableAst || s_specialVariablesCache.Value.Contains(variableExpression.VariablePath.UserPath)) | ||
| { | ||
| return AstVisitAction.Continue; | ||
| } | ||
|
|
||
| SaveVariableInfo(variableExpression.VariablePath.UserPath, convertExpression.StaticType, isConstraint: true); | ||
| if (firstConvertExpression is not null) | ||
| { | ||
| SaveVariableInfo(variableExpression.VariablePath.UserPath, firstConvertExpression.StaticType, isConstraint: true); | ||
| } | ||
| else | ||
| { | ||
| Type lastAssignedType = assignmentStatementAst.Right is CommandExpressionAst commandExpression | ||
| ? GetInferredVarTypeFromAst(commandExpression.Expression) | ||
| : null; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All the types handled by As for useful defaults: I can't think of any. I mean I guess I could add
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If it makes sense to improve in future, I'd prefer to use case expression pattern with a todo comment for null default about types we can process in future.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "If it makes sense" is subjective. If it was up to me alone I'd leave it exactly like it is now as it was never meant to be a comprehensive type analysis. |
||
| SaveVariableInfo(variableExpression.VariablePath.UserPath, lastAssignedType, isConstraint: false); | ||
| } | ||
| } | ||
| } | ||
| else if (assignmentStatementAst.Left is VariableExpressionAst variableExpression) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.