|
4 | 4 | */
|
5 | 5 |
|
6 | 6 | import csharp
|
| 7 | + |
| 8 | +private newtype TGvnKind = |
| 9 | + TGvnKindExpr(int kind) { expressions(_, kind, _) } or |
| 10 | + TGvnKindStmt(int kind) { statements(_, kind) } or |
| 11 | + TGvnKindDeclaration(GvnKindExpr kind, boolean thisTarget, Declaration d) { |
| 12 | + exists(Expr e | |
| 13 | + d = referenceAttribute(e) and thisTarget = isTargetThis(e) and kind = getKind(e) |
| 14 | + ) |
| 15 | + } |
| 16 | + |
| 17 | +abstract private class GvnKind extends TGvnKind { |
| 18 | + abstract string toString(); |
| 19 | +} |
| 20 | + |
| 21 | +private class GvnKindExpr extends GvnKind, TGvnKindExpr { |
| 22 | + private int kind; |
| 23 | + |
| 24 | + GvnKindExpr() { this = TGvnKindExpr(kind) } |
| 25 | + |
| 26 | + override string toString() { result = "Expr(" + kind.toString() + ")" } |
| 27 | +} |
| 28 | + |
| 29 | +private class GvnKindStmt extends GvnKind, TGvnKindStmt { |
| 30 | + private int kind; |
| 31 | + |
| 32 | + GvnKindStmt() { this = TGvnKindStmt(kind) } |
| 33 | + |
| 34 | + override string toString() { result = "Stmt(" + kind.toString() + ")" } |
| 35 | +} |
| 36 | + |
| 37 | +private class GvnKindDeclaration extends GvnKind, TGvnKindDeclaration { |
| 38 | + private GvnKindExpr kind; |
| 39 | + private boolean isTargetThis; |
| 40 | + private Declaration d; |
| 41 | + |
| 42 | + GvnKindDeclaration() { this = TGvnKindDeclaration(kind, isTargetThis, d) } |
| 43 | + |
| 44 | + override string toString() { result = kind.toString() + "," + isTargetThis + "," + d.toString() } |
| 45 | +} |
| 46 | + |
| 47 | +/** Gets the declaration referenced by the expression `e`, if any. */ |
| 48 | +private Declaration referenceAttribute(Expr e) { |
| 49 | + result = e.(MethodCall).getTarget() |
| 50 | + or |
| 51 | + result = e.(ObjectCreation).getTarget() |
| 52 | + or |
| 53 | + result = e.(Access).getTarget() |
| 54 | +} |
| 55 | + |
| 56 | +/** Returns true iff the target of the expression `e` is `this`. */ |
| 57 | +private boolean isTargetThis(Expr e) { |
| 58 | + result = true and e.(MemberAccess).targetIsThisInstance() |
| 59 | + or |
| 60 | + result = false and not e.(MemberAccess).targetIsThisInstance() |
| 61 | +} |
| 62 | + |
| 63 | +/** Gets the AST node kind of element `cfe` wrapped in the GvnKind type. */ |
| 64 | +private GvnKind getKind(ControlFlowElement cfe) { |
| 65 | + exists(int kind | |
| 66 | + expressions(cfe, kind, _) and |
| 67 | + result = TGvnKindExpr(kind) |
| 68 | + or |
| 69 | + statements(cfe, kind) and |
| 70 | + result = TGvnKindStmt(kind) |
| 71 | + ) |
| 72 | +} |
0 commit comments