@@ -272,3 +272,104 @@ private module ParameterSynth {
272
272
}
273
273
}
274
274
}
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