diff --git a/DiagramBuilder/Activity/Diagram/ActivityDiagramBuilder.cs b/DiagramBuilder/Activity/Diagram/ActivityDiagramBuilder.cs index da5d1d39361c4293fd41faf62767a4d53e7abe29..04711ddc4dc4af5a5e1b20f5a9e7acb936938e85 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 2bba65347fb1a50ce6c4fff8bd9d42a798e98bee..62828978a1ddae00d1d2ba7b060f568e7b095294 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 077ee304428e967e0c774bec64c5028fd7d7ecf8..4e8515703b61eca8c050a07839149fe11c38241c 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 d97fcf2e3857a65f302b1bcd33f2c30c65b7dd64..820ccb9ed9675850b785c5c1f0c4d406f9c09ce9 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 ce40f5fb019eb618b04e04cf6d9a12dec7af34e3..eb77eb1e3c4672f3c2ddf3e3b85be45ab8cf33b3 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 f5d91e72c05e4da37b1ecd6aecf7db2b5ed1b67d..72a92fcaa7a057bb4167c2625c1e7f6e63f3756d 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 01ff212cb48ba11ceb27d3d3cfc8bf8a3d590f3c..c15d5f03d4b3b209a72224cc5741152e77db2a06 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 f3ef8a1fdb2f357763031923b954e0248b83e56b..84156298f9a956f026b1b5d77082f594d0a16565 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 4142461a70d4c6fb7dc8d75e6501daf26259a13e..784592979bff508b6bac3b5a90f8d2e4ee98893d 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();