Skip to content

Commit 0b4a7f9

Browse files
committed
PS: Synthesize a simpler notion of parameters.
1 parent 5bc0a26 commit 0b4a7f9

File tree

1 file changed

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

1 file changed

+121
-0
lines changed

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

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,124 @@ private module SetVariableAssignment {
151151
}
152152
}
153153
}
154+
155+
/**
156+
* Syntesize parameters from parameter blocks and function definitions
157+
* so that they have a uniform API.
158+
*/
159+
private module ParameterSynth {
160+
private class ParameterSynth extends Synthesis {
161+
final override predicate isRelevant(Raw::Ast a) { a = any(Scope::Range r).getAParameter() }
162+
163+
private predicate parameter(
164+
Raw::Ast parent, ChildIndex i, Raw::Parameter p, Child child, boolean isPipelineParameter
165+
) {
166+
exists(Scope::Range r, int index |
167+
p = r.getParameter(index) and
168+
parent = r and
169+
i = funParam(index) and
170+
child = SynthChild(VarSynthKind(ParamVarRealKind())) and
171+
if p instanceof Raw::PipelineParameter
172+
then isPipelineParameter = true
173+
else isPipelineParameter = false
174+
)
175+
}
176+
177+
final override predicate isPipelineParameter(Parameter p) {
178+
exists(Raw::Ast parent, ChildIndex i |
179+
parent = getRawAst(p.getFunction().getBody()) and
180+
this.isPipelineParameterChild(parent, _, i) and
181+
p = TVariableSynth(parent, i)
182+
)
183+
}
184+
185+
override predicate implicitAssignment(Raw::Ast dest, string name) {
186+
exists(Raw::Parameter p |
187+
dest = p and
188+
name = p.getName()
189+
)
190+
}
191+
192+
final override predicate variableSynthName(VariableSynth v, string name) {
193+
exists(Raw::Ast parent, int i, Raw::Parameter p |
194+
this.parameter(parent, FunParam(i), p, _, false) and
195+
v = TVariableSynth(parent, FunParam(i)) and
196+
name = p.getName()
197+
)
198+
or
199+
exists(Raw::Ast parent |
200+
this.child(parent, PipelineParamVar(), _) and
201+
v = TVariableSynth(parent, PipelineParamVar()) and
202+
name = "[synth] pipeline"
203+
)
204+
}
205+
206+
private predicate isPipelineParameterChild(Raw::Ast parent, int index, ChildIndex i) {
207+
exists(Scope::Range r | parent = r and i = PipelineParamVar() |
208+
r.getParameter(index) instanceof Raw::PipelineParameter
209+
or
210+
not r.getAParameter() instanceof Raw::PipelineParameter and
211+
index = synthPipelineParameterChildIndex(r)
212+
)
213+
}
214+
215+
final override predicate pipelineParameterHasIndex(ScriptBlock s, int i) {
216+
exists(Raw::ScriptBlock scriptBlock |
217+
s = TScriptBlock(scriptBlock) and
218+
this.isPipelineParameterChild(scriptBlock, i, _)
219+
)
220+
}
221+
222+
final override predicate child(Raw::Ast parent, ChildIndex i, Child child) {
223+
// Synthesize parameters
224+
this.parameter(parent, i, _, child, false)
225+
or
226+
// Synthesize pipeline parameter
227+
child = SynthChild(VarSynthKind(ParamVarPipelineKind())) and
228+
this.isPipelineParameterChild(parent, _, i)
229+
or
230+
// Synthesize default values
231+
exists(Raw::Parameter q |
232+
parent = q and
233+
this.parameter(_, _, q, _, _)
234+
|
235+
i = paramDefaultVal() and
236+
child = childRef(getResultAst(q.getDefaultValue()))
237+
or
238+
exists(int index |
239+
i = paramAttr(index) and
240+
child = childRef(getResultAst(q.getAttribute(index)))
241+
)
242+
)
243+
}
244+
245+
final override Parameter getResultAstImpl(Raw::Ast r) {
246+
exists(Raw::Ast parent, int i |
247+
this.parameter(parent, FunParam(i), r, _, false) and
248+
result = TVariableSynth(parent, FunParam(i))
249+
)
250+
or
251+
exists(Scope::Range scope, int i, ChildIndex index |
252+
scope.getParameter(i) = r and
253+
this.isPipelineParameterChild(scope, i, index) and
254+
result = TVariableSynth(scope, index)
255+
)
256+
}
257+
258+
final override Location getLocation(Ast n) {
259+
exists(Raw::Ast parent, Raw::Parameter p, int i |
260+
this.parameter(parent, _, p, _, _) and
261+
n = TVariableSynth(parent, FunParam(i)) and
262+
result = p.getLocation()
263+
)
264+
}
265+
266+
final override predicate parameterStaticType(Parameter n, string type) {
267+
exists(Raw::Ast parent, int i, Raw::Parameter p |
268+
this.parameter(parent, FunParam(i), p, _, false) and
269+
n = TVariableSynth(parent, FunParam(i)) and
270+
type = p.getStaticType()
271+
)
272+
}
273+
}
274+
}

0 commit comments

Comments
 (0)