From ae5f7be8ff117a956f5da27fe6554316058292bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Konvi=C4=8Dka?= <konvicka.g630@gmail.com>
Date: Thu, 11 Jan 2024 17:36:02 +0100
Subject: [PATCH] fix(#24): Fix Activity and Class diagram code parsing

---
 .gitignore                                    |   2 +-
 .idea/.idea.CodeParser/.idea/workspace.xml    | 126 ------------------
 .idea/.idea.CodeToXMI/.idea/.gitignore        |  13 --
 .idea/.idea.CodeToXMI/.idea/.name             |   1 -
 .idea/.idea.CodeToXMI/.idea/encodings.xml     |   4 -
 .idea/.idea.CodeToXMI/.idea/indexLayout.xml   |   8 --
 .idea/.idea.CodeToXMI/.idea/misc.xml          |  19 ---
 .idea/.idea.CodeToXMI/.idea/vcs.xml           |   6 -
 ...compose.development.generated.override.yml |  21 ---
 DiagramBuilder/Class/Diagram/ClassBuilder.cs  |   6 +-
 .../Class/Diagram/OperationBuilder.cs         |   4 +-
 .../Class/Interface/IClassBuilder.cs          |   2 +-
 .../Class/XML/XmiClassDiagramUmlBuilder.cs    |   8 +-
 .../Cpp/CppActivityDiagramVisitor.cs          |  31 ++++-
 .../Cpp/CppClassDiagramVisitor.cs             |  20 +--
 UnitTest/ClassDiagramTests.cs                 |   8 +-
 WebAPI/Controllers/ApiController.cs           |   5 +-
 17 files changed, 57 insertions(+), 227 deletions(-)
 delete mode 100644 .idea/.idea.CodeParser/.idea/workspace.xml
 delete mode 100644 .idea/.idea.CodeToXMI/.idea/.gitignore
 delete mode 100644 .idea/.idea.CodeToXMI/.idea/.name
 delete mode 100644 .idea/.idea.CodeToXMI/.idea/encodings.xml
 delete mode 100644 .idea/.idea.CodeToXMI/.idea/indexLayout.xml
 delete mode 100644 .idea/.idea.CodeToXMI/.idea/misc.xml
 delete mode 100644 .idea/.idea.CodeToXMI/.idea/vcs.xml
 delete mode 100644 .idea/.idea.CodeToXMI/Docker/docker-compose.development.generated.override.yml

diff --git a/.gitignore b/.gitignore
index 91953df..39c9242 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,4 @@ obj/
 /packages/
 riderModule.iml
 /_ReSharper.Caches/
-.idea
\ No newline at end of file
+.idea/
diff --git a/.idea/.idea.CodeParser/.idea/workspace.xml b/.idea/.idea.CodeParser/.idea/workspace.xml
deleted file mode 100644
index 464ebe8..0000000
--- a/.idea/.idea.CodeParser/.idea/workspace.xml
+++ /dev/null
@@ -1,126 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="AutoGeneratedRunConfigurationManager">
-    <projectFile>ConsoleApp1/ConsoleApp1.csproj</projectFile>
-  </component>
-  <component name="AutoImportSettings">
-    <option name="autoReloadType" value="SELECTIVE" />
-  </component>
-  <component name="ChangeListManager">
-    <list default="true" id="38df7b5a-e819-45ed-9bf5-eb7ce2106e88" name="Changes" comment="" />
-    <option name="SHOW_DIALOG" value="false" />
-    <option name="HIGHLIGHT_CONFLICTS" value="true" />
-    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
-    <option name="LAST_RESOLUTION" value="IGNORE" />
-  </component>
-  <component name="Git.Settings">
-    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
-  </component>
-  <component name="MarkdownSettingsMigration">
-    <option name="stateVersion" value="1" />
-  </component>
-  <component name="MetaFilesCheckinStateConfiguration" checkMetaFiles="true" />
-  <component name="ProjectColorInfo"><![CDATA[{
-  "associatedIndex": 4
-}]]></component>
-  <component name="ProjectId" id="2WL74YsffR7PLpZQhzToFOyb7sj" />
-  <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
-  <component name="ProjectViewState">
-    <option name="autoscrollFromSource" value="true" />
-    <option name="hideEmptyMiddlePackages" value="true" />
-    <option name="showLibraryContents" value="true" />
-  </component>
-  <component name="PropertiesComponent"><![CDATA[{
-  "keyToString": {
-    "RunOnceActivity.OpenProjectViewOnStart": "true",
-    "RunOnceActivity.ShowReadmeOnStart": "true",
-    "WebServerToolWindowFactoryState": "false",
-    "git-widget-placeholder": "main",
-    "node.js.detected.package.eslint": "true",
-    "node.js.detected.package.tslint": "true",
-    "node.js.selected.package.eslint": "(autodetect)",
-    "node.js.selected.package.tslint": "(autodetect)",
-    "nodejs_package_manager_path": "npm",
-    "settings.editor.selected.configurable": "preferences.pluginManager",
-    "vue.rearranger.settings.migration": "true"
-  },
-  "keyToStringList": {
-    "rider.external.source.directories": [
-      "C:\\Users\\root\\AppData\\Roaming\\JetBrains\\Rider2023.2\\resharper-host\\DecompilerCache",
-      "C:\\Users\\root\\AppData\\Roaming\\JetBrains\\Rider2023.2\\resharper-host\\SourcesCache",
-      "C:\\Users\\root\\AppData\\Local\\Symbols\\src"
-    ]
-  }
-}]]></component>
-  <component name="RunManager">
-    <configuration name="ConsoleApp1" type="DotNetProject" factoryName=".NET Project">
-      <option name="EXE_PATH" value="" />
-      <option name="PROGRAM_PARAMETERS" value="" />
-      <option name="WORKING_DIRECTORY" value="" />
-      <option name="PASS_PARENT_ENVS" value="1" />
-      <option name="USE_EXTERNAL_CONSOLE" value="0" />
-      <option name="USE_MONO" value="0" />
-      <option name="RUNTIME_ARGUMENTS" value="" />
-      <option name="PROJECT_PATH" value="$PROJECT_DIR$/ConsoleApp1/ConsoleApp1.csproj" />
-      <option name="PROJECT_EXE_PATH_TRACKING" value="1" />
-      <option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
-      <option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
-      <option name="PROJECT_KIND" value="DotNetCore" />
-      <option name="PROJECT_TFM" value="" />
-      <method v="2">
-        <option name="Build" />
-      </method>
-    </configuration>
-  </component>
-  <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
-  <component name="TaskManager">
-    <task active="true" id="Default" summary="Default task">
-      <changelist id="38df7b5a-e819-45ed-9bf5-eb7ce2106e88" name="Changes" comment="" />
-      <created>1696499815256</created>
-      <option name="number" value="Default" />
-      <option name="presentableId" value="Default" />
-      <updated>1696499815256</updated>
-      <workItem from="1696499816476" duration="339000" />
-    </task>
-    <task id="LOCAL-00001" summary="Add project files">
-      <option name="closed" value="true" />
-      <created>1696499974654</created>
-      <option name="number" value="00001" />
-      <option name="presentableId" value="LOCAL-00001" />
-      <option name="project" value="LOCAL" />
-      <updated>1696499974654</updated>
-    </task>
-    <task id="LOCAL-00002" summary="Rename solution">
-      <option name="closed" value="true" />
-      <created>1696500005181</created>
-      <option name="number" value="00002" />
-      <option name="presentableId" value="LOCAL-00002" />
-      <option name="project" value="LOCAL" />
-      <updated>1696500005181</updated>
-    </task>
-    <option name="localTasksCounter" value="3" />
-    <servers />
-  </component>
-  <component name="TypeScriptGeneratedFilesManager">
-    <option name="version" value="3" />
-  </component>
-  <component name="UnityCheckinConfiguration" checkUnsavedScenes="true" />
-  <component name="Vcs.Log.Tabs.Properties">
-    <option name="TAB_STATES">
-      <map>
-        <entry key="MAIN">
-          <value>
-            <State />
-          </value>
-        </entry>
-      </map>
-    </option>
-  </component>
-  <component name="VcsManagerConfiguration">
-    <option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
-    <MESSAGE value="Add project files" />
-    <MESSAGE value="Rename solution" />
-    <option name="LAST_COMMIT_MESSAGE" value="Rename solution" />
-    <option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="true" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/.idea/.idea.CodeToXMI/.idea/.gitignore b/.idea/.idea.CodeToXMI/.idea/.gitignore
deleted file mode 100644
index 62202ac..0000000
--- a/.idea/.idea.CodeToXMI/.idea/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Rider ignored files
-/modules.xml
-/projectSettingsUpdater.xml
-/.idea.CodeParser.iml
-/contentModel.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/.idea.CodeToXMI/.idea/.name b/.idea/.idea.CodeToXMI/.idea/.name
deleted file mode 100644
index 908c041..0000000
--- a/.idea/.idea.CodeToXMI/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-CodeToXMI
\ No newline at end of file
diff --git a/.idea/.idea.CodeToXMI/.idea/encodings.xml b/.idea/.idea.CodeToXMI/.idea/encodings.xml
deleted file mode 100644
index df87cf9..0000000
--- a/.idea/.idea.CodeToXMI/.idea/encodings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
-</project>
\ No newline at end of file
diff --git a/.idea/.idea.CodeToXMI/.idea/indexLayout.xml b/.idea/.idea.CodeToXMI/.idea/indexLayout.xml
deleted file mode 100644
index 7b08163..0000000
--- a/.idea/.idea.CodeToXMI/.idea/indexLayout.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="UserContentModel">
-    <attachedFolders />
-    <explicitIncludes />
-    <explicitExcludes />
-  </component>
-</project>
\ No newline at end of file
diff --git a/.idea/.idea.CodeToXMI/.idea/misc.xml b/.idea/.idea.CodeToXMI/.idea/misc.xml
deleted file mode 100644
index c3a6a2a..0000000
--- a/.idea/.idea.CodeToXMI/.idea/misc.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ANTLRGenerationPreferences">
-    <option name="perGrammarGenerationSettings">
-      <list>
-        <PerGrammarGenerationSettings>
-          <option name="fileName" value="$PROJECT_DIR$/LanguageRecogniser/Cpp/CPP14Parser.g4" />
-          <option name="autoGen" value="true" />
-          <option name="outputDir" value="/gen" />
-          <option name="libDir" value="" />
-          <option name="encoding" value="" />
-          <option name="pkg" value="" />
-          <option name="language" value="CSharp" />
-          <option name="generateVisitor" value="true" />
-        </PerGrammarGenerationSettings>
-      </list>
-    </option>
-  </component>
-</project>
\ No newline at end of file
diff --git a/.idea/.idea.CodeToXMI/.idea/vcs.xml b/.idea/.idea.CodeToXMI/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/.idea.CodeToXMI/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$" vcs="Git" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/.idea/.idea.CodeToXMI/Docker/docker-compose.development.generated.override.yml b/.idea/.idea.CodeToXMI/Docker/docker-compose.development.generated.override.yml
deleted file mode 100644
index 13ca75c..0000000
--- a/.idea/.idea.CodeToXMI/Docker/docker-compose.development.generated.override.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-# This is a generated file. Not intended for manual editing.
-version: "3"
-services:
-  codeToXMI_dev:
-    build:
-      context: "/Users/jakubkonvicka/RiderProjects/diplomathesis"
-      dockerfile: "./WebAPI/Dockerfile"
-      target: "base"
-    command: []
-    entrypoint:
-    - "dotnet"
-    - "/app/bin/Debug/net7.0/WebAPI.dll"
-    environment:
-      DOTNET_USE_POLLING_FILE_WATCHER: "true"
-    image: "webapi:dev"
-    ports: []
-    volumes:
-    - "/Users/jakubkonvicka/.nuget/packages:/root/.nuget/packages"
-    - "/Users/jakubkonvicka/RiderProjects/diplomathesis/WebAPI:/app:rw"
-    - "/Users/jakubkonvicka/RiderProjects/diplomathesis:/src:rw"
-    working_dir: "/app"
diff --git a/DiagramBuilder/Class/Diagram/ClassBuilder.cs b/DiagramBuilder/Class/Diagram/ClassBuilder.cs
index f39ae36..20d295b 100644
--- a/DiagramBuilder/Class/Diagram/ClassBuilder.cs
+++ b/DiagramBuilder/Class/Diagram/ClassBuilder.cs
@@ -25,10 +25,10 @@ public class ClassBuilder : IClassBuilder
     {
         return new OperationBuilder(_xmiClassDiagramUmlBuilder, _class, name, returnType, visibilityType);
     }
-    
-    public IClassBuilder AddAssociation(string? targetClassName, VisibilityType visibilityType, AssociationType associationType)
+
+    public IClassBuilder AddAssociation(string? targetClassName, string? name, VisibilityType visibilityType, AssociationType associationType)
     {
-        _xmiClassDiagramUmlBuilder.AddAssociation(_class, targetClassName, visibilityType, associationType);
+        _xmiClassDiagramUmlBuilder.AddAssociation(_class, targetClassName, name, visibilityType, associationType);
         return this;
     }
 
diff --git a/DiagramBuilder/Class/Diagram/OperationBuilder.cs b/DiagramBuilder/Class/Diagram/OperationBuilder.cs
index 97866c4..f1077e4 100644
--- a/DiagramBuilder/Class/Diagram/OperationBuilder.cs
+++ b/DiagramBuilder/Class/Diagram/OperationBuilder.cs
@@ -30,9 +30,9 @@ public class OperationBuilder : IOperationBuilder
         return this;
     }
     
-    public IClassBuilder AddAssociation(string? targetClassName, VisibilityType visibilityType, AssociationType associationType)
+    public IClassBuilder AddAssociation(string? targetClassName, string? name, VisibilityType visibilityType, AssociationType associationType)
     {
-        _xmiClassDiagramUmlBuilder.AddAssociation(_class, targetClassName, visibilityType, associationType);
+        _xmiClassDiagramUmlBuilder.AddAssociation(_class, targetClassName, name, visibilityType, associationType);
         return this;
     }
 
diff --git a/DiagramBuilder/Class/Interface/IClassBuilder.cs b/DiagramBuilder/Class/Interface/IClassBuilder.cs
index a67fdc4..1f04480 100644
--- a/DiagramBuilder/Class/Interface/IClassBuilder.cs
+++ b/DiagramBuilder/Class/Interface/IClassBuilder.cs
@@ -6,6 +6,6 @@ public interface IClassBuilder
 {
     IClassBuilder AddProperty(string? name, VisibilityType visibilityType, PropertyType propertyType);
     IOperationBuilder AddOperation(string? name, PropertyType returnType, VisibilityType visibilityType);
-    IClassBuilder AddAssociation(string? targetClass, VisibilityType visibilityType, AssociationType associationType);
+    IClassBuilder AddAssociation(string? targetClass, string? name, VisibilityType visibilityType, AssociationType associationType);
     IClassBuilder AddGeneralization(string? targetClass);
 }
\ No newline at end of file
diff --git a/DiagramBuilder/Class/XML/XmiClassDiagramUmlBuilder.cs b/DiagramBuilder/Class/XML/XmiClassDiagramUmlBuilder.cs
index 8dace87..e6fdadc 100644
--- a/DiagramBuilder/Class/XML/XmiClassDiagramUmlBuilder.cs
+++ b/DiagramBuilder/Class/XML/XmiClassDiagramUmlBuilder.cs
@@ -92,15 +92,15 @@ public class XmiClassDiagramUmlBuilder : DiagramUmlBuilder
         return operation;
     }
 
-    public void AddAssociation(XmiElement parent, string? targetClassName, VisibilityType visibilityType, AssociationType associationType)
+    public void AddAssociation(XmiElement parent, string? targetClassName, string? name, VisibilityType visibilityType, AssociationType associationType)
     {
         string? packageName = parent.XmlElement.GetAttribute("xmi:id").Split('-')[0];
         string parentName = parent.XmlElement.GetAttribute("name");
-        string associationName = $"{packageName}-Association{_nextPackageAssociationId[packageName].ToString()}";
+        string associationName = $"{packageName}-Association_{{name}}_{_nextPackageAssociationId[packageName].ToString()}";
 
         var association = new Association()
         {
-            Name = $"Association{_nextPackageAssociationId[packageName].ToString()}",
+            Name = $"Association_{name}_{_nextPackageAssociationId[packageName].ToString()}",
             Package = packageName,
             Source = new AssociationDetail()
             {
@@ -264,7 +264,7 @@ public class XmiClassDiagramUmlBuilder : DiagramUmlBuilder
             }
             else
             {
-                throw new ArgumentException($"Target class {association.Target.ClassName} not found");
+                Console.WriteLine($"Target class {association.Target.ClassName} not found");
             }
         }
     }
diff --git a/LanguageRecogniser/Cpp/CppActivityDiagramVisitor.cs b/LanguageRecogniser/Cpp/CppActivityDiagramVisitor.cs
index 7a9b441..6250485 100644
--- a/LanguageRecogniser/Cpp/CppActivityDiagramVisitor.cs
+++ b/LanguageRecogniser/Cpp/CppActivityDiagramVisitor.cs
@@ -10,11 +10,16 @@ public class CppActivityDiagramVisitor : CPP14ParserBaseVisitor<object>
     private IDiagramBuilder _diagramBuilder { get; set; }
     private string functionIdentifier { get; set; }
     private Stack<(IDecisionBuilder, Stack<BranchType>)> _decisionBuilderStack { get; set; } = new Stack<(IDecisionBuilder, Stack<BranchType>)>();
+    private long decisionUniqueueId { get; set; } = 0;
+    
+    private string actualContext { get; set; } = string.Empty;
+    private string contextIdentifier { get; set; } = string.Empty;
 
-    public CppActivityDiagramVisitor(IDiagramBuilder diagramBuilder, string functionIdentifier)
+    public CppActivityDiagramVisitor(IDiagramBuilder diagramBuilder, string contextIdentifier, string functionIdentifier)
     {
         _diagramBuilder = diagramBuilder;
         this.functionIdentifier = functionIdentifier;
+        this.contextIdentifier = contextIdentifier;
     }
 
     public override object VisitTranslationUnit(CPP14Parser.TranslationUnitContext context)
@@ -49,16 +54,35 @@ public class CppActivityDiagramVisitor : CPP14ParserBaseVisitor<object>
         {
             Visit(context.namespaceDefinition());
         }
+        else if(context.blockDeclaration().simpleDeclaration() != null)
+        {
+            VisitChildren(context.blockDeclaration().simpleDeclaration().declSpecifierSeq());
+        }
 
         return null;
     }
 
+    public override string VisitClassSpecifier(CPP14Parser.ClassSpecifierContext context)
+    {
+        var className = Visit(context.classHead().classHeadName());
+        
+        this.actualContext = className as string;
+        Visit(context.memberSpecification());
+        this.actualContext = string.Empty;
+        return string.Empty;
+    }
+    
+    public override string VisitClassName(CPP14Parser.ClassNameContext context)
+    {
+        return context.Identifier()?.GetText();
+    }
+
     public override object VisitFunctionDefinition(CPP14Parser.FunctionDefinitionContext context)
     {
         var functionName = context.declarator().pointerDeclarator().noPointerDeclarator().noPointerDeclarator()
             .declaratorid().GetText();
 
-        if (this.functionIdentifier == functionName)
+        if (this.functionIdentifier == functionName && this.contextIdentifier == this.actualContext)
         {
             Visit(context.functionBody());
         }
@@ -175,7 +199,8 @@ public class CppActivityDiagramVisitor : CPP14ParserBaseVisitor<object>
         }
 
         long count = _decisionBuilderStack.Count();
-        _decisionBuilderStack.Pop().Item1.AddMerge($"merge-{count}");
+        decisionUniqueueId++;
+        _decisionBuilderStack.Pop().Item1.AddMerge($"merge-{decisionUniqueueId}");
         return null;
     }
 
diff --git a/LanguageRecogniser/Cpp/CppClassDiagramVisitor.cs b/LanguageRecogniser/Cpp/CppClassDiagramVisitor.cs
index 28d4379..69148f2 100644
--- a/LanguageRecogniser/Cpp/CppClassDiagramVisitor.cs
+++ b/LanguageRecogniser/Cpp/CppClassDiagramVisitor.cs
@@ -112,31 +112,31 @@ public class CppClassDiagramVisitor : CPP14ParserBaseVisitor<object>
                     else
                     {
                         // Regular expressions
-                        string aggregationPattern = @"^((std::)?vector<(\w*)\*>|(\w*)\*|(\w*)\* (\w*|\[\]))$";
-                        string compositionPattern = @"^((std::)?vector<(\w*)>|(\w*)|(\w*) (\w*|\[\]))$";
+                        string aggregationPattern = @"^(?:std::)?(?:vector<)?(\w+)\*>?(?![\w*])$";
+                        string compositionPattern = @"^(?:std::)?(?:vector<)?(\w+)>?$";
 
                         // Check if the property type matches aggregation or composition
                         Match aggregationMatch = Regex.Match(atribute.Type, aggregationPattern);
                         Match compositionMatch = Regex.Match(atribute.Type, compositionPattern);
-
-                        if (aggregationMatch.Success && !string.IsNullOrEmpty(aggregationMatch.Groups[3].Value))
+                        int groupMatch = 1;
+                        if (aggregationMatch.Success && !string.IsNullOrEmpty(aggregationMatch.Groups[groupMatch].Value))
                         {
                             // Aggregation type
-                            string? typeName = aggregationMatch.Groups[3].Value; // Second capturing group
-                            _classes.Last().Value.AddAssociation(typeName, actualAccessSpecifier,
+                            string? typeName = aggregationMatch.Groups[groupMatch].Value; // Second capturing group
+                            _classes.Last().Value.AddAssociation(typeName, atribute.Name, actualAccessSpecifier,
                                 AssociationType.Aggregation);
                         }
-                        else if (compositionMatch.Success && !string.IsNullOrEmpty(compositionMatch.Groups[2].Value))
+                        else if (compositionMatch.Success && !string.IsNullOrEmpty(compositionMatch.Groups[groupMatch].Value))
                         {
                             // Composition type
-                            string? typeName = compositionMatch.Groups[3].Value; // Second capturing group
-                            _classes.Last().Value.AddAssociation(typeName, actualAccessSpecifier,
+                            string? typeName = compositionMatch.Groups[groupMatch].Value; // Second capturing group
+                            _classes.Last().Value.AddAssociation(typeName, atribute.Name, actualAccessSpecifier,
                                 AssociationType.Composition);
                         }
                         else
                         {
                             // Default to regular association if no match is found
-                            _classes.Last().Value.AddAssociation(atribute.Type, actualAccessSpecifier,
+                            _classes.Last().Value.AddAssociation(atribute.Type, atribute.Name, actualAccessSpecifier,
                                 AssociationType.Association);
                         }
                     }
diff --git a/UnitTest/ClassDiagramTests.cs b/UnitTest/ClassDiagramTests.cs
index d22f5c9..8674c79 100644
--- a/UnitTest/ClassDiagramTests.cs
+++ b/UnitTest/ClassDiagramTests.cs
@@ -120,7 +120,7 @@ public class ClassDiagramTests
             for (int i = 1; i < numberOfClasses; i++)
             {
                 package.AddClass($"Class{i}", false)
-                    .AddAssociation($"Class{i-1}", VisibilityType.Public, AssociationType.Association);
+                    .AddAssociation($"Class{i-1}", $"name{i-1}",VisibilityType.Public, AssociationType.Association);
             }
             var xmi = ClassDiagramBuilder.BuildDiagram();
         
@@ -164,11 +164,11 @@ public class ClassDiagramTests
         {
             var package1 = ClassDiagramBuilder.AddPackage("Package1");
             package1.AddClass("Class1", false)
-                .AddAssociation("Class2", VisibilityType.Public, AssociationType.Association);
+                .AddAssociation("Class2", "name2",VisibilityType.Public, AssociationType.Association);
 
             var package2 = ClassDiagramBuilder.AddPackage("Package2");
             package2.AddClass("Class2", false)
-                .AddAssociation("Class1", VisibilityType.Public, AssociationType.Aggregation);
+                .AddAssociation("Class1", "name1",VisibilityType.Public, AssociationType.Aggregation);
 
             var xmi = ClassDiagramBuilder.BuildDiagram();
             AssertCommonAssertions(xmi);
@@ -202,7 +202,7 @@ public class ClassDiagramTests
             var class1 = package.AddClass("Class1", false);
             var class2 = package.AddClass("Class2", false);
             
-            class2.AddAssociation(targetAssociation, visibilityType, type);
+            class2.AddAssociation(targetAssociation, "association",visibilityType, type);
 
             if (!isValid)
             {
diff --git a/WebAPI/Controllers/ApiController.cs b/WebAPI/Controllers/ApiController.cs
index 7b7b67e..4ae5993 100644
--- a/WebAPI/Controllers/ApiController.cs
+++ b/WebAPI/Controllers/ApiController.cs
@@ -1,4 +1,5 @@
 using System.ComponentModel.DataAnnotations;
+using System.Runtime.InteropServices;
 using System.Text;
 using Antlr4.Runtime;
 using Antlr4.Runtime.Tree;
@@ -43,6 +44,8 @@ namespace WebAPI.Controllers
             [Range(1, int.MaxValue, ErrorMessage = "Id must be greater than 0")]
             int sourceCodeId,
             
+            string? contextIdentifier,
+            
             [Required(ErrorMessage = "FunctionIdentifier is required")]
             string functionIdentifier)
         {
@@ -72,7 +75,7 @@ namespace WebAPI.Controllers
 
                 if (parser.NumberOfSyntaxErrors == 0)
                 {
-                    CppActivityDiagramVisitor activityDiagramVisitor = new CppActivityDiagramVisitor(diagramBuilder, functionIdentifier);
+                    CppActivityDiagramVisitor activityDiagramVisitor = new CppActivityDiagramVisitor(diagramBuilder, contextIdentifier, functionIdentifier);
                     Console.WriteLine(activityDiagramVisitor.Visit(tree));
                 }
 
-- 
GitLab