@@ -272,3 +272,104 @@ private module ParameterSynth {
272272 }
273273 }
274274}
275+
276+ /**
277+ * Holds if `child` is a child of `n` that is a `Stmt` in the raw AST, but should
278+ * be mapped to an `Expr` in the synthesized AST.
279+ */
280+ private predicate mustHaveExprChild ( Raw:: Ast n , Raw:: Stmt child ) {
281+ n .( Raw:: AssignStmt ) .getRightHandSide ( ) = child
282+ or
283+ n .( Raw:: Pipeline ) .getAComponent ( ) = child
284+ or
285+ n .( Raw:: ReturnStmt ) .getPipeline ( ) = child
286+ or
287+ n .( Raw:: HashTableExpr ) .getAStmt ( ) = child
288+ or
289+ n .( Raw:: ParenExpr ) .getBase ( ) = child
290+ or
291+ n .( Raw:: DoUntilStmt ) .getCondition ( ) = child
292+ or
293+ n .( Raw:: DoWhileStmt ) .getCondition ( ) = child
294+ or
295+ n .( Raw:: ExitStmt ) .getPipeline ( ) = child
296+ or
297+ n .( Raw:: ForEachStmt ) .getIterableExpr ( ) = child
298+ or
299+ // TODO: What to do about initializer and iterator?
300+ exists ( Raw:: ForStmt for | n = for | for .getCondition ( ) = child )
301+ or
302+ n .( Raw:: IfStmt ) .getACondition ( ) = child
303+ or
304+ n .( Raw:: SwitchStmt ) .getCondition ( ) = child
305+ or
306+ n .( Raw:: ThrowStmt ) .getPipeline ( ) = child
307+ or
308+ n .( Raw:: WhileStmt ) .getCondition ( ) = child
309+ }
310+
311+ private class RawStmtThatShouldBeExpr extends Raw:: Stmt {
312+ RawStmtThatShouldBeExpr ( ) {
313+ this instanceof Raw:: Cmd or
314+ this instanceof Raw:: Pipeline or
315+ this instanceof Raw:: PipelineChain or
316+ this instanceof Raw:: IfStmt
317+ }
318+
319+ Expr getExpr ( ) {
320+ result = TCmd ( this )
321+ or
322+ result = TPipeline ( this )
323+ or
324+ result = TPipelineChain ( this )
325+ or
326+ result = TIf ( this )
327+ }
328+ }
329+
330+ /**
331+ * Insert expr-to-stmt conversions where needed.
332+ */
333+ private module ExprToStmtSynth {
334+ private class ExprToStmtSynth extends Synthesis {
335+ private predicate exprToSynthStmtChild ( Raw:: Ast parent , ChildIndex i , Raw:: Stmt stmt , Expr e ) {
336+ this .child ( parent , i , SynthChild ( ExprStmtKind ( ) ) , stmt ) and
337+ e = stmt .( RawStmtThatShouldBeExpr ) .getExpr ( )
338+ }
339+
340+ private predicate child ( Raw:: Ast parent , ChildIndex i , Child child , Raw:: Stmt stmt ) {
341+ // Synthesize the expr-to-stmt conversion
342+ child = SynthChild ( ExprStmtKind ( ) ) and
343+ stmt instanceof RawStmtThatShouldBeExpr and
344+ parent .getChild ( toRawChildIndex ( i ) ) = stmt and
345+ not mustHaveExprChild ( parent , stmt )
346+ }
347+
348+ final override predicate child ( Raw:: Ast parent , ChildIndex i , Child child ) {
349+ this .child ( parent , i , child , _)
350+ }
351+
352+ final override predicate exprStmtExpr ( ExprStmt e , Expr expr ) {
353+ exists ( Raw:: Ast parent , ChildIndex i , Raw:: Stmt stmt |
354+ e = TExprStmtSynth ( parent , i ) and
355+ this .exprToSynthStmtChild ( parent , i , stmt , expr )
356+ )
357+ }
358+
359+ final override Location getLocation ( Ast n ) {
360+ exists ( Raw:: Ast parent , ChildIndex i , Raw:: Stmt stmt |
361+ n = TExprStmtSynth ( parent , i ) and
362+ this .exprToSynthStmtChild ( parent , i , stmt , _) and
363+ result = stmt .getLocation ( )
364+ )
365+ }
366+
367+ final override string toString ( Ast n ) {
368+ exists ( Raw:: Ast parent , ChildIndex i , Raw:: Stmt stmt |
369+ n = TExprStmtSynth ( parent , i ) and
370+ this .exprToSynthStmtChild ( parent , i , stmt , _) and
371+ result = stmt .toString ( )
372+ )
373+ }
374+ }
375+ }
0 commit comments