Distinguish record patterns that do or don't declare identifiers

This commit is contained in:
Chris Smowton
2024-03-25 16:20:36 +00:00
parent a4401963f5
commit 17193ac11b
2 changed files with 19 additions and 6 deletions

View File

@@ -2739,4 +2739,14 @@ class RecordPatternExpr extends Expr, @recordpatternexpr {
)
)
}
/**
* Holds if this record pattern declares any identifiers (i.e., at least one leaf declaration is named).
*/
predicate declaresAnyIdentifiers() {
exists(PatternExpr subPattern | subPattern = this.getSubPattern(_) |
subPattern.asRecordPattern().declaresAnyIdentifiers() or
not subPattern.asBindingOrUnnamedPattern().isAnonymous()
)
}
}

View File

@@ -194,14 +194,17 @@ predicate simpleAstFlowStep(Expr e1, Expr e2) {
// In the following three cases only record patterns need this flow edge, leading from the bound instanceof
// or switch tested expression to a record pattern that will read its fields. Simple binding patterns are
// handled via VariableAssign.getSource instead.
// We only consider unique patterns because cases that declare multiple patterns are not allowed to declare
// any identifiers, so can't participate in dataflow.
exists(SwitchExpr se |
e1 = se.getExpr() and e2 = se.getACase().(PatternCase).getUniquePattern().asRecordPattern()
// We only consider patterns that declare any identifiers
exists(SwitchExpr se, RecordPatternExpr recordPattern | recordPattern = e2 |
e1 = se.getExpr() and
recordPattern = se.getACase().(PatternCase).getAPattern() and
recordPattern.declaresAnyIdentifiers()
)
or
exists(SwitchStmt ss |
e1 = ss.getExpr() and e2 = ss.getACase().(PatternCase).getUniquePattern().asRecordPattern()
exists(SwitchStmt ss, RecordPatternExpr recordPattern | recordPattern = e2 |
e1 = ss.getExpr() and
recordPattern = ss.getACase().(PatternCase).getAPattern() and
recordPattern.declaresAnyIdentifiers()
)
or
exists(InstanceOfExpr ioe | e1 = ioe.getExpr() and e2 = ioe.getPattern().asRecordPattern())