Skip to content
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

Implement Null Coalescing and Null Coalescing assignment operators #10636

Merged
merged 24 commits into from Oct 17, 2019

Conversation

adityapatwardhan
Copy link
Member

@adityapatwardhan adityapatwardhan commented Sep 27, 2019

PR Summary

Implement the Null Coalescing ?? and Null Coalescing Assignment ??= operators.

PR Context

The operators are discussed in the issue #3240
This PR addresses part of RFC PowerShell/PowerShell-RFC#223

The PR is marked as a Breaking Change due to changes in the TokenFlags enum. The changes were made to include the new TokenFlag - BinaryPrecedenceCoalesce. While making this change, it was also decided to create more space in the BinaryPrecedence section of the enum for future binary operators. The BinaryPrecedenceMask was also changed from 0x07 to 0x0f. The order of precedence is not changed. We expected it can cause a breaking change for binary modules as C# treats enums as constants. Though, it is a breaking change we expect the impact to be pretty low as the usage of precedence token flags should be fairly low.

PR Checklist

@kilasuit
Copy link
Collaborator

FYI this will clash with Posh-Git that implements an alias of ?? as below

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           ?? -> Invoke-NullCoalescing                        0.7.3      Posh-git

@rkeithhill
Copy link
Collaborator

We've already moved the use of ?? to internal-only in v1 and will happily get rid of it altogether for PS v7.

@adityapatwardhan adityapatwardhan marked this pull request as ready for review October 2, 2019 21:48
Copy link
Collaborator

@rjmholt rjmholt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice that this didn't require any changes to the parser and generally quite contained elsewhere -- feels like a vindication of good code for assignment processing.

Left a few comments.

Copy link
Member

@daxian-dbw daxian-dbw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talked to @adityapatwardhan offline.
After more thoughts, supporting the coalesce operation in binder doesn't really make sense. The operation is so simple that the restriction generated from binder will basically be the same checks we will do if the support is done in compiler directly. So after talking with @adityapatwardhan, we decided to move the implementation back to compiler.

The extended binary operation approach could be useful for a binary operation that is more complex, in case we need another binary operator in future.


/// <summary>
/// The precedence of comparison operators including: '-eq', '-ne', '-ge', '-gt', '-lt', '-le', '-like', '-notlike',
/// '-match', '-notmatch', '-replace', '-contains', '-notcontains', '-in', '-notin', '-split', '-join', '-is', '-isnot', '-as',
/// and all of the case sensitive variants of these operators, if they exists.
/// </summary>
BinaryPrecedenceComparison = 3,
BinaryPrecedenceComparison = 0x5,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since enum's are treated like constants, this would be a breaking change for compiled projects right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this will be a breaking change. We are expecting the impact to very small though. I have updated the PR Context in description with more details.

@TylerLeonhardt
Copy link
Member

This issue has changes that could potentially change syntax. Please consider adding this feature to EditorSyntax which is used for syntax highlighting in GitHub, Visual Studio Code, Atom, Sublime Text, and many more locations.

Consistent syntax highlighting is very important for the language and a feature isn't "complete" until syntax highlighting is what is expected.

If you can't contribute to EditorSyntax, at least open an issue to track the work - however, please note, that no one is actively working on the repo and so the work will likely not get done in a timely manner.

We hope that you consider contributing to EditorSyntax.

(note this is copy/pasted text for any change that looks like it could impact EditorSyntax - and will be a bot in the future)

@TylerLeonhardt
Copy link
Member

(thanks for opening the issue already!)

@daxian-dbw daxian-dbw added the Breaking-Change breaking change that may affect users label Oct 14, 2019
Copy link
Member

@daxian-dbw daxian-dbw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Now waiting on the breaking change review from the committee.

@daxian-dbw daxian-dbw added the Review - Committee The PR/Issue needs a review from the PowerShell Committee label Oct 15, 2019
@daxian-dbw
Copy link
Member

It just occurred to me that none of the existing ICustomAstVisitor2.VisitBinaryExpression implementation is changed.
@adityapatwardhan did you review all existing VisitBinaryExpression and VisitAssignmentStatement to see if anything needs to be changed? For example, IsConstantValueVisitor might need to be updated for the ?? binary operation, as this operation can be potentially constant value.

@rjmholt
Copy link
Collaborator

rjmholt commented Oct 15, 2019

IsConstantValueVisitor might need to be updated for the ?? binary operation, as this operation can be potentially constant value.

It looks like that's just a question of the token flag:

public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
{
return binaryExpressionAst.Operator.HasTrait(TokenFlags.CanConstantFold) &&
(bool)binaryExpressionAst.Left.Accept(this) && (bool)binaryExpressionAst.Right.Accept(this)
&& !IsNullDivisor(binaryExpressionAst.Right);
}

@adityapatwardhan
Copy link
Member Author

@daxian-dbw I will review all the existing VisitBinaryExpression and VisitAssignmentStatement to see if anything needs to change. I will submit those changes as part of a different PR.

@daxian-dbw
Copy link
Member

@PowerShell/powershell-committee reviewed the changes to TokenFlags and agreed to accept this breaking change. We can revisit this decision if there is new feedback coming in during the use of 7.0.0-preview.5 and 7.0.0-preview.6 of pwsh.

@iSazonov iSazonov added Committee-Reviewed PS-Committee has reviewed this and made a decision and removed Review - Committee The PR/Issue needs a review from the PowerShell Committee labels Oct 17, 2019
@daxian-dbw daxian-dbw merged commit 425bc36 into PowerShell:master Oct 17, 2019
@SteveL-MSFT SteveL-MSFT added this to the 7.0.0-preview.5 milestone Oct 17, 2019
@daxian-dbw daxian-dbw added the CL-Engine Indicates that a PR should be marked as an engine change in the Change Log label Oct 17, 2019
@ghost
Copy link

ghost commented Oct 23, 2019

🎉v7.0.0-preview.5 has been released which incorporates this pull request.:tada:

Handy links:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Breaking-Change breaking change that may affect users CL-Engine Indicates that a PR should be marked as an engine change in the Change Log Committee-Reviewed PS-Committee has reviewed this and made a decision
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet