From c6b60bf170cffab0d7afe4641366f206d725e838 Mon Sep 17 00:00:00 2001 From: KavinduZoysa Date: Thu, 5 Feb 2026 21:59:22 +0530 Subject: [PATCH] Generate data mapper creation node in correct file --- .../core/model/SourceBuilder.java | 4 +- .../model/node/DataMapperCreationBuilder.java | 63 ++++++++++--------- .../model/node/FunctionCreationBuilder.java | 7 +++ .../source/data_mapper/functions.bal | 0 4 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 flow-model-generator/modules/flow-model-generator-ls-extension/src/test/resources/to_source/source/data_mapper/functions.bal diff --git a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java index 57e1f2d8af..5bb9e03b07 100644 --- a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java +++ b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/SourceBuilder.java @@ -122,8 +122,8 @@ private Path resolvePath(Path inputPath, NodeKind node, LineRange lineRange, Boo String defaultFile = switch (node) { case NEW_CONNECTION, MODEL_PROVIDER, EMBEDDING_PROVIDER, VECTOR_STORE, KNOWLEDGE_BASE, DATA_LOADER, CHUNKER, CLASS_INIT -> CONNECTIONS_BAL; - case DATA_MAPPER_DEFINITION, DATA_MAPPER_CREATION -> DATA_MAPPINGS_BAL; - case FUNCTION_DEFINITION, NP_FUNCTION, NP_FUNCTION_DEFINITION, FUNCTION_CREATION -> FUNCTIONS_BAL; + case DATA_MAPPER_DEFINITION -> DATA_MAPPINGS_BAL; + case FUNCTION_DEFINITION, NP_FUNCTION, NP_FUNCTION_DEFINITION -> FUNCTIONS_BAL; case AUTOMATION -> AUTOMATION_BAL; case AGENT, MEMORY, MEMORY_STORE, MCP_TOOL_KIT -> AGENTS_BAL; default -> null; diff --git a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/node/DataMapperCreationBuilder.java b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/node/DataMapperCreationBuilder.java index 881008b0bf..e46bb896e7 100644 --- a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/node/DataMapperCreationBuilder.java +++ b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/node/DataMapperCreationBuilder.java @@ -20,8 +20,6 @@ import com.google.gson.Gson; import io.ballerina.compiler.syntax.tree.SyntaxKind; -import io.ballerina.flowmodelgenerator.core.model.Codedata; -import io.ballerina.flowmodelgenerator.core.model.FlowNode; import io.ballerina.flowmodelgenerator.core.model.FormBuilder; import io.ballerina.flowmodelgenerator.core.model.NodeBuilder; import io.ballerina.flowmodelgenerator.core.model.NodeKind; @@ -29,6 +27,7 @@ import io.ballerina.flowmodelgenerator.core.model.SourceBuilder; import io.ballerina.flowmodelgenerator.core.utils.FileSystemUtils; import io.ballerina.modelgenerator.commons.CommonUtils; +import io.ballerina.projects.Document; import org.ballerinalang.model.types.TypeKind; import org.eclipse.lsp4j.TextEdit; @@ -63,6 +62,8 @@ public class DataMapperCreationBuilder extends NodeBuilder { public static final String RETURN_TYPE = TypeKind.ANYDATA.typeName(); public static final String PARAMETER_TYPE = TypeKind.ANYDATA.typeName(); + private static final String DATA_MAPPER_DEFINITION_FILE = "data_mappings.bal"; + protected String getNameLabel() { return DATA_MAPPER_NAME_LABEL; } @@ -79,6 +80,10 @@ protected String getParametersDoc() { return PARAMETERS_DOC; } + protected String getNodeDefinitionFile() { + return DATA_MAPPER_DEFINITION_FILE; + } + @Override public void setConcreteConstData() { metadata().label(LABEL).description(DESCRIPTION); @@ -139,8 +144,8 @@ public void setOptionalProperties(NodeBuilder nodeBuilder) { @Override public Map> toSource(SourceBuilder sourceBuilder) { - Map> definition = createDefinition(sourceBuilder); Map> invocation = createInvocation(sourceBuilder); + Map> definition = createDefinition(sourceBuilder); Map> combined = new HashMap<>(definition); combined.putAll(invocation); @@ -148,17 +153,21 @@ public Map> toSource(SourceBuilder sourceBuilder) { } private Map> createDefinition(SourceBuilder sourceBuilder) { - sourceBuilder.token().keyword(SyntaxKind.FUNCTION_KEYWORD); + Path rootPath = sourceBuilder.workspaceManager.projectRoot(sourceBuilder.filePath); + Path nodeDefinitionPath = rootPath.resolve(getNodeDefinitionFile()); + SourceBuilder definitionBuilder = + new SourceBuilder(sourceBuilder.flowNode, sourceBuilder.workspaceManager, nodeDefinitionPath); + definitionBuilder.token().keyword(SyntaxKind.FUNCTION_KEYWORD); - Optional property = sourceBuilder.getProperty(Property.FUNCTION_NAME_KEY); + Optional property = definitionBuilder.getProperty(Property.FUNCTION_NAME_KEY); if (property.isEmpty()) { throw new IllegalStateException("Data mapper name is not present"); } - sourceBuilder.token() + definitionBuilder.token() .name(property.get().value().toString()) .keyword(SyntaxKind.OPEN_PAREN_TOKEN); - Optional parameters = sourceBuilder.getProperty(Property.PARAMETERS_KEY); + Optional parameters = definitionBuilder.getProperty(Property.PARAMETERS_KEY); if (parameters.isPresent() && parameters.get().value() instanceof Map paramMap) { List paramList = new ArrayList<>(); for (Map.Entry entry : paramMap.entrySet()) { @@ -171,29 +180,31 @@ private Map> createDefinition(SourceBuilder sourceBuilder) FormBuilder.NODE_PROPERTIES_TYPE); paramList.add(paramProperties.get(Property.TYPE_KEY).value().toString() + " " + entry.getKey()); } - sourceBuilder.token().name(String.join(", ", paramList)); + definitionBuilder.token().name(String.join(", ", paramList)); } - sourceBuilder.token().keyword(SyntaxKind.CLOSE_PAREN_TOKEN); + definitionBuilder.token().keyword(SyntaxKind.CLOSE_PAREN_TOKEN); // Write the return type - Optional returnType = sourceBuilder.getProperty(Property.TYPE_KEY); + Optional returnType = definitionBuilder.getProperty(Property.TYPE_KEY); if (returnType.isEmpty() || returnType.get().value().toString().isEmpty()) { throw new IllegalStateException("The return type should be defined"); } String returnTypeString = returnType.get().value().toString(); - sourceBuilder.token() + definitionBuilder.token() .keyword(SyntaxKind.RETURNS_KEYWORD) .name(returnTypeString); Optional returnBody = - sourceBuilder.getExpressionBodyText(returnTypeString, returnType.get().imports()); + definitionBuilder.getExpressionBodyText(returnTypeString, returnType.get().imports()); if (returnBody.isEmpty()) { throw new IllegalStateException("Failed to produce the function body"); } - endSourceGeneration(sourceBuilder, returnBody.get()); - return sourceBuilder - .textEdit(SourceBuilder.SourceKind.DECLARATION) + endSourceGeneration(definitionBuilder, returnBody.get()); + Document document = FileSystemUtils.getDocument(definitionBuilder.workspaceManager, nodeDefinitionPath); + return definitionBuilder + .textEdit(SourceBuilder.SourceKind.DECLARATION, nodeDefinitionPath, + CommonUtils.toRange(document.syntaxTree().rootNode().lineRange().endLine())) .build(); } @@ -206,22 +217,16 @@ protected void endSourceGeneration(SourceBuilder sourceBuilder, String returnBod } private Map> createInvocation(SourceBuilder sourceBuilder) { - FlowNode flowNode = sourceBuilder.flowNode; - Codedata codedata = flowNode.codedata(); - Path path = FileSystemUtils.resolveFilePathFromCodedata(codedata, - sourceBuilder.workspaceManager.projectRoot(sourceBuilder.filePath)); - SourceBuilder callBuilder = new SourceBuilder(flowNode, sourceBuilder.workspaceManager, path); - - callBuilder.newVariableWithInferredType(); + sourceBuilder.newVariableWithInferredType(); Optional property = sourceBuilder.getProperty(Property.FUNCTION_NAME_KEY); if (property.isEmpty()) { throw new IllegalStateException("Name is not present"); } - callBuilder.token() + sourceBuilder.token() .name(property.get().value().toString()) .keyword(SyntaxKind.OPEN_PAREN_TOKEN); - Optional parameters = callBuilder.getProperty(Property.PARAMETERS_KEY); + Optional parameters = sourceBuilder.getProperty(Property.PARAMETERS_KEY); if (parameters.isPresent() && parameters.get().value() instanceof Map paramMap) { List argsList = new ArrayList<>(); for (Object obj : paramMap.values()) { @@ -234,13 +239,13 @@ private Map> createInvocation(SourceBuilder sourceBuilder) String paramName = paramProperties.get(Property.VARIABLE_KEY).value().toString(); argsList.add(paramName); } - callBuilder.token().name(String.join(", ", argsList)); + sourceBuilder.token().name(String.join(", ", argsList)); } - callBuilder.token().keyword(SyntaxKind.CLOSE_PAREN_TOKEN); - callBuilder.token().endOfStatement(); + sourceBuilder.token().keyword(SyntaxKind.CLOSE_PAREN_TOKEN); + sourceBuilder.token().endOfStatement(); - return callBuilder - .textEdit(SourceBuilder.SourceKind.STATEMENT, path, CommonUtils.toRange(codedata.lineRange())) + return sourceBuilder + .textEdit(SourceBuilder.SourceKind.STATEMENT) .acceptImportWithVariableType() .build(); } diff --git a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/node/FunctionCreationBuilder.java b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/node/FunctionCreationBuilder.java index a4d76b6a72..020643aaac 100644 --- a/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/node/FunctionCreationBuilder.java +++ b/flow-model-generator/modules/flow-model-generator-core/src/main/java/io/ballerina/flowmodelgenerator/core/model/node/FunctionCreationBuilder.java @@ -38,6 +38,8 @@ public class FunctionCreationBuilder extends DataMapperCreationBuilder { public static final String OUTPUT_DOC = "Output type of the function"; + private static final String FUNCTION_DEFINITION_FILE = "functions.bal"; + @Override protected String getNameLabel() { return FUNCTION_NAME_LABEL; @@ -64,6 +66,11 @@ public void setConcreteConstData() { codedata().node(NodeKind.FUNCTION_CREATION); } + @Override + protected String getNodeDefinitionFile() { + return FUNCTION_DEFINITION_FILE; + } + @Override protected void endSourceGeneration(SourceBuilder sourceBuilder, String returnBody) { sourceBuilder diff --git a/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/resources/to_source/source/data_mapper/functions.bal b/flow-model-generator/modules/flow-model-generator-ls-extension/src/test/resources/to_source/source/data_mapper/functions.bal new file mode 100644 index 0000000000..e69de29bb2