C#: Remove expanded assignments.#21452
Conversation
c94de85 to
1d8d712
Compare
abb75be to
5021ea9
Compare
41fef59 to
07144c2
Compare
|
@hvitved : I would really appreciate a review of this PR even though it is still in draft mode. The PR still needs upgrade/downgrade scripts and more DCA runs. |
07144c2 to
d2188dd
Compare
| * An assignment operation. Either an arithmetic assignment operation | ||
| * (`AssignArithmeticOperation`), a bitwise assignment operation | ||
| * (`AssignBitwiseOperation`), or an event assignment (`AddOrRemoveEventExpr`). | ||
| * (`AssignArithmeticOperation`), a bitwise assignment operation or |
There was a problem hiding this comment.
Spurious "or"
| * (`AssignArithmeticOperation`), a bitwise assignment operation or | |
| * (`AssignArithmeticOperation`), a bitwise assignment operation |
| } | ||
|
|
||
| /** | ||
| * An assignment operation that corresponds to an operator call, for example `x += y` corresponds to `x = x + y`. |
There was a problem hiding this comment.
This reads somewhat off to me. Did you mean something like this instead?
| * An assignment operation that corresponds to an operator call, for example `x += y` corresponds to `x = x + y`. | |
| * An assignment operation that corresponds to an operator call, for example `x += y` corresponds to a call to `+=`. |
There was a problem hiding this comment.
Some further elaboration on this piece of qldoc might also be nice to clarify exactly which compound assignments are considered OperatorCalls.
| /** | ||
| * An assignment operation that corresponds to an operator call, for example `x += y` corresponds to `x = x + y`. | ||
| */ | ||
| class AssignCallOperation extends AssignOperation, OperatorCall, @assign_op_call_expr { |
There was a problem hiding this comment.
Now that most AssignOperations extend OperatorCall, then the qldoc for OperatorCall needs a tweak as it currently claims to only cover calls to user-defined operators.
There was a problem hiding this comment.
Yes, we should consider changing the wording as I am not sure what a non user-defined operator is (unless it is a real built-in like &&). The operator used in a += b (when a and b are of type int) is a user-defined operator and it is declared here.
| * An assignment operation that corresponds to an operator call, for example `x += y` corresponds to `x = x + y`. | ||
| */ | ||
| class AssignCallOperation extends AssignOperation, OperatorCall, @assign_op_call_expr { | ||
| override string toString() { result = "... " + this.getOperator() + " ..." } |
There was a problem hiding this comment.
This toString can be simplified.
| override string toString() { result = "... " + this.getOperator() + " ..." } | |
| override string toString() { result = AssignOperation.super.toString() } |
| import Expr | ||
|
|
||
| /** A binary operation that involves a null-coalescing operation. */ | ||
| abstract private class NullCoalescingOperationImpl extends BinaryOperation { } |
There was a problem hiding this comment.
I believe all the classes in this file break some new ground wrt the AST class hierarchy design, so perhaps ought to be considered in a slightly broader bike-shedding session. Or is there something similar in other languages that I'm not aware of?
Regardless, I'm not a big fan of all the Add-prefixed names. Sure they're private, but they're still not very nice and they overload the meaning of "Add" in a context that already references "Add". Also, it's unfortunate that e.g. AddExpr and AssignAddExpr are not subclasses of AddOperation - that would be more natural. And if the latter is fixed, then I don't think we need all those addition-to-abstract-class classes that have such awkward names, which would address the former point as well.
There was a problem hiding this comment.
The other option that I considered was extending the DB-scheme with @add_operation = @add_expr | @assign_add_expr; and similar for the other operations, then the QL part will look more "natural". Would you prefer such a solution instead?
| * ``` | ||
| * Use `expr_parent` instead. | ||
| */ | ||
| cached |
There was a problem hiding this comment.
May as well get rid of cached.
There was a problem hiding this comment.
We can't, it's a public predicate in a cached module - so it has to be cached as well.
There was a problem hiding this comment.
Just remove it; the QL doc on the file says INTERNAL: Do not use..
|
Besides the nits, code changes generally LGTM. |
hvitved
left a comment
There was a problem hiding this comment.
Overall LGTM; no further comments than what @aschackmull has already pointed out, thanks for making this change.
fd781ef to
8f725cd
Compare
| // Swap children for assignments, local variable declarations and add/remove event. | ||
| if isAssignment(parent) | ||
| then | ||
| child = 0 and expr_parent(e, 1, parent) |
There was a problem hiding this comment.
These two need new_expressions(parent, _, _) and new_expression(e, _, _) to prevent db inconsistencies, right?
There was a problem hiding this comment.
This query predicate is only concerned with contracting and rotating the parent/child relation.
The first case handles rotating the children of "assignments" (non-expanding), where we re-use existing expression entities (and the expressions are included in the update to the expressions table, which is the result of running new_expressions - however, I haven't tried running the code yet).
There was a problem hiding this comment.
It's exactly the contraction that I'm thinking about - i.e. currently the child-parent tuples for the expressions that we delete in new_expressions are being kept, which I think will create an inconsistent db.
| child = 1 and expr_parent(e, 0, op) | ||
| ) | ||
| or | ||
| expr_parent(e, child, parent) and not exists(getOperatorCall(parent)) |
|
What about downgrade script? |
Uh, sorry - I should have mentioned that the PR is now considered "draft" again. I haven't even tried running the upgrade script yet - and yes - a downgrade script it also needed - but I would like to test the upgrade script first. |
…se operations are operator calls.
…o extend OperatorCall and add AssignOperation classes.
…ct expanded assignments.
…nments (those that was previously covered by expanded assignments).
…ove hack that rotates children of assignments.
8f725cd to
028f2b8
Compare
This PR has two goals, primarily to avoid making multiple upgrade/downgrade scripts:
a += b, it would synthesizea = a + b.Review on a commit-by-commit basis is encouraged.
Implementation notes
a += b(e.g., whenaandbare int) as an operator call, since it implicitly invokes the user-defined static operator onInt32.??=as the null-coalescing operator is a built-in short-circuit like operation.AddOperation, which can represent eithera + bora += b).DCA notes
cs/unsynchronized-getteris due to removal of a false positive: the query did not properly account for expanded assignments.cs/web/xsslooks acceptable: one alert is removed, but it is essentially a shorter path to the same underlying alert (which is here)cs/useless-upcastlook acceptable.