@@ -49,7 +49,8 @@ public BexCompiledProgram compile(blue.bex.api.BexProgramSource source) {
4949 compiledFunctions .put (name , compileFunction (name , functionNodes .get (name )));
5050 }
5151
52- String entryName = source .entry ().orElse (text (prop (step , "entry" )));
52+ FrozenNode stepExpr = meaningful (prop (step , "expr" ));
53+ String entryName = source .entry ().orElse (text (meaningful (prop (step , "entry" ))));
5354 BexCompiledProgram .CompiledFunction root ;
5455 int rootFrameSize = 0 ;
5556 if (entryName != null && !entryName .isEmpty ()) {
@@ -62,14 +63,14 @@ public BexCompiledProgram compile(blue.bex.api.BexProgramSource source) {
6263 new ReturnStatement (sourceExpr ("$root" , "/entry/$call" , "$call" ,
6364 new CallExpr (entryName , new String [0 ], new CompiledExpression [0 ]))))),
6465 null , 0 );
65- } else if (prop ( step , "expr" ) != null ) {
66+ } else if (stepExpr != null ) {
6667 currentFunction = "$root" ;
6768 root = new BexCompiledProgram .CompiledFunction ("$root" , Collections .<String >emptyList (),
68- Collections .<CompiledStatement >emptyList (), compileExpr (prop ( step , "expr" ) , new CompileScope (), "/expr" ), 0 );
69+ Collections .<CompiledStatement >emptyList (), compileExpr (stepExpr , new CompileScope (), "/expr" ), 0 );
6970 } else {
7071 CompileScope scope = new CompileScope ();
7172 currentFunction = "$root" ;
72- List <CompiledStatement > statements = compileStatements (prop (step , "do" ), scope , "/do" );
73+ List <CompiledStatement > statements = compileStatements (meaningful ( prop (step , "do" ) ), scope , "/do" );
7374 rootFrameSize = scope .frameSize ();
7475 root = new BexCompiledProgram .CompiledFunction ("$root" , Collections .<String >emptyList (), statements , null , rootFrameSize );
7576 }
@@ -90,9 +91,10 @@ private BexCompiledProgram.CompiledFunction compileFunction(String name, FrozenN
9091 scope .declareOrGetSlot (arg );
9192 }
9293 }
93- CompiledExpression expression = prop (functionNode , "expr" ) != null ? compileExpr (prop (functionNode , "expr" ), scope , "/functions/" + escape (name ) + "/expr" ) : null ;
94+ FrozenNode functionExpr = meaningful (prop (functionNode , "expr" ));
95+ CompiledExpression expression = functionExpr != null ? compileExpr (functionExpr , scope , "/functions/" + escape (name ) + "/expr" ) : null ;
9496 List <CompiledStatement > statements = expression == null
95- ? compileStatements (prop (functionNode , "do" ), scope , "/functions/" + escape (name ) + "/do" )
97+ ? compileStatements (meaningful ( prop (functionNode , "do" ) ), scope , "/functions/" + escape (name ) + "/do" )
9698 : Collections .<CompiledStatement >emptyList ();
9799 currentFunction = previousFunction ;
98100 return new BexCompiledProgram .CompiledFunction (name , Collections .unmodifiableList (args ),
@@ -467,6 +469,16 @@ private FrozenNode prop(FrozenNode node, String key) {
467469 return null ;
468470 }
469471
472+ private FrozenNode meaningful (FrozenNode node ) {
473+ if (node == null ) {
474+ return null ;
475+ }
476+ boolean hasPayload = node .getValue () != null
477+ || (node .getItems () != null && !node .getItems ().isEmpty ())
478+ || (node .getProperties () != null && !node .getProperties ().isEmpty ());
479+ return hasPayload ? node : null ;
480+ }
481+
470482 private FrozenNode required (FrozenNode node , String label ) {
471483 if (node == null ) {
472484 throw new BexException ("Missing required field: " + label );
0 commit comments