From 2747b052b6e44fa5f7fc442b9149af19ac62ab98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Konvi=C4=8Dka?= <konvicka.g630@gmail.com> Date: Wed, 24 Jan 2024 18:07:26 +0100 Subject: [PATCH] fix(#24), refactor(#26, #25): Modifications and fixes, testing --- .../Diagram/ActivityDiagramBuilder.cs | 4 ++- .../Activity/Diagram/DecisionBuilder.cs | 18 ++++++++-- .../XML/XmiActivityDiagramUmlBuilder.cs | 15 +++++--- .../Class/Diagram/OperationBuilder.cs | 4 +-- .../Class/Interface/IOperationBuilder.cs | 2 +- .../Class/XML/XmiClassDiagramUmlBuilder.cs | 35 ++++++++++++++----- DiagramBuilder/Convertor.cs | 1 + .../Cpp/CppActivityDiagramVisitor.cs | 14 +++++++- .../Cpp/CppClassDiagramVisitor.cs | 7 ++-- 9 files changed, 77 insertions(+), 23 deletions(-) diff --git a/DiagramBuilder/Activity/Diagram/ActivityDiagramBuilder.cs b/DiagramBuilder/Activity/Diagram/ActivityDiagramBuilder.cs index da5d1d3..04711dd 100644 --- a/DiagramBuilder/Activity/Diagram/ActivityDiagramBuilder.cs +++ b/DiagramBuilder/Activity/Diagram/ActivityDiagramBuilder.cs @@ -14,6 +14,7 @@ public class ActivityDiagramBuilder : IDiagramBuilder private Stack<XmiElement> _loopElements { get; set; } = new Stack<XmiElement>(); private XmiElement _lastClosedDecision { get; set; } = null; + private XmiElement _lastOpenedDecision { get; set; } = null; internal ActivityDiagramBuilder() { @@ -43,6 +44,7 @@ public class ActivityDiagramBuilder : IDiagramBuilder else LastActivity = _xmiActivityDiagramUmlBuilder.AddDecision(_xmiActivityDiagramUmlBuilder.ActivityDiagram, name, new() {_lastEdge}, null, _lastClosedDecision); _loopElements.Push(LastActivity); + _lastOpenedDecision = LastActivity; return this; } @@ -62,7 +64,7 @@ public class ActivityDiagramBuilder : IDiagramBuilder else LastActivity = _xmiActivityDiagramUmlBuilder.AddDecision(_xmiActivityDiagramUmlBuilder.ActivityDiagram, name, new() {_lastEdge}, null, _lastClosedDecision); - return new DecisionBuilder(this._name, this._xmiActivityDiagramUmlBuilder, _lastEdge, LastActivity, this); + return new DecisionBuilder(this._name, this._xmiActivityDiagramUmlBuilder, _lastEdge, LastActivity, _lastOpenedDecision, this); } public string? BuildDiagram() diff --git a/DiagramBuilder/Activity/Diagram/DecisionBuilder.cs b/DiagramBuilder/Activity/Diagram/DecisionBuilder.cs index 2bba653..6282897 100644 --- a/DiagramBuilder/Activity/Diagram/DecisionBuilder.cs +++ b/DiagramBuilder/Activity/Diagram/DecisionBuilder.cs @@ -14,6 +14,7 @@ namespace DiagramBuilder.Activity.Diagram private List<Dictionary<BranchType, XmiElement>> _lastAddedEdge { get; set; } = new(); private List<Dictionary<BranchType, XmiElement>> _loopElements { get; set; } = new(); private List<Dictionary<BranchType, XmiElement>> _lastAddedNode { get; set; } = new(); + private List<XmiElement> _lastAddedLoopNode { get; set; } = new(); IDiagramBuilder _diagramBuilder { get; set; } private List<BranchType> _lastBranchTypeForDecision { get; set; } = new(); @@ -21,7 +22,8 @@ namespace DiagramBuilder.Activity.Diagram private long _actualDecisionId { get; set; } = 0; public DecisionBuilder(string? name, XmiActivityDiagramUmlBuilder xmiActivityDiagramUmlBuilder, - XmiElement trueBranchEdge, XmiElement lastAddedNode, IDiagramBuilder _diagramBuilder) + XmiElement trueBranchEdge, XmiElement lastAddedNode, XmiElement lastOpenedDecision, + IDiagramBuilder _diagramBuilder) { this._diagramBuilder = _diagramBuilder; _xmiActivityDiagramUmlBuilder = xmiActivityDiagramUmlBuilder; @@ -32,6 +34,7 @@ namespace DiagramBuilder.Activity.Diagram _lastAddedEdge[^1].Add(BranchType.True, trueBranchEdge); _lastAddedNode[^1].Add(BranchType.True, lastAddedNode); _lastAddedNode[^1].Add(BranchType.False, lastAddedNode); + _lastAddedLoopNode.Add(lastOpenedDecision); } public string? BuildDiagram() @@ -64,9 +67,14 @@ namespace DiagramBuilder.Activity.Diagram public (IDecisionBuilder, IDiagramBuilder) AddMerge(string? name) { + XmiElement lastAddedDecisionNode = _lastAddedLoopNode[^1]; + if(_lastAddedLoopNode.Count > 1) + { + lastAddedDecisionNode = _lastAddedLoopNode[^2]; + } var mergeNode = _xmiActivityDiagramUmlBuilder.AddMerge( _xmiActivityDiagramUmlBuilder.ActivityDiagram, name, - _lastAddedNode[^1][BranchType.True], _lastAddedNode[^1][BranchType.False]); + _lastAddedNode[^1][BranchType.True], _lastAddedNode[^1][BranchType.False], lastAddedDecisionNode); _lastAddedEdge.Remove(_lastAddedEdge.Last()); _lastAddedNode.Remove(_lastAddedNode.Last()); @@ -79,7 +87,10 @@ namespace DiagramBuilder.Activity.Diagram _lastAddedNode.Last()[_lastBranchTypeForDecision.Last()] = mergeNode; _lastBranchTypeForDecision.RemoveAt(_lastBranchTypeForDecision.Count - 1); - + if (_lastAddedLoopNode.Count > 2) + { + _lastAddedLoopNode.RemoveAt(_lastAddedLoopNode.Count - 1); + } return (this, null); } @@ -140,6 +151,7 @@ namespace DiagramBuilder.Activity.Diagram _loopElements.Add(new Dictionary<BranchType, XmiElement>()); _loopElements[^1].Add(type, _lastAddedNode[^1][type]); + _lastAddedLoopNode.Add(_lastAddedNode[^1][type]); return this; } diff --git a/DiagramBuilder/Activity/XML/XmiActivityDiagramUmlBuilder.cs b/DiagramBuilder/Activity/XML/XmiActivityDiagramUmlBuilder.cs index 077ee30..4e85157 100644 --- a/DiagramBuilder/Activity/XML/XmiActivityDiagramUmlBuilder.cs +++ b/DiagramBuilder/Activity/XML/XmiActivityDiagramUmlBuilder.cs @@ -61,9 +61,10 @@ public class XmiActivityDiagramUmlBuilder : DiagramUmlBuilder - public XmiElement AddMerge(XmiElement parent, string? name, XmiElement lastTrueBranchNode, XmiElement lastFalseBranchNode) + public XmiElement AddMerge(XmiElement parent, string? name, XmiElement lastTrueBranchNode, + XmiElement lastFalseBranchNode, XmiElement lastAddedDecisionNode) { - _lastAddedNodeElement = AddMergeNode(parent, name, lastTrueBranchNode, lastFalseBranchNode); + _lastAddedNodeElement = AddMergeNode(parent, name, lastTrueBranchNode, lastFalseBranchNode, lastAddedDecisionNode); _nodes.Add(_lastAddedNodeElement.XmlElement.GetAttribute("xmi:id"), _lastAddedNodeElement); return _lastAddedNodeElement; } @@ -166,11 +167,15 @@ public class XmiActivityDiagramUmlBuilder : DiagramUmlBuilder return _edges.LastOrDefault(); } - private XmiElement AddMergeNode(XmiElement parent, string? name, XmiElement lastTrueBranchNode, XmiElement lastFalseBranchNode) + private XmiElement AddMergeNode(XmiElement parent, string? name, XmiElement lastTrueBranchNode, + XmiElement lastFalseBranchNode, XmiElement lastAddedDecisionNode) { var node = _xmiBuilder.AddElement(parent, "node", XmiType.UmlMergeNode, name, null); - AddEdge(ActivityDiagram, lastTrueBranchNode, node); - AddEdge(ActivityDiagram, lastFalseBranchNode, node); + AddEdge(ActivityDiagram, lastTrueBranchNode, + lastTrueBranchNode.XmlElement.GetAttribute("name") != "continue;" ? node : lastAddedDecisionNode); + + AddEdge(ActivityDiagram, lastFalseBranchNode, + lastFalseBranchNode.XmlElement.GetAttribute("name") != "continue;" ? node : lastAddedDecisionNode); return node; } diff --git a/DiagramBuilder/Class/Diagram/OperationBuilder.cs b/DiagramBuilder/Class/Diagram/OperationBuilder.cs index d97fcf2..820ccb9 100644 --- a/DiagramBuilder/Class/Diagram/OperationBuilder.cs +++ b/DiagramBuilder/Class/Diagram/OperationBuilder.cs @@ -42,9 +42,9 @@ public class OperationBuilder : IOperationBuilder return this; } - public IOperationBuilder AddParameter(string? name, PropertyType propertyType) + public IOperationBuilder AddParameter(string? name, PropertyType propertyType, string? paramType) { - _xmiClassDiagramUmlBuilder.AddParameter(_operation, name, propertyType); + _xmiClassDiagramUmlBuilder.AddParameter(_operation, name, propertyType, paramType); return this; } } \ No newline at end of file diff --git a/DiagramBuilder/Class/Interface/IOperationBuilder.cs b/DiagramBuilder/Class/Interface/IOperationBuilder.cs index ce40f5f..eb77eb1 100644 --- a/DiagramBuilder/Class/Interface/IOperationBuilder.cs +++ b/DiagramBuilder/Class/Interface/IOperationBuilder.cs @@ -4,5 +4,5 @@ namespace DiagramBuilder.Class.Interface; public interface IOperationBuilder : IClassBuilder { - IOperationBuilder AddParameter(string? name, PropertyType propertyType); + IOperationBuilder AddParameter(string? name, PropertyType propertyType, string? paramType); } \ No newline at end of file diff --git a/DiagramBuilder/Class/XML/XmiClassDiagramUmlBuilder.cs b/DiagramBuilder/Class/XML/XmiClassDiagramUmlBuilder.cs index f5d91e7..72a92fc 100644 --- a/DiagramBuilder/Class/XML/XmiClassDiagramUmlBuilder.cs +++ b/DiagramBuilder/Class/XML/XmiClassDiagramUmlBuilder.cs @@ -145,22 +145,41 @@ public class XmiClassDiagramUmlBuilder : DiagramUmlBuilder _nextPackageAssociationId[packageName]++; } - public void AddParameter(XmiElement parent, string? name, PropertyType propertyType) + public void AddParameter(XmiElement parent, string? name, PropertyType propertyType, string? paramType) { - if (propertyType != PropertyType.NonPrimitiveType && propertyType != PropertyType.NoDataType) + if (propertyType != PropertyType.NoDataType) { + XmiAttributeDto typeAttribute = null; + List<XmiAttributeDto> additionalAttributes = new(); var directionAttribute = new XmiAttributeDto() { AttributeName = "direction", AttributeValue = "in" }; - var parameter = AddOwnedParameter(parent, XmiType.UmlParameter, name, new(){ directionAttribute }); - var hrefAttribute = new XmiAttributeDto() + + additionalAttributes.Add(directionAttribute); + if (_elementClasses.TryGetValue(paramType, out var paramReferenceTypeId)) { - AttributeName = "href", - AttributeValue = $"http://www.omg.org/spec/UML/20131001/UML.xmi#{Convertor.PropertyTypeToDataTypeString(propertyType)}" - }; - AddTypeAttribute(parameter, propertyType, new(){ hrefAttribute }); + typeAttribute = new XmiAttributeDto() + { + AttributeName = "type", + AttributeValue = paramReferenceTypeId.XmlElement.GetAttribute("xmi:id") + }; + additionalAttributes.Add(typeAttribute); + } + + var parameter = AddOwnedParameter(parent, XmiType.UmlParameter, name, additionalAttributes); + XmiAttributeDto referenceAttribute = null; + if (propertyType != PropertyType.NonPrimitiveType) + { + referenceAttribute = new XmiAttributeDto() + { + AttributeName = "href", + AttributeValue = + $"http://www.omg.org/spec/UML/20131001/UML.xmi#{Convertor.PropertyTypeToDataTypeString(propertyType)}" + }; + AddTypeAttribute(parameter, propertyType, new(){ referenceAttribute }); + } } } diff --git a/DiagramBuilder/Convertor.cs b/DiagramBuilder/Convertor.cs index 01ff212..c15d5f0 100644 --- a/DiagramBuilder/Convertor.cs +++ b/DiagramBuilder/Convertor.cs @@ -110,6 +110,7 @@ public static class Convertor or PropertyType.PrimitiveTypeString => $"{prefix}:PrimitiveType", PropertyType.LiteralInteger => $"{prefix}:LiteralInteger", PropertyType.LiteralBoolean => $"{prefix}:LiteralBoolean", + PropertyType.NonPrimitiveType => $"{prefix}:Class", _ => throw new ArgumentOutOfRangeException(nameof(propertyType), propertyType, null) }; } diff --git a/LanguageRecogniser/Cpp/CppActivityDiagramVisitor.cs b/LanguageRecogniser/Cpp/CppActivityDiagramVisitor.cs index f3ef8a1..8415629 100644 --- a/LanguageRecogniser/Cpp/CppActivityDiagramVisitor.cs +++ b/LanguageRecogniser/Cpp/CppActivityDiagramVisitor.cs @@ -115,7 +115,7 @@ public class CppActivityDiagramVisitor : CPP14ParserBaseVisitor<object> public override object VisitJumpStatement(CPP14Parser.JumpStatementContext context) { - if (context.Return() != null) + if (context.Return() != null || context.Continue() != null || context.Break() != null) { if (_decisionBuilderStack.Count > 0) { @@ -206,6 +206,12 @@ public class CppActivityDiagramVisitor : CPP14ParserBaseVisitor<object> public override object VisitIterationStatement(CPP14Parser.IterationStatementContext context) { var condition = context.condition().GetText(); + + if(context.forInitStatement() != null) + { + var forInitStatement = ExtractOriginalText(context.forInitStatement()); + _diagramBuilder.AddAction(forInitStatement); + } if (_decisionBuilderStack.Count == 0) _diagramBuilder.AddLoop(condition, condition); @@ -213,6 +219,12 @@ public class CppActivityDiagramVisitor : CPP14ParserBaseVisitor<object> _decisionBuilderStack.Peek().Item1.AddLoop(condition, condition, _decisionBuilderStack.Peek().Item2.Peek()); Visit(context.statement()); + + if(context.expression() != null) + { + var expression = $"{ExtractOriginalText(context.expression())};"; + _diagramBuilder.AddAction(expression); + } if (_decisionBuilderStack.Count == 0) _diagramBuilder.CloseLoop(condition); diff --git a/LanguageRecogniser/Cpp/CppClassDiagramVisitor.cs b/LanguageRecogniser/Cpp/CppClassDiagramVisitor.cs index 4142461..7845929 100644 --- a/LanguageRecogniser/Cpp/CppClassDiagramVisitor.cs +++ b/LanguageRecogniser/Cpp/CppClassDiagramVisitor.cs @@ -118,7 +118,7 @@ public class CppClassDiagramVisitor : CPP14ParserBaseVisitor<object> { foreach (var param in function.Parameters) { - operationBuilder.AddParameter(param.Name, Convertor.StringToPropertyType(param.Type)); + operationBuilder.AddParameter(param.Name, Convertor.StringToPropertyType(param.Type), param.Type); } } } @@ -194,7 +194,10 @@ public class CppClassDiagramVisitor : CPP14ParserBaseVisitor<object> if (context.declSpecifierSeq() != null) { int returnTypeIndex = context.declSpecifierSeq().declSpecifier().Length - 1; - function.ReturnType = Visit(context.declSpecifierSeq().declSpecifier()[returnTypeIndex].typeSpecifier()).ToString(); + if (context.declSpecifierSeq().declSpecifier()[returnTypeIndex].typeSpecifier() != null) + { + function.ReturnType = Visit(context.declSpecifierSeq().declSpecifier()[returnTypeIndex].typeSpecifier().trailingTypeSpecifier().simpleTypeSpecifier()).ToString(); + } } function.Name = Visit(context.declarator().pointerDeclarator().noPointerDeclarator().noPointerDeclarator().declaratorid().idExpression()).ToString(); -- GitLab