From 8eee7ab98329f5f4b3074b4cfe0609249b64656c Mon Sep 17 00:00:00 2001 From: MKZaito <127297267+MKZaito@users.noreply.github.com> Date: Fri, 5 Dec 2025 16:15:20 +0100 Subject: [PATCH 01/11] CoCo4 --- .../lang/sysmlv2/cocos/MKPX_CoCo4.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 language/src/main/java/de/monticore/lang/sysmlv2/cocos/MKPX_CoCo4.java diff --git a/language/src/main/java/de/monticore/lang/sysmlv2/cocos/MKPX_CoCo4.java b/language/src/main/java/de/monticore/lang/sysmlv2/cocos/MKPX_CoCo4.java new file mode 100644 index 00000000..d8163e25 --- /dev/null +++ b/language/src/main/java/de/monticore/lang/sysmlv2/cocos/MKPX_CoCo4.java @@ -0,0 +1,100 @@ +/* (c) https://github.com/MontiCore/monticore */ +package de.monticore.lang.sysmlv2.cocos; + +import de.monticore.lang.sysmlbasis._ast.ASTEndpoint; +import de.monticore.lang.sysmlparts._ast.ASTConnectionUsage; +import de.monticore.lang.sysmlparts._cocos.SysMLPartsASTConnectionUsageCoCo; +import de.monticore.lang.sysmlparts._symboltable.ISysMLPartsScope; +import de.monticore.lang.sysmlparts._symboltable.PartDefSymbol; +import de.monticore.lang.sysmlparts._symboltable.PartUsageSymbol; +import de.monticore.symboltable.modifiers.AccessModifier; +import de.se_rwth.commons.logging.Log; + +import java.util.List; +import java.util.Optional; + +/** + * MKPX_CoCo4: + * In einer Verbindung "connect a.b to c.d" muss jeder verwendete (qualifizierte) Portname existieren. + */ +public class MKPX_CoCo4 implements SysMLPartsASTConnectionUsageCoCo { + + @Override + public void check(ASTConnectionUsage node) { + if (!node.isPresentSrc() || !node.isPresentTgt()) { + return; // keine Verbindung + } + + ISysMLPartsScope scope = node.getEnclosingScope(); + + checkEndpoint(scope, node.getSrc(), node); + checkEndpoint(scope, node.getTgt(), node); + } + + protected void checkEndpoint(ISysMLPartsScope scope, + ASTEndpoint endpoint, + ASTConnectionUsage conn) { + String qname = endpointQName(endpoint); + if (qname.isEmpty()) { + return; + } + + String[] parts = qname.split("\\."); + + // Qualifizierter Name: a.b -> resolve a (PartUsage), dann b in PartDef + if (parts.length >= 2) { + String partName = parts[0]; + String portName = parts[parts.length - 1]; + + Optional partOpt = scope.resolvePartUsageLocally(partName); + + if (partOpt.isEmpty()) { + // Existenz der Subkomponente wird bereits in MKPX_CoCo3 geprüft. + return; + } + + var partDefOpt = partOpt.get().getPartDef(); + if (partDefOpt.isEmpty()) { + Log.error( + "0xMKPX04 The subcomponent '" + partName + "' does not reference a valid part definition.", + conn.get_SourcePositionStart(), + conn.get_SourcePositionEnd() + ); + return; + } + + PartDefSymbol partDef = partDefOpt.get(); + boolean portExistsInDef = partDef.getSpannedScope() + .resolvePortUsageLocallyMany(false, portName, AccessModifier.ALL_INCLUSION, p -> true) + .size() == 1; + + if (!portExistsInDef) { + Log.error( + "0xMKPX04 The port '" + portName + "' does not exist in the definition of subcomponent '" + + partName + "'.", + conn.get_SourcePositionStart(), + conn.get_SourcePositionEnd() + ); + } + } + else { + // Unqualifiziert: Port der Oberkomponente muss lokal existieren + String portName = parts[0]; + List localPorts = scope.resolvePortUsageLocallyMany( + false, portName, AccessModifier.ALL_INCLUSION, p -> true); + if (localPorts.isEmpty()) { + Log.error( + "0xMKPX04 The port used in 'connect' '" + portName + + "' does not exist in the parent component.", + conn.get_SourcePositionStart(), + conn.get_SourcePositionEnd() + ); + } + } + } + + /** Liefert den qualifizierten Namen des Endpunkts als String. */ + protected String endpointQName(ASTEndpoint ep) { + return ep.getMCQualifiedName() != null ? ep.getMCQualifiedName().toString() : ""; + } +} From d9b52bbfb5e8c637fa120979d38fa6add0694407 Mon Sep 17 00:00:00 2001 From: MKZaito <127297267+MKZaito@users.noreply.github.com> Date: Tue, 9 Dec 2025 18:28:02 +0100 Subject: [PATCH 02/11] not responsible for undefined parts covered in MKPX_CoCo3 --- .../java/de/monticore/lang/sysmlv2/cocos/MKPX_CoCo4.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/language/src/main/java/de/monticore/lang/sysmlv2/cocos/MKPX_CoCo4.java b/language/src/main/java/de/monticore/lang/sysmlv2/cocos/MKPX_CoCo4.java index d8163e25..ff9a357b 100644 --- a/language/src/main/java/de/monticore/lang/sysmlv2/cocos/MKPX_CoCo4.java +++ b/language/src/main/java/de/monticore/lang/sysmlv2/cocos/MKPX_CoCo4.java @@ -55,11 +55,7 @@ protected void checkEndpoint(ISysMLPartsScope scope, var partDefOpt = partOpt.get().getPartDef(); if (partDefOpt.isEmpty()) { - Log.error( - "0xMKPX04 The subcomponent '" + partName + "' does not reference a valid part definition.", - conn.get_SourcePositionStart(), - conn.get_SourcePositionEnd() - ); + // CoCo3 return; } From cea7d3f5d2a6dd9bbe6acb3bf3dc84fe095eb8a4 Mon Sep 17 00:00:00 2001 From: MKZaito <127297267+MKZaito@users.noreply.github.com> Date: Tue, 9 Dec 2025 18:28:45 +0100 Subject: [PATCH 03/11] Test for MKPX_CoCo4 --- .../src/test/java/cocos/MKPXCoCo4Test.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 language/src/test/java/cocos/MKPXCoCo4Test.java diff --git a/language/src/test/java/cocos/MKPXCoCo4Test.java b/language/src/test/java/cocos/MKPXCoCo4Test.java new file mode 100644 index 00000000..7048ca2f --- /dev/null +++ b/language/src/test/java/cocos/MKPXCoCo4Test.java @@ -0,0 +1,76 @@ +/* (c) https://github.com/MontiCore/monticore */ +package cocos; + +import de.monticore.lang.sysmlparts._cocos.SysMLPartsASTConnectionUsageCoCo; +import de.monticore.lang.sysmlv2.SysMLv2Mill; +import de.monticore.lang.sysmlv2._ast.ASTSysMLModel; +import de.monticore.lang.sysmlv2._cocos.SysMLv2CoCoChecker; +import de.monticore.lang.sysmlv2.cocos.MKPX_CoCo4; +import de.se_rwth.commons.logging.Log; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class MKPXCoCo4Test { + + @BeforeAll + public static void init() { + Log.init(); + SysMLv2Mill.init(); + } + + @BeforeEach + public void reset() { + SysMLv2Mill.globalScope().clear(); + Log.getFindings().clear(); + Log.enableFailQuick(true); + } + + @Nested + public class PortExistenceTests { + @Test + public void testValid() throws IOException { + String validModel = + "part def A { port p; }" + + "part def B { port q: ~; }" + + "part def System {" + + "part a: A;" + + "part b: B;" + + "connect a.p to b.q;" + + "}"; + + ASTSysMLModel ast = SysMLv2Mill.parser().parse_String(validModel).get(); + SysMLv2Mill.scopesGenitorDelegator().createFromAST(ast); + var checker = new SysMLv2CoCoChecker(); + checker.addCoCo((SysMLPartsASTConnectionUsageCoCo) new MKPX_CoCo4()); + checker.checkAll(ast); + assertTrue(Log.getFindings().isEmpty()); + } + + @Test + public void testInvalid() throws IOException { + String invalidModel = + "part def A { port p; }" + + "part def B { port q: ~; }" + + "part def System {" + + "part a: A;" + + "part b: B;" + + "connect a.wrongName to b.q;" + + "}"; + + ASTSysMLModel ast = SysMLv2Mill.parser().parse_String(invalidModel).get(); + SysMLv2Mill.scopesGenitorDelegator().createFromAST(ast); + var checker = new SysMLv2CoCoChecker(); + checker.addCoCo((SysMLPartsASTConnectionUsageCoCo) new MKPX_CoCo4()); + Log.enableFailQuick(false); + checker.checkAll(ast); + assertTrue(Log.getFindings().stream() + .anyMatch(f -> f.getMsg().contains("0xMKPX04"))); + } + } +} From aaf916354b4061619a4ff994196ca2c4cb17a405 Mon Sep 17 00:00:00 2001 From: MKZaito <127297267+MKZaito@users.noreply.github.com> Date: Tue, 9 Dec 2025 18:51:05 +0100 Subject: [PATCH 04/11] add parser and Model Path --- language/src/test/java/cocos/MKPXCoCo4Test.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/language/src/test/java/cocos/MKPXCoCo4Test.java b/language/src/test/java/cocos/MKPXCoCo4Test.java index 7048ca2f..92730a3d 100644 --- a/language/src/test/java/cocos/MKPXCoCo4Test.java +++ b/language/src/test/java/cocos/MKPXCoCo4Test.java @@ -18,6 +18,10 @@ public class MKPXCoCo4Test { + private static final String MODEL_PATH = "src/test/resources/parser"; + + private SysMLv2Parser parser = SysMLv2Mill.parser(); + @BeforeAll public static void init() { Log.init(); From 0911cbf39e65d25597bd71f2f7eeafa41b6ad127 Mon Sep 17 00:00:00 2001 From: MKZaito <127297267+MKZaito@users.noreply.github.com> Date: Tue, 9 Dec 2025 19:00:10 +0100 Subject: [PATCH 05/11] Missing Import SysMLv2Parser --- language/src/test/java/cocos/MKPXCoCo4Test.java | 1 + 1 file changed, 1 insertion(+) diff --git a/language/src/test/java/cocos/MKPXCoCo4Test.java b/language/src/test/java/cocos/MKPXCoCo4Test.java index 92730a3d..c2b0285e 100644 --- a/language/src/test/java/cocos/MKPXCoCo4Test.java +++ b/language/src/test/java/cocos/MKPXCoCo4Test.java @@ -5,6 +5,7 @@ import de.monticore.lang.sysmlv2.SysMLv2Mill; import de.monticore.lang.sysmlv2._ast.ASTSysMLModel; import de.monticore.lang.sysmlv2._cocos.SysMLv2CoCoChecker; +import de.monticore.lang.sysmlv2._parser.SysMLv2Parser; import de.monticore.lang.sysmlv2.cocos.MKPX_CoCo4; import de.se_rwth.commons.logging.Log; import org.junit.jupiter.api.BeforeAll; From de0e731358a61b0e9a746d79dba67cccc10e5038 Mon Sep 17 00:00:00 2001 From: MKZaito <127297267+MKZaito@users.noreply.github.com> Date: Tue, 9 Dec 2025 19:16:33 +0100 Subject: [PATCH 06/11] Missing import assertFalse --- language/src/test/java/cocos/MKPXCoCo4Test.java | 1 + 1 file changed, 1 insertion(+) diff --git a/language/src/test/java/cocos/MKPXCoCo4Test.java b/language/src/test/java/cocos/MKPXCoCo4Test.java index c2b0285e..86a32c53 100644 --- a/language/src/test/java/cocos/MKPXCoCo4Test.java +++ b/language/src/test/java/cocos/MKPXCoCo4Test.java @@ -15,6 +15,7 @@ import java.io.IOException; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class MKPXCoCo4Test { From 27c4e78b3fd8e0c1f39970050ada885aaa4517b8 Mon Sep 17 00:00:00 2001 From: MKZaito <127297267+MKZaito@users.noreply.github.com> Date: Tue, 9 Dec 2025 19:55:55 +0100 Subject: [PATCH 07/11] Update MKPXCoCo4Test.java --- language/src/test/java/cocos/MKPXCoCo4Test.java | 1 + 1 file changed, 1 insertion(+) diff --git a/language/src/test/java/cocos/MKPXCoCo4Test.java b/language/src/test/java/cocos/MKPXCoCo4Test.java index 86a32c53..e5bdc25e 100644 --- a/language/src/test/java/cocos/MKPXCoCo4Test.java +++ b/language/src/test/java/cocos/MKPXCoCo4Test.java @@ -2,6 +2,7 @@ package cocos; import de.monticore.lang.sysmlparts._cocos.SysMLPartsASTConnectionUsageCoCo; +import de.monticore.lang.sysmlparts._cocos.SysMLPartsASTPartDefCoCo; import de.monticore.lang.sysmlv2.SysMLv2Mill; import de.monticore.lang.sysmlv2._ast.ASTSysMLModel; import de.monticore.lang.sysmlv2._cocos.SysMLv2CoCoChecker; From 9542181b8db96b7954df2540e7b2d9f4f401b847 Mon Sep 17 00:00:00 2001 From: MKZaito <127297267+MKZaito@users.noreply.github.com> Date: Tue, 9 Dec 2025 20:00:55 +0100 Subject: [PATCH 08/11] Update MKPXCoCo4Test.java --- language/src/test/java/cocos/MKPXCoCo4Test.java | 1 + 1 file changed, 1 insertion(+) diff --git a/language/src/test/java/cocos/MKPXCoCo4Test.java b/language/src/test/java/cocos/MKPXCoCo4Test.java index e5bdc25e..c2860548 100644 --- a/language/src/test/java/cocos/MKPXCoCo4Test.java +++ b/language/src/test/java/cocos/MKPXCoCo4Test.java @@ -3,6 +3,7 @@ import de.monticore.lang.sysmlparts._cocos.SysMLPartsASTConnectionUsageCoCo; import de.monticore.lang.sysmlparts._cocos.SysMLPartsASTPartDefCoCo; +import de.monticore.lang.sysmlparts._cocos.SysMLPartsASTPartUsageCoCo; import de.monticore.lang.sysmlv2.SysMLv2Mill; import de.monticore.lang.sysmlv2._ast.ASTSysMLModel; import de.monticore.lang.sysmlv2._cocos.SysMLv2CoCoChecker; From b8619d703f4d1a117623d3bdd886b8601b7903c4 Mon Sep 17 00:00:00 2001 From: MKZaito <127297267+MKZaito@users.noreply.github.com> Date: Tue, 9 Dec 2025 20:18:46 +0100 Subject: [PATCH 09/11] Update MKPXCoCo4Test.java --- language/src/test/java/cocos/MKPXCoCo4Test.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/language/src/test/java/cocos/MKPXCoCo4Test.java b/language/src/test/java/cocos/MKPXCoCo4Test.java index c2860548..2680f23b 100644 --- a/language/src/test/java/cocos/MKPXCoCo4Test.java +++ b/language/src/test/java/cocos/MKPXCoCo4Test.java @@ -40,7 +40,7 @@ public void reset() { } @Nested - public class PortExistenceTests { + public class MKPXCoCo4Tests { @Test public void testValid() throws IOException { String validModel = From 10fe4d64c5de2b99d93e7af8b31647984bc02f22 Mon Sep 17 00:00:00 2001 From: MKZaito <127297267+MKZaito@users.noreply.github.com> Date: Tue, 9 Dec 2025 21:16:33 +0100 Subject: [PATCH 10/11] Update MKPXCoCo4Test.java --- language/src/test/java/cocos/MKPXCoCo4Test.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/language/src/test/java/cocos/MKPXCoCo4Test.java b/language/src/test/java/cocos/MKPXCoCo4Test.java index 2680f23b..79159369 100644 --- a/language/src/test/java/cocos/MKPXCoCo4Test.java +++ b/language/src/test/java/cocos/MKPXCoCo4Test.java @@ -44,8 +44,8 @@ public class MKPXCoCo4Tests { @Test public void testValid() throws IOException { String validModel = - "part def A { port p; }" - + "part def B { port q: ~; }" + "part def A { port p int; }" + + "part def B { port q: ~int; }" + "part def System {" + "part a: A;" + "part b: B;" @@ -55,7 +55,7 @@ public void testValid() throws IOException { ASTSysMLModel ast = SysMLv2Mill.parser().parse_String(validModel).get(); SysMLv2Mill.scopesGenitorDelegator().createFromAST(ast); var checker = new SysMLv2CoCoChecker(); - checker.addCoCo((SysMLPartsASTConnectionUsageCoCo) new MKPX_CoCo4()); + checker.addCoCo(new MKPX_CoCo4()); checker.checkAll(ast); assertTrue(Log.getFindings().isEmpty()); } @@ -63,8 +63,8 @@ public void testValid() throws IOException { @Test public void testInvalid() throws IOException { String invalidModel = - "part def A { port p; }" - + "part def B { port q: ~; }" + "part def A { port p int; }" + + "part def B { port q: ~int; }" + "part def System {" + "part a: A;" + "part b: B;" @@ -74,7 +74,7 @@ public void testInvalid() throws IOException { ASTSysMLModel ast = SysMLv2Mill.parser().parse_String(invalidModel).get(); SysMLv2Mill.scopesGenitorDelegator().createFromAST(ast); var checker = new SysMLv2CoCoChecker(); - checker.addCoCo((SysMLPartsASTConnectionUsageCoCo) new MKPX_CoCo4()); + checker.addCoCo(new MKPX_CoCo4()); Log.enableFailQuick(false); checker.checkAll(ast); assertTrue(Log.getFindings().stream() From aea19d5e8b468d0246497a1a598656c7e28bdec1 Mon Sep 17 00:00:00 2001 From: MKZaito <127297267+MKZaito@users.noreply.github.com> Date: Wed, 10 Dec 2025 12:01:08 +0100 Subject: [PATCH 11/11] syntax error fixed --- language/src/test/java/cocos/MKPXCoCo4Test.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/language/src/test/java/cocos/MKPXCoCo4Test.java b/language/src/test/java/cocos/MKPXCoCo4Test.java index 79159369..180aa5bd 100644 --- a/language/src/test/java/cocos/MKPXCoCo4Test.java +++ b/language/src/test/java/cocos/MKPXCoCo4Test.java @@ -44,7 +44,7 @@ public class MKPXCoCo4Tests { @Test public void testValid() throws IOException { String validModel = - "part def A { port p int; }" + "part def A { port p: int; }" + "part def B { port q: ~int; }" + "part def System {" + "part a: A;" @@ -63,7 +63,7 @@ public void testValid() throws IOException { @Test public void testInvalid() throws IOException { String invalidModel = - "part def A { port p int; }" + "part def A { port p: int; }" + "part def B { port q: ~int; }" + "part def System {" + "part a: A;"