mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Swift: Adopt shared ConditionalCompletionSplitting implementation
This commit is contained in:
@@ -46,10 +46,6 @@ module CfgInput implements InputSig<Location> {
|
|||||||
|
|
||||||
CfgScope getCfgScope(AstNode n) { result = scopeOfAst(n.asAstNode()) }
|
CfgScope getCfgScope(AstNode n) { result = scopeOfAst(n.asAstNode()) }
|
||||||
|
|
||||||
class SplitKindBase = Splitting::TSplitKind;
|
|
||||||
|
|
||||||
class Split = Splitting::Split;
|
|
||||||
|
|
||||||
class SuccessorType = Cfg::SuccessorType;
|
class SuccessorType = Cfg::SuccessorType;
|
||||||
|
|
||||||
/** Gets a successor type that matches completion `c`. */
|
/** Gets a successor type that matches completion `c`. */
|
||||||
@@ -88,4 +84,19 @@ module CfgInput implements InputSig<Location> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module CfgImpl = Make<Location, CfgInput>;
|
private module CfgSplittingInput implements SplittingInputSig<Location, CfgInput> {
|
||||||
|
private import Splitting as S
|
||||||
|
|
||||||
|
class SplitKindBase = S::TSplitKind;
|
||||||
|
|
||||||
|
class Split = S::Split;
|
||||||
|
}
|
||||||
|
|
||||||
|
private module ConditionalCompletionSplittingInput implements
|
||||||
|
ConditionalCompletionSplittingInputSig<Location, CfgInput, CfgSplittingInput>
|
||||||
|
{
|
||||||
|
import Splitting::ConditionalCompletionSplitting::ConditionalCompletionSplittingInput
|
||||||
|
}
|
||||||
|
|
||||||
|
module CfgImpl =
|
||||||
|
MakeWithSplitting<Location, CfgInput, CfgSplittingInput, ConditionalCompletionSplittingInput>;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class Split extends TSplit {
|
|||||||
string toString() { none() }
|
string toString() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private module ConditionalCompletionSplitting {
|
module ConditionalCompletionSplitting {
|
||||||
/** A split for conditional completions. */
|
/** A split for conditional completions. */
|
||||||
class ConditionalCompletionSplit extends Split, TConditionalCompletionSplit {
|
class ConditionalCompletionSplit extends Split, TConditionalCompletionSplit {
|
||||||
ConditionalCompletion completion;
|
ConditionalCompletion completion;
|
||||||
@@ -38,7 +38,7 @@ private module ConditionalCompletionSplitting {
|
|||||||
override string toString() { result = completion.toString() }
|
override string toString() { result = completion.toString() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ConditionalCompletionSplitKind extends SplitKind, TConditionalCompletionSplitKind {
|
private class ConditionalCompletionSplitKind_ extends SplitKind, TConditionalCompletionSplitKind {
|
||||||
override int getListOrder() { result = 0 }
|
override int getListOrder() { result = 0 }
|
||||||
|
|
||||||
override predicate isEnabled(ControlFlowElement n) { this.appliesTo(n) }
|
override predicate isEnabled(ControlFlowElement n) { this.appliesTo(n) }
|
||||||
@@ -46,54 +46,44 @@ private module ConditionalCompletionSplitting {
|
|||||||
override string toString() { result = "ConditionalCompletion" }
|
override string toString() { result = "ConditionalCompletion" }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ConditionalCompletionSplitImpl extends SplitImpl instanceof ConditionalCompletionSplit
|
module ConditionalCompletionSplittingInput {
|
||||||
{
|
private import Completion as Comp
|
||||||
override ConditionalCompletionSplitKind getKind() { any() }
|
|
||||||
|
|
||||||
override predicate hasEntry(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
|
class ConditionalCompletion = Comp::ConditionalCompletion;
|
||||||
succ(pred, succ, c) and
|
|
||||||
last(succ, _, super.getCompletion()) and
|
class ConditionalCompletionSplitKind extends ConditionalCompletionSplitKind_, TSplitKind { }
|
||||||
|
|
||||||
|
class ConditionalCompletionSplit = ConditionalCompletionSplitting::ConditionalCompletionSplit;
|
||||||
|
|
||||||
|
bindingset[parent, parentCompletion]
|
||||||
|
private predicate condPropagateAstExpr(
|
||||||
|
AstNode parent, ConditionalCompletion parentCompletion, AstNode child,
|
||||||
|
ConditionalCompletion childCompletion
|
||||||
|
) {
|
||||||
|
child = parent.(NotExpr).getOperand().getFullyConverted() and
|
||||||
|
childCompletion.(BooleanCompletion).getDual() = parentCompletion
|
||||||
|
or
|
||||||
|
childCompletion = parentCompletion and
|
||||||
(
|
(
|
||||||
astLast(succ.asAstNode().(NotExpr).getOperand().getFullyConverted(), pred, c) and
|
child = parent.(LogicalAndExpr).getAnOperand().getFullyConverted()
|
||||||
super.getCompletion().(BooleanCompletion).getDual() = c
|
|
||||||
or
|
or
|
||||||
astLast(succ.asAstNode().(LogicalAndExpr).getAnOperand().getFullyConverted(), pred, c) and
|
child = parent.(LogicalOrExpr).getAnOperand().getFullyConverted()
|
||||||
super.getCompletion() = c
|
|
||||||
or
|
or
|
||||||
astLast(succ.asAstNode().(LogicalOrExpr).getAnOperand().getFullyConverted(), pred, c) and
|
child = parent.(IfExpr).getBranch(_).getFullyConverted()
|
||||||
super.getCompletion() = c
|
|
||||||
or
|
or
|
||||||
succ.asAstNode() =
|
exists(Exprs::Conversions::ConversionOrIdentityTree conv |
|
||||||
any(IfExpr ce |
|
parent = conv.getAst() and
|
||||||
astLast(ce.getBranch(_).getFullyConverted(), pred, c) and
|
conv.convertsFrom(child)
|
||||||
super.getCompletion() = c
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(Expr e, Exprs::Conversions::ConversionOrIdentityTree conv |
|
|
||||||
succ.asAstNode() = conv.getAst() and
|
|
||||||
conv.convertsFrom(e) and
|
|
||||||
astLast(e, pred, c) and
|
|
||||||
super.getCompletion() = c
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate hasEntryScope(CfgInput::CfgScope scope, ControlFlowElement succ) { none() }
|
bindingset[parent, parentCompletion]
|
||||||
|
predicate condPropagateExpr(
|
||||||
override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
|
ControlFlowElement parent, ConditionalCompletion parentCompletion, ControlFlowElement child,
|
||||||
this.appliesTo(pred) and
|
ConditionalCompletion childCompletion
|
||||||
succ(pred, succ, c) and
|
) {
|
||||||
if c instanceof ConditionalCompletion then super.getCompletion() = c else any()
|
condPropagateAstExpr(parent.asAstNode(), parentCompletion, child.asAstNode(), childCompletion)
|
||||||
}
|
|
||||||
|
|
||||||
override predicate hasExitScope(CfgInput::CfgScope scope, ControlFlowElement last, Completion c) {
|
|
||||||
this.appliesTo(last) and
|
|
||||||
succExit(scope, last, c) and
|
|
||||||
if c instanceof ConditionalCompletion then super.getCompletion() = c else any()
|
|
||||||
}
|
|
||||||
|
|
||||||
override predicate hasSuccessor(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
|
|
||||||
none()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user