Skip to content

Commit 8eb5e65

Browse files
committed
PS: Synthesize Function and Type classes instead of relying on the statement that defines them.
1 parent 1766134 commit 8eb5e65

File tree

1 file changed

+86
-0
lines changed
  • powershell/ql/lib/semmle/code/powershell/ast/internal

1 file changed

+86
-0
lines changed

powershell/ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,89 @@ private module ExprToStmtSynth {
373373
}
374374
}
375375
}
376+
377+
predicate excludeFunctionDefinitionStmt(Raw::FunctionDefinitionStmt f) {
378+
// We don't care about function definition statements which define methods
379+
// because they live inside a type anyway (and we don't have control-flow
380+
// inside a type).
381+
parent(f, any(Raw::Method m))
382+
}
383+
384+
/**
385+
* Synthesize function "declarations" from function definitions statements.
386+
*/
387+
private module FunctionSynth {
388+
private class FunctionSynth extends Synthesis {
389+
override predicate child(Raw::Ast parent, ChildIndex i, Child child) {
390+
i = funDefFun() and
391+
child = SynthChild(FunctionSynthKind()) and
392+
exists(Raw::FunctionDefinitionStmt fundefStmt |
393+
if excludeFunctionDefinitionStmt(fundefStmt)
394+
then parent(fundefStmt, parent)
395+
else parent = fundefStmt
396+
)
397+
}
398+
399+
override predicate functionName(FunctionBase f, string name) {
400+
exists(Raw::FunctionDefinitionStmt fundefStmt |
401+
f = TFunctionSynth(fundefStmt, _) and
402+
fundefStmt.getName() = name
403+
)
404+
or
405+
exists(Raw::TopLevelScriptBlock topLevelScriptBlock |
406+
f = TTopLevelFunction(topLevelScriptBlock) and
407+
name = "toplevel function for " + topLevelScriptBlock.getLocation().getFile().getBaseName()
408+
)
409+
}
410+
411+
override predicate functionScriptBlock(FunctionBase f, ScriptBlock block) {
412+
exists(Raw::FunctionDefinitionStmt fundefStmt |
413+
f = TFunctionSynth(fundefStmt, _) and
414+
getResultAst(fundefStmt.getBody()) = block
415+
)
416+
or
417+
exists(Raw::TopLevelScriptBlock topLevelScriptBlock |
418+
block = getResultAst(topLevelScriptBlock) and
419+
f = TTopLevelFunction(topLevelScriptBlock)
420+
)
421+
}
422+
423+
override Location getLocation(Ast n) {
424+
exists(Raw::FunctionDefinitionStmt fundefStmt |
425+
n = TFunctionSynth(fundefStmt, _) and
426+
result = fundefStmt.getLocation()
427+
)
428+
}
429+
}
430+
}
431+
432+
private module TypeSynth {
433+
private class TypeSynth extends Synthesis {
434+
override predicate child(Raw::Ast parent, ChildIndex i, Child child) {
435+
parent instanceof Raw::TypeStmt and
436+
i = typeDefType() and
437+
child = SynthChild(TypeSynthKind())
438+
}
439+
440+
final override predicate typeMember(Type t, int i, Member m) {
441+
exists(Raw::TypeStmt typeStmt |
442+
t = TTypeSynth(typeStmt, _) and
443+
m = getResultAst(typeStmt.getMember(i))
444+
)
445+
}
446+
447+
override predicate typeName(Type t, string name) {
448+
exists(Raw::TypeStmt typeStmt |
449+
t = TTypeSynth(typeStmt, _) and
450+
typeStmt.getName() = name
451+
)
452+
}
453+
454+
override Location getLocation(Ast n) {
455+
exists(Raw::TypeStmt typeStmt |
456+
n = TTypeSynth(typeStmt, _) and
457+
result = typeStmt.getLocation()
458+
)
459+
}
460+
}
461+
}

0 commit comments

Comments
 (0)