-
Notifications
You must be signed in to change notification settings - Fork 2k
C#: Remove expanded assignments. #21452
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
Merged
michaelnebel
merged 18 commits into
github:main
from
michaelnebel:csharp/expandedassignment
Mar 27, 2026
Merged
Changes from 15 commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
c8169f5
C#: Don't extract expanded assignments and swap child indices for ass…
michaelnebel b426c6f
C#: Update the DB scheme to reflect that assign arithmetic- and bitwi…
michaelnebel 327757d
C#: Update the child indices for assignments, update Assign classes t…
michaelnebel 2a78183
C#: Deprecate the expanded assignment predicate as we no longer extra…
michaelnebel e2afb00
C#: Cleaup expanded assignments from the dispatch logic.
michaelnebel 569e33b
C#: Introduce a new kind of assignable definitions for compound assig…
michaelnebel 149df86
C#: Update the CFG implementation based on the new operations and rem…
michaelnebel 5167331
C#: Upgrade libraries and queries to use the new Operation classes.
michaelnebel 5551634
C#: Add/update tests and expected output.
michaelnebel 96f55fb
C#: Add operation types to the DB scheme.
michaelnebel 3d2d09d
C#: Use the DB types and replace the abstract class implementation.
michaelnebel a900fe8
C#: Adress review comments.
michaelnebel d96e8cb
C#: Remove expr_parent_adjusted.
michaelnebel 29acd69
C#: Add upgrade script.
michaelnebel 147ac37
C#: Add downgrade script.
michaelnebel a402ce5
C#: Fix bad join in cs/coalesce-of-identical-expressions.
michaelnebel a5f27b8
C#: Add change-note.
michaelnebel 41bb349
C#: Improve the downgrade script.
michaelnebel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
178 changes: 178 additions & 0 deletions
178
csharp/downgrades/19b8cc3e2dc768d4cbc03d6e3773b709bbebd036/assignments.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,178 @@ | ||
| class Expr extends @expr { | ||
| string toString() { none() } | ||
| } | ||
|
|
||
| class Location extends @location { | ||
| string toString() { none() } | ||
| } | ||
|
|
||
| newtype TAddedElement = | ||
| TAssignment(Expr e) or | ||
| TLhs(Expr e) or | ||
| TRhs(Expr e) | ||
|
|
||
| module Fresh = QlBuiltins::NewEntity<TAddedElement>; | ||
|
|
||
| class TNewExpr = @expr or Fresh::EntityId; | ||
|
|
||
| class NewExpr extends TNewExpr { | ||
| string toString() { none() } | ||
| } | ||
|
|
||
| class TNewControlFlowElement = @control_flow_element or Fresh::EntityId; | ||
|
|
||
| class NewControlFlowElement extends TNewControlFlowElement { | ||
| string toString() { none() } | ||
| } | ||
|
|
||
| class TypeOrRef extends @type_or_ref { | ||
| string toString() { none() } | ||
| } | ||
|
|
||
| class Callable extends @callable { | ||
| string toString() { none() } | ||
| } | ||
|
|
||
| class Accessible extends @accessible { | ||
| string toString() { none() } | ||
| } | ||
|
|
||
| predicate assignmentKind(int kind) { | ||
| // | 63 = @simple_assign_expr | ||
| // | 80 = @add_event_expr | ||
| // | 81 = @remove_event_expr | ||
| // | 83 = @local_var_decl_expr | ||
| kind = [63, 80, 81, 83] | ||
| } | ||
|
|
||
| predicate compoundAssignmentKind(int kind) { | ||
| // | 64 = @assign_add_expr | ||
| // | 65 = @assign_sub_expr | ||
| // | 66 = @assign_mul_expr | ||
| // | 67 = @assign_div_expr | ||
| // | 68 = @assign_rem_expr | ||
| // | 69 = @assign_and_expr | ||
| // | 70 = @assign_xor_expr | ||
| // | 71 = @assign_or_expr | ||
| // | 72 = @assign_lshift_expr | ||
| // | 73 = @assign_rshift_expr | ||
| // | 119 = @assign_coalesce_expr | ||
| // | 134 = @assign_urshift_expr | ||
| kind = [64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 119, 134] | ||
| } | ||
|
|
||
| int getOperatorKindFromAssignmentKind(int kind) { | ||
| kind = 64 and result = 44 // @assign_add_expr -> @add_expr | ||
| or | ||
| kind = 65 and result = 45 // @assign_sub_expr -> @sub_expr | ||
| or | ||
| kind = 66 and result = 41 // @assign_mul_expr -> @mul_expr | ||
| or | ||
| kind = 67 and result = 42 // @assign_div_expr -> @div_expr | ||
| or | ||
| kind = 68 and result = 43 // @assign_rem_expr -> @rem_expr | ||
| or | ||
| kind = 69 and result = 54 // @assign_and_expr -> @bit_and_expr | ||
| or | ||
| kind = 70 and result = 55 // @assign_xor_expr -> @bit_xor_expr | ||
| or | ||
| kind = 71 and result = 56 // @assign_or_expr -> @bit_or_expr | ||
| or | ||
| kind = 72 and result = 46 // @assign_lshift_expr -> @lshift_expr | ||
| or | ||
| kind = 73 and result = 47 // @assign_rshift_expr -> @rshift_expr | ||
| or | ||
| kind = 119 and result = 61 // @assign_coalesce_expr -> @coalesce_expr | ||
| or | ||
| kind = 134 and result = 133 // @assign_urshift_expr -> @urshift_expr | ||
| } | ||
|
|
||
| predicate isAssignment(Expr ass) { | ||
| exists(int kind | assignmentKind(kind) | expressions(ass, kind, _)) | ||
| } | ||
|
|
||
| class CompoundAssignmentExpr extends Expr { | ||
| CompoundAssignmentExpr() { | ||
| exists(int kind | compoundAssignmentKind(kind) | expressions(this, kind, _)) | ||
| } | ||
| } | ||
|
|
||
| query predicate new_expressions(NewExpr e, int kind, TypeOrRef t) { | ||
| expressions(e, kind, t) | ||
| or | ||
| // Introduce expanded expression nodes. | ||
| exists(CompoundAssignmentExpr compound, int kind0, Expr e1, int kind1 | | ||
| expressions(compound, kind0, t) and | ||
| compoundAssignmentKind(kind0) and | ||
| expressions(e1, kind1, _) and | ||
| expr_parent(e1, 0, compound) | ||
| | | ||
| Fresh::map(TAssignment(compound)) = e and kind = 63 | ||
| or | ||
| Fresh::map(TLhs(compound)) = e and kind = kind1 | ||
| or | ||
| Fresh::map(TRhs(compound)) = e and kind = getOperatorKindFromAssignmentKind(kind0) | ||
| ) | ||
| } | ||
|
|
||
| query predicate new_expr_parent(NewExpr e, int child, NewControlFlowElement parent) { | ||
| if isAssignment(parent) | ||
| then | ||
| // Swap children for assignments, local variable declarations and add/remove event. | ||
| child = 0 and expr_parent(e, 1, parent) | ||
| or | ||
| child = 1 and expr_parent(e, 0, parent) | ||
| else ( | ||
| exists(CompoundAssignmentExpr compound | | ||
| Fresh::map(TAssignment(compound)) = e and child = 2 and parent = compound | ||
| or | ||
| Fresh::map(TLhs(compound)) = e and child = 1 and parent = Fresh::map(TAssignment(compound)) | ||
| or | ||
| Fresh::map(TRhs(compound)) = e and child = 0 and parent = Fresh::map(TAssignment(compound)) | ||
| or | ||
| expr_parent(e, child, compound) and parent = Fresh::map(TRhs(compound)) | ||
| ) | ||
| or | ||
| // Copy the expr_parent relation except for compound assignment edges. | ||
| expr_parent(e, child, parent) and not parent instanceof CompoundAssignmentExpr | ||
| ) | ||
| } | ||
|
|
||
| query predicate new_expr_location(NewExpr e, Location loc) { | ||
| expr_location(e, loc) | ||
| or | ||
| exists(CompoundAssignmentExpr compound | | ||
| Fresh::map(TAssignment(compound)) = e and expr_location(compound, loc) | ||
| or | ||
| Fresh::map(TLhs(compound)) = e and | ||
| exists(Expr child | expr_location(child, loc) and expr_parent(child, 0, compound)) | ||
| or | ||
| Fresh::map(TRhs(compound)) = e and expr_location(compound, loc) | ||
| ) | ||
| } | ||
|
|
||
| query predicate new_expr_call(NewExpr e, Callable c) { | ||
| expr_call(e, c) and not e instanceof CompoundAssignmentExpr | ||
| or | ||
| exists(CompoundAssignmentExpr compound | | ||
| Fresh::map(TRhs(compound)) = e and expr_call(compound, c) | ||
| ) | ||
| } | ||
|
|
||
| query predicate new_dynamic_member_name(NewExpr e, string name) { | ||
| dynamic_member_name(e, name) and not e instanceof CompoundAssignmentExpr | ||
| or | ||
| exists(CompoundAssignmentExpr compound | | ||
| Fresh::map(TRhs(compound)) = e and dynamic_member_name(compound, name) | ||
| ) | ||
| } | ||
|
|
||
| query predicate new_expr_access(NewExpr e, Accessible a) { | ||
| expr_access(e, a) | ||
| or | ||
| exists(CompoundAssignmentExpr compound, Expr access | | ||
| expr_parent(access, 0, compound) and | ||
| expr_access(access, a) and | ||
| Fresh::map(TLhs(compound)) = e | ||
| ) | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
These could be
CompoundAssignmentExprinstead ofExpr, right? I don't know if it matters - it probably doesn't.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 will change it.