4747import io .ballerina .compiler .syntax .tree .FunctionCallExpressionNode ;
4848import io .ballerina .compiler .syntax .tree .ImplicitNewExpressionNode ;
4949import io .ballerina .compiler .syntax .tree .IntermediateClauseNode ;
50+ import io .ballerina .compiler .syntax .tree .LetExpressionNode ;
51+ import io .ballerina .compiler .syntax .tree .LetVariableDeclarationNode ;
5052import io .ballerina .compiler .syntax .tree .ListConstructorExpressionNode ;
5153import io .ballerina .compiler .syntax .tree .MappingConstructorExpressionNode ;
5254import io .ballerina .compiler .syntax .tree .MappingFieldNode ;
@@ -193,10 +195,17 @@ public JsonElement getMappings(JsonElement node, LinePosition position, String p
193195 return null ;
194196 }
195197
196- Type type ;
198+ Type type = Type .fromSemanticSymbol (targetNode .typeSymbol ());
199+ String name = targetNode .name ();
200+ MappingPort outputPort = getMappingPort (name , name , type );
197201 ExpressionNode expressionNode = targetNode .expressionNode ();
202+ if (expressionNode == null ) {
203+ return gson .toJsonTree (new Model (inputPorts , outputPort , new ArrayList <>(), null ));
204+ }
205+
198206 Query query = null ;
199- if (expressionNode != null && targetNode .expressionNode ().kind () == SyntaxKind .QUERY_EXPRESSION ) {
207+ List <MappingPort > subMappingPorts = null ;
208+ if (expressionNode .kind () == SyntaxKind .QUERY_EXPRESSION ) {
200209 QueryExpressionNode queryExpressionNode = (QueryExpressionNode ) targetNode .expressionNode ();
201210 FromClauseNode fromClauseNode = queryExpressionNode .queryPipeline ().fromClause ();
202211 List <String > inputs = new ArrayList <>();
@@ -221,20 +230,29 @@ public JsonElement getMappings(JsonElement node, LinePosition position, String p
221230 }
222231 query = new Query (targetField , inputs , fromClause ,
223232 getQueryIntermediateClause (queryExpressionNode .queryPipeline ()), resultClause );
233+ } else if (expressionNode .kind () == SyntaxKind .LET_EXPRESSION ) {
234+ LetExpressionNode letExpressionNode = (LetExpressionNode ) expressionNode ;
235+ subMappingPorts = new ArrayList <>();
236+ for (LetVariableDeclarationNode letVarDeclaration : letExpressionNode .letVarDeclarations ()) {
237+ Optional <Symbol > optSymbol = newSemanticModel .symbol (letVarDeclaration );
238+ if (optSymbol .isEmpty ()) {
239+ continue ;
240+ }
241+ Symbol symbol = optSymbol .get ();
242+ String letVarName = symbol .getName ().orElseThrow ();
243+ subMappingPorts .add (getMappingPort (letVarName , letVarName , Type .fromSemanticSymbol (symbol )));
244+ }
224245 }
225- type = Type .fromSemanticSymbol (targetNode .typeSymbol ());
226- String name = targetNode .name ();
227- MappingPort outputPort = getMappingPort (name , name , type );
246+
228247 List <Mapping > mappings = new ArrayList <>();
229- if (expressionNode != null ) {
230- TypeDescKind typeDescKind = CommonUtils .getRawType (targetNode .typeSymbol ()).typeKind ();
231- if (typeDescKind == TypeDescKind .RECORD ) {
232- generateRecordVariableDataMapping (expressionNode , mappings , name , newSemanticModel );
233- } else if (typeDescKind == TypeDescKind .ARRAY ) {
234- generateArrayVariableDataMapping (expressionNode , mappings , name , newSemanticModel );
235- }
248+ TypeDescKind typeDescKind = CommonUtils .getRawType (targetNode .typeSymbol ()).typeKind ();
249+ if (typeDescKind == TypeDescKind .RECORD ) {
250+ generateRecordVariableDataMapping (expressionNode , mappings , name , newSemanticModel );
251+ } else if (typeDescKind == TypeDescKind .ARRAY ) {
252+ generateArrayVariableDataMapping (expressionNode , mappings , name , newSemanticModel );
236253 }
237- return gson .toJsonTree (new Model (inputPorts , outputPort , mappings , query ));
254+
255+ return gson .toJsonTree (new Model (inputPorts , outputPort , subMappingPorts , mappings , query ));
238256 }
239257
240258 private TargetNode getTargetNode (Node parentNode , String targetField , NodeKind nodeKind , String propertyKey ,
@@ -1275,14 +1293,19 @@ private List<IntermediateClause> getQueryIntermediateClause(QueryPipelineNode qu
12751293 return intermediateClauses ;
12761294 }
12771295
1278- private record Model (List <MappingPort > inputs , MappingPort output , List <Mapping > mappings , Query query ) {
1296+ private record Model (List <MappingPort > inputs , MappingPort output , List <MappingPort > subMappings ,
1297+ List <Mapping > mappings , Query query ) {
12791298
12801299 private Model (List <MappingPort > inputs , MappingPort output , List <Mapping > mappings ) {
1281- this (inputs , output , mappings , null );
1300+ this (inputs , output , null , mappings , null );
12821301 }
12831302
12841303 private Model (List <MappingPort > inputs , MappingPort output , Query query ) {
1285- this (inputs , output , new ArrayList <>(), query );
1304+ this (inputs , output , null , new ArrayList <>(), query );
1305+ }
1306+
1307+ private Model (List <MappingPort > inputs , MappingPort output , List <Mapping > mappings , Query query ) {
1308+ this (inputs , output , null , mappings , query );
12861309 }
12871310 }
12881311
0 commit comments