Skip to content

Commit c69d70a

Browse files
committed
PS: Add CFG test skeleton.
1 parent d29cb30 commit c69d70a

File tree

7 files changed

+39
-27
lines changed

7 files changed

+39
-27
lines changed

powershell/ql/lib/semmle/code/powershell/controlflow/ControlFlowGraph.qll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ private import internal.Scope
1616
* Note that module declarations are not themselves CFG scopes, as they are part of
1717
* the CFG of the enclosing top-level or callable.
1818
*/
19-
class CfgScope extends Scope instanceof CfgImpl::CfgScopeImpl {
20-
/** Gets the CFG scope that this scope is nested under, if any. */
21-
final CfgScope getOuterCfgScope() { none() }
22-
}
19+
class CfgScope extends Scope instanceof CfgImpl::CfgScope { }
2320

2421
/**
2522
* A control flow node.

powershell/ql/lib/semmle/code/powershell/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ private module CfgInput implements CfgShared::InputSig<Location> {
2828

2929
CfgScope getCfgScope(Ast n) { result = Impl::getCfgScope(n) }
3030

31-
predicate scopeFirst(CfgScope scope, Ast first) { scope.(Impl::CfgScopeImpl).entry(first) }
31+
predicate scopeFirst(CfgScope scope, Ast first) { scope.(Impl::CfgScope).entry(first) }
3232

3333
predicate scopeLast(CfgScope scope, Ast last, Completion c) {
34-
scope.(Impl::CfgScopeImpl).exit(last, c)
34+
scope.(Impl::CfgScope).exit(last, c)
3535
}
3636

3737
class SplitKindBase = Splitting::TSplitKind;
@@ -56,32 +56,32 @@ private module CfgInput implements CfgShared::InputSig<Location> {
5656
}
5757
}
5858

59+
private import CfgInput
5960
import CfgShared::Make<Location, CfgInput>
6061

61-
abstract class CfgScopeImpl extends Ast {
62-
abstract predicate entry(Ast first);
62+
class CfgScope extends Scope {
63+
predicate entry(Ast first) { first(this, first) }
6364

64-
abstract predicate exit(Ast last, Completion c);
65+
predicate exit(Ast last, Completion c) { last(this, last, c) }
6566
}
6667

6768
/** Holds if `first` is first executed when entering `scope`. */
6869
pragma[nomagic]
69-
predicate succEntry(CfgScopeImpl scope, Ast first) { scope.entry(first) }
70+
predicate succEntry(CfgScope scope, Ast first) { scope.entry(first) }
7071

7172
/** Holds if `last` with completion `c` can exit `scope`. */
7273
pragma[nomagic]
73-
predicate succExit(CfgScopeImpl scope, Ast last, Completion c) { scope.exit(last, c) }
74+
predicate succExit(CfgScope scope, Ast last, Completion c) { scope.exit(last, c) }
7475

7576
/** Defines the CFG by dispatch on the various AST types. */
7677
module Trees {
7778
// TODO
7879
}
7980

81+
private import Scope
82+
8083
cached
81-
private CfgScope getCfgScopeImpl(Ast n) {
82-
// TODO
83-
none()
84-
}
84+
private CfgScope getCfgScopeImpl(Ast n) { result = scopeOf(n) }
8585

8686
/** Gets the CFG scope of node `n`. */
8787
pragma[inline]
Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
private import powershell
22
private import ControlFlowGraphImpl
33

4-
class TScopeType = @function_definition; // TODO: top-level definitions (including a single top-level scope)
5-
6-
abstract class ScopeImpl extends Ast, TScopeType {
7-
final Scope getOuterScopeImpl() {
8-
none() // TODO
9-
}
4+
/** Gets the enclosing scope of `n`. */
5+
Scope scopeOf(Ast n) {
6+
exists(Ast m | m = n.getParent() |
7+
m = result
8+
or
9+
not m instanceof Scope and result = scopeOf(m)
10+
)
1011
}
1112

1213
/**
1314
* A variable scope. This is either a top-level (file), a module, a class,
1415
* or a callable.
1516
*/
16-
class Scope extends Ast instanceof ScopeImpl {
17+
class Scope extends Ast, @script_block {
1718
/** Gets the outer scope, if any. */
18-
Scope getOuterScope() { result = super.getOuterScopeImpl() }
19+
Scope getOuterScope() { result = scopeOf(this) }
1920
}

powershell/ql/lib/semmle/code/powershell/controlflow/internal/Splitting.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
private import powershell
66
private import Completion
77
private import ControlFlowGraphImpl
8-
private import SuccessorTypes
9-
private import semmle.code.powershell.controlflow.ControlFlowGraph
8+
private import Cfg::SuccessorTypes
9+
private import semmle.code.powershell.controlflow.ControlFlowGraph as Cfg
1010

1111
cached
1212
private module Cached {
@@ -63,15 +63,15 @@ private module ConditionalCompletionSplitting {
6363
none() // TODO
6464
}
6565

66-
override predicate hasEntryScope(CfgScope scope, Ast succ) { none() }
66+
override predicate hasEntryScope(Cfg::CfgScope scope, Ast succ) { none() }
6767

6868
override predicate hasExit(Ast pred, Ast succ, Completion c) {
6969
this.appliesTo(pred) and
7070
succ(pred, succ, c) and
7171
if c instanceof ConditionalCompletion then completion = c else any()
7272
}
7373

74-
override predicate hasExitScope(CfgScope scope, Ast last, Completion c) {
74+
override predicate hasExitScope(Cfg::CfgScope scope, Ast last, Completion c) {
7575
this.appliesTo(last) and
7676
succExit(scope, last, c) and
7777
if c instanceof ConditionalCompletion then completion = c else any()

powershell/ql/test/library-tests/controlflow/graph/Cfg.expected

Whitespace-only changes.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @kind graph
3+
*/
4+
5+
import semmle.code.powershell.Cfg
6+
7+
class TestRelevantNode extends CfgNode {
8+
string getOrderDisambiguation() { result = "" }
9+
}
10+
11+
import semmle.code.powershell.controlflow.internal.ControlFlowGraphImpl::TestOutput<TestRelevantNode>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
$a = 1
2+
$b = 2
3+
$c = $a + $b

0 commit comments

Comments
 (0)