Skip to content

Commit

Permalink
Merge pull request #481 from nipunayf/add-form-builder
Browse files Browse the repository at this point in the history
Improve the flow node form
  • Loading branch information
LakshanWeerasinghe authored Nov 8, 2024
2 parents 1a27c22 + 24f0339 commit ed83ae5
Show file tree
Hide file tree
Showing 115 changed files with 1,890 additions and 1,264 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
import io.ballerina.flowmodelgenerator.core.model.node.Rollback;
import io.ballerina.flowmodelgenerator.core.model.node.Start;
import io.ballerina.flowmodelgenerator.core.model.node.XmlPayload;
import io.ballerina.projects.ModuleDescriptor;
import io.ballerina.projects.Project;
import io.ballerina.tools.text.LinePosition;
import io.ballerina.tools.text.LineRange;
Expand Down Expand Up @@ -140,12 +141,13 @@ class CodeAnalyzer extends NodeVisitor {
private TypedBindingPatternNode typedBindingPatternNode;
private final String connectionScope;
private final TextDocument textDocument;
private final String defaultModuleName;
private final ModuleDescriptor moduleDescriptor;
private final boolean forceAssign;
private final DiagnosticHandler diagnosticHandler;

public CodeAnalyzer(Project project, SemanticModel semanticModel, String connectionScope,
Map<String, LineRange> dataMappings, TextDocument textDocument, String defaultModuleName,
Map<String, LineRange> dataMappings, TextDocument textDocument,
ModuleDescriptor moduleDescriptor,
boolean forceAssign) {
this.project = project;
this.flowNodeList = new ArrayList<>();
Expand All @@ -154,7 +156,7 @@ public CodeAnalyzer(Project project, SemanticModel semanticModel, String connect
this.dataMappings = dataMappings;
this.connectionScope = connectionScope;
this.textDocument = textDocument;
this.defaultModuleName = defaultModuleName;
this.moduleDescriptor = moduleDescriptor;
this.forceAssign = forceAssign;
this.diagnosticHandler = new DiagnosticHandler(semanticModel);
}
Expand All @@ -177,8 +179,8 @@ public void visit(FunctionDefinitionNode functionDefinitionNode) {
public void visit(ObjectFieldNode objectFieldNode) {
objectFieldNode.expression().ifPresent(expressionNode -> expressionNode.accept(this));
nodeBuilder.properties()
.type(objectFieldNode.typeName())
.variable(objectFieldNode.fieldName());
.type(objectFieldNode.typeName(), true)
.data(objectFieldNode.fieldName(), false, new HashSet<>());
endNode(objectFieldNode);
}

Expand Down Expand Up @@ -260,7 +262,7 @@ private void handleActionNode(ActionNode actionNode, String methodName, Expressi
String description = documentation.flatMap(Documentation::description).orElse("");
Map<String, String> documentationMap = documentation.map(Documentation::parameterMap).orElse(Map.of());

startNode(NodeKind.REMOTE_ACTION_CALL, expressionNode)
startNode(NodeKind.REMOTE_ACTION_CALL, expressionNode.parent())
.symbolInfo(methodSymbol)
.metadata()
.label(methodName)
Expand All @@ -272,20 +274,20 @@ private void handleActionNode(ActionNode actionNode, String methodName, Expressi
.stepOut()
.properties()
.callExpression(expressionNode, Property.CONNECTION_KEY);
handleFunctionCallActionCallsParams(argumentNodes, methodSymbol, documentationMap);
handleFunctionParams(argumentNodes, methodSymbol, documentationMap);
handleCheckFlag(actionNode, SyntaxKind.CHECK_ACTION, methodSymbol.typeDescriptor());
}

private void handleFunctionCallActionCallsParams(SeparatedNodeList<FunctionArgumentNode> argumentNodes,
FunctionSymbol methodSymbol,
Map<String, String> documentationMap) {
Optional<List<ParameterSymbol>> funcParams = methodSymbol.typeDescriptor().params();
private void handleFunctionParams(SeparatedNodeList<FunctionArgumentNode> argumentNodes,
FunctionSymbol functionSymbol,
Map<String, String> documentationMap) {
Optional<List<ParameterSymbol>> funcParams = functionSymbol.typeDescriptor().params();
if (funcParams.isPresent()) {
List<ParameterSymbol> params = funcParams.get().stream()
.filter(p -> p.paramKind() != ParameterKind.INCLUDED_RECORD)
.toList();
nodeBuilder.properties().functionArguments(
argumentNodes, params, documentationMap, methodSymbol.external());
argumentNodes, params, documentationMap, functionSymbol.external());
}
}

Expand Down Expand Up @@ -324,23 +326,23 @@ private void handleResourceActionNode(ClientResourceAccessActionNode actionNode,

String resourcePathTemplate = CommonUtils.buildResourcePathTemplate(methodSymbol);

startNode(NodeKind.RESOURCE_ACTION_CALL, expressionNode)
startNode(NodeKind.RESOURCE_ACTION_CALL, expressionNode.parent())
.symbolInfo(methodSymbol)
.metadata()
.label(methodName)
.description(description)
.stepOut()
.label(methodName)
.description(description)
.stepOut()
.codedata()
.object("Client")
.symbol(methodName)
.resourcePath(resourcePathTemplate)
.stepOut()
.object("Client")
.symbol(methodName)
.resourcePath(resourcePathTemplate)
.stepOut()
.properties()
.callExpression(expressionNode, Property.CONNECTION_KEY)
.resourcePath(fullPath)
.variable(this.typedBindingPatternNode);
.callExpression(expressionNode, Property.CONNECTION_KEY)
.resourcePath(fullPath)
.data(this.typedBindingPatternNode, false, new HashSet<>());

handleFunctionCallActionCallsParams(argumentNodes, methodSymbol, documentationMap);
handleFunctionParams(argumentNodes, methodSymbol, documentationMap);
handleCheckFlag(actionNode, SyntaxKind.CHECK_ACTION, methodSymbol.typeDescriptor());

}
Expand Down Expand Up @@ -567,12 +569,12 @@ public void visit(AssignmentStatementNode assignmentStatementNode) {
.stepOut()
.properties()
.expression(expression)
.variable(assignmentStatementNode.varRef(), true);
.data(assignmentStatementNode.varRef(), true, new HashSet<>());
}

if (nodeBuilder instanceof XmlPayload || nodeBuilder instanceof JsonPayload
|| nodeBuilder instanceof BinaryData) {
nodeBuilder.properties().variable(assignmentStatementNode.varRef());
nodeBuilder.properties().data(assignmentStatementNode.varRef(), false, new HashSet<>());
}
endNode(assignmentStatementNode);
}
Expand Down Expand Up @@ -624,73 +626,50 @@ public void visit(FunctionCallExpressionNode functionCallExpressionNode) {
}

FunctionSymbol functionSymbol = (FunctionSymbol) symbol.get();
String orgName = CommonUtils.getOrgName(functionSymbol);
NameReferenceNode nameReferenceNode = functionCallExpressionNode.functionName();

if (nameReferenceNode.kind() == SyntaxKind.QUALIFIED_NAME_REFERENCE) {
String functionName = ((QualifiedNameReferenceNode) nameReferenceNode).identifier().text();
Optional<Documentation> documentation = functionSymbol.documentation();
String description = documentation.flatMap(Documentation::description).orElse("");
Map<String, String> documentationMap = documentation.map(Documentation::parameterMap).orElse(Map.of());

startNode(NodeKind.FUNCTION_CALL, functionCallExpressionNode)
.symbolInfo(functionSymbol)
.metadata()
.label(functionName)
.description(description)
.stepOut()
.codedata()
.symbol(functionName);

handleFunctionCallActionCallsParams(functionCallExpressionNode.arguments(),
functionSymbol, documentationMap);
handleCheckFlag(functionCallExpressionNode, SyntaxKind.CHECK_EXPRESSION, functionSymbol.typeDescriptor());
} else if (nameReferenceNode.kind() == SyntaxKind.SIMPLE_NAME_REFERENCE) {
SimpleNameReferenceNode simpleNameReferenceNode = (SimpleNameReferenceNode) nameReferenceNode;
String functionName = simpleNameReferenceNode.name().text();
if (dataMappings.containsKey(functionName)) {
startNode(NodeKind.DATA_MAPPER, functionCallExpressionNode)
.properties()
.functionName(functionName)
.output(this.typedBindingPatternNode);

Optional<List<ParameterSymbol>> funcParams = functionSymbol.typeDescriptor().params();
if (funcParams.isPresent()) {
List<ParameterSymbol> params = funcParams.get().stream()
.filter(p -> p.paramKind() != ParameterKind.INCLUDED_RECORD)
.toList();
nodeBuilder.properties().inputs(functionCallExpressionNode.arguments(), params);
}
nodeBuilder.properties().view(dataMappings.get(functionName));
} else {
startNode(NodeKind.FUNCTION_CALL, functionCallExpressionNode)
.metadata()
.label(functionName)
.stepOut()
.codedata()
.org(orgName)
.module(defaultModuleName)
.version(functionSymbol.getModule().get().id().version())
.symbol(functionName);

Optional<List<ParameterSymbol>> funcParams = functionSymbol.typeDescriptor().params();
if (funcParams.isPresent()) {
List<ParameterSymbol> params = funcParams.get().stream()
.filter(p -> p.paramKind() != ParameterKind.INCLUDED_RECORD)
.toList();
nodeBuilder.properties().functionArguments(
functionCallExpressionNode.arguments(), params);
}
Optional<Documentation> documentation = functionSymbol.documentation();
String description = documentation.flatMap(Documentation::description).orElse("");
Map<String, String> documentationMap = documentation.map(Documentation::parameterMap).orElse(Map.of());
SeparatedNodeList<FunctionArgumentNode> arguments = functionCallExpressionNode.arguments();

String functionName = switch (nameReferenceNode.kind()) {
case QUALIFIED_NAME_REFERENCE -> ((QualifiedNameReferenceNode) nameReferenceNode).identifier().text();
case SIMPLE_NAME_REFERENCE -> ((SimpleNameReferenceNode) nameReferenceNode).name().text();
default -> "";
};

if (dataMappings.containsKey(functionName)) {
startNode(NodeKind.DATA_MAPPER, functionCallExpressionNode.parent()).properties()
.functionName(functionName)
.output(this.typedBindingPatternNode);
Optional<List<ParameterSymbol>> funcParams = functionSymbol.typeDescriptor().params();
if (funcParams.isPresent()) {
List<ParameterSymbol> params = funcParams.get().stream()
.filter(p -> p.paramKind() != ParameterKind.INCLUDED_RECORD)
.toList();
nodeBuilder.properties().inputs(arguments, params);
}
nodeBuilder.properties().view(dataMappings.get(functionName));
} else {
startNode(NodeKind.FUNCTION_CALL, functionCallExpressionNode.parent());
handleFunctionParams(arguments, functionSymbol, documentationMap);
if (CommonUtils.isDefaultPackage(functionSymbol, moduleDescriptor)) {
functionSymbol.getLocation()
.flatMap(location -> CommonUtil.findNode(functionSymbol,
CommonUtils.getDocument(project, location).syntaxTree()))
.ifPresent(node -> nodeBuilder.properties().view(node.lineRange()));
handleCheckFlag(functionCallExpressionNode, SyntaxKind.CHECK_EXPRESSION,
functionSymbol.typeDescriptor());
}
} else {
handleExpressionNode(functionCallExpressionNode);
}

nodeBuilder
.symbolInfo(functionSymbol)
.metadata()
.label(functionName)
.description(description)
.stepOut()
.codedata().symbol(functionName);
handleCheckFlag(functionCallExpressionNode, SyntaxKind.CHECK_EXPRESSION, functionSymbol.typeDescriptor());
}

@Override
Expand Down Expand Up @@ -929,7 +908,7 @@ private void handleConstructorExpressionNode(ExpressionNode constructorExprNode)
}
}

// Utility methods
// Utility methods

/**
* It's the responsibility of the parent node to add the children nodes when building the diagram. Hence, the method
Expand All @@ -949,16 +928,17 @@ private void endNode() {
private NodeBuilder startNode(NodeKind kind) {
this.nodeBuilder = NodeBuilder.getNodeFromKind(kind)
.semanticModel(semanticModel)
.defaultModuleName(defaultModuleName);
.defaultModuleName(moduleDescriptor);
return this.nodeBuilder;
}

private NodeBuilder startNode(NodeKind kind, Node node) {
this.nodeBuilder = NodeBuilder.getNodeFromKind(kind)
.semanticModel(semanticModel)
.diagnosticHandler(diagnosticHandler)
.defaultModuleName(defaultModuleName);
diagnosticHandler.handle(nodeBuilder, node.lineRange(), false);
.defaultModuleName(moduleDescriptor);
diagnosticHandler.handle(nodeBuilder,
node instanceof ExpressionNode ? node.parent().lineRange() : node.lineRange(), false);
return this.nodeBuilder;
}

Expand All @@ -982,7 +962,7 @@ private Branch.Builder startBranch(String label, NodeKind node, Branch.BranchKin
this.nodeBuilder = null;
return new Branch.Builder()
.semanticModel(semanticModel)
.defaultModuleName(defaultModuleName)
.defaultModuleName(moduleDescriptor)
.diagnosticHandler(diagnosticHandler)
.codedata().node(node).stepOut()
.label(label)
Expand Down
Loading

0 comments on commit ed83ae5

Please sign in to comment.