From aec886de9a8153f14a1b5d3d39d06bc0b0e1de77 Mon Sep 17 00:00:00 2001 From: atheate Date: Thu, 27 Aug 2026 11:07:33 +0200 Subject: [PATCH] Fix #299 --- .../Extensions/GrammarErrata.cs | 23 +++++++++- .../12a-Dependency.sysml | 11 +++++ .../12b-Allocation-1.sysml | 44 +++++++++++++++++++ .../12b-Allocation.sysml | 22 ++++++++++ .../TextualNotationValidationTestFixture.cs | 3 ++ .../ElementTextualNotationBuilder.cs | 13 +++--- 6 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12a-Dependency.sysml create mode 100644 SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12b-Allocation-1.sysml create mode 100644 SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12b-Allocation.sysml diff --git a/SysML2.NET.CodeGenerator/Extensions/GrammarErrata.cs b/SysML2.NET.CodeGenerator/Extensions/GrammarErrata.cs index 19c3eaa5f..c03ed1bce 100644 --- a/SysML2.NET.CodeGenerator/Extensions/GrammarErrata.cs +++ b/SysML2.NET.CodeGenerator/Extensions/GrammarErrata.cs @@ -89,7 +89,28 @@ public static class GrammarErrata "alternative spelling: rendering the ReturnParameterMembership through the generic " + "parameter path emits 'out verdict', which re-parses as a plain FeatureMembership with " + "direction out and so loses the metaclass. CalculationBodyItem is already declared in the " + - "same file, so the replacement resolves without any further correction.") + "same file, so the replacement resolves without any further correction."), + new("DefinitionElement", + " | InterfaceDefinition\n | PortDefinition", + " | InterfaceDefinition\n | AllocationDefinition\n | PortDefinition", + "SysML 8.2.2.5.2 declares 'AllocationDefinition = OccurrenceDefinitionPrefix 'allocation' " + + "'def' Definition' but no production references it: DefinitionElement lists " + + "ConnectionDefinition, FlowDefinition, InterfaceDefinition and PortDefinition, and omits " + + "AllocationDefinition, so there is no path to it from RootNamespace. OMG has CONFIRMED this " + + "as a specification error — Systems-Modeling/SysML-v2-Release issue 124 item 1, answered " + + "2026-07-29: 'I can confirm that all your items are specification errors, except for item " + + "5'; the correction is routed to a Revision Task Force, so it is not expected in the KEBNF " + + "for some time. The issue's own suggested fix is the one applied here. The pilot " + + "implementation already wires it exactly this way (org.omg.sysml.xtext SysML.xtext, rule " + + "DefinitionElement, AllocationDefinition listed directly after InterfaceDefinition), which " + + "is why the alternative is inserted at that position. There is no admissible alternative " + + "spelling: AllocationDefinition specializes ConnectionDefinition, so without the " + + "alternative the generator emits no dispatch arm and an AllocationDefinition renders " + + "through the ConnectionDefinition arm as 'connection def'. That re-parses to a DIFFERENT " + + "metaclass — AllocationUsage::allocationDefinition (which redefines " + + "ConnectionUsage::connectionDefinition) derives to empty, and the library grounding shifts " + + "from Allocations::Allocation to Connections::Connection. No OCL constraint flags the " + + "downgrade, so nothing but the validation corpus catches it.") ]; /// diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12a-Dependency.sysml b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12a-Dependency.sysml new file mode 100644 index 000000000..f2abad223 --- /dev/null +++ b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12a-Dependency.sysml @@ -0,0 +1,11 @@ +package '12a-Dependency' { + package 'Application Layer'; + package 'Service Layer'; + package 'Data Layer'; + dependency Use from 'Application Layer' to 'Service Layer'; + dependency 'Service Layer' to 'Data Layer'; + attribute x; + attribute y; + attribute z; + dependency z to x, y; +} diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12b-Allocation-1.sysml b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12b-Allocation-1.sysml new file mode 100644 index 000000000..b52d72a64 --- /dev/null +++ b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12b-Allocation-1.sysml @@ -0,0 +1,44 @@ +package '12b-Allocation-1' { + private import SI::*; + private import RequirementModel::*; + private import LogicalModel::*; + private import PhysicalModel::*; + package RequirementModel { + requirement torqueGeneration { + subject generator: TorqueGenerator; + require constraint { generator.generateTorque.torque > 0.0[(N * m)] } + } + } + package LogicalModel { + action def GenerateTorque { + out torque :> ISQ::torque; + } + part def LogicalElement; + part def TorqueGenerator :> LogicalElement { + perform action generateTorque: GenerateTorque; + } + action providePower { + action generateTorque: GenerateTorque; + } + part torqueGenerator: TorqueGenerator { + perform providePower.generateTorque :>> generateTorque; + } + assert satisfy torqueGeneration by torqueGenerator; + } + package PhysicalModel { + part def PhysicalElement; + part def PowerTrain :> PhysicalElement; + part powerTrain: PowerTrain { + part engine { + perform providePower.generateTorque; + } + } + } + allocation def LogicalToPhysical { + end ref logical: LogicalElement; + end ref physical: PhysicalElement; + } + allocation torqueGenAlloc: LogicalToPhysical allocate logical ::> torqueGenerator to physical ::> powerTrain { + allocate torqueGenerator.generateTorque to powerTrain.engine.generateTorque; + } +} diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12b-Allocation.sysml b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12b-Allocation.sysml new file mode 100644 index 000000000..320924086 --- /dev/null +++ b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/12-Dependency Relationships/12b-Allocation.sysml @@ -0,0 +1,22 @@ +package '12b-Allocation' { + private import LogicalModel::*; + private import PhysicalModel::*; + package LogicalModel { + action providePower { + action generateTorque; + } + part torqueGenerator { + perform providePower.generateTorque; + } + } + package PhysicalModel { + part powerTrain { + part engine { + perform providePower.generateTorque; + } + } + } + allocate torqueGenerator to powerTrain { + allocate torqueGenerator.generateTorque to powerTrain.engine.generateTorque; + } +} diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationValidationTestFixture.cs b/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationValidationTestFixture.cs index bf3206c5e..b91d8a22a 100644 --- a/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationValidationTestFixture.cs +++ b/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationValidationTestFixture.cs @@ -110,6 +110,9 @@ public void OneTimeTearDown() [TestCase("10-Analysis and Trades", "10b-Trade-off Among Alternative Configurations.sysmlx")] [TestCase("10-Analysis and Trades", "10c-Fuel Economy Analysis.sysmlx")] [TestCase("10-Analysis and Trades", "10d-Dynamics Analysis.sysmlx")] + [TestCase("12-Dependency Relationships", "12a-Dependency.sysmlx")] + [TestCase("12-Dependency Relationships", "12b-Allocation-1.sysmlx")] + [TestCase("12-Dependency Relationships", "12b-Allocation.sysmlx")] public async Task VerifyValidationTextualNotationXmi(string folderName, string fileName) { var loggerFactory = LoggerFactory.Create(builder => diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs index 24916da39..e0a07953a 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs @@ -62,7 +62,7 @@ public static void BuildIdentification(SysML2.NET.Core.POCO.Root.Elements.IEleme /// /// Builds the Textual Notation string for the rule DefinitionElement - /// DefinitionElement:Element=Package|LibraryPackage|AnnotatingElement|Dependency|AttributeDefinition|EnumerationDefinition|OccurrenceDefinition|IndividualDefinition|ItemDefinition|PartDefinition|ConnectionDefinition|FlowDefinition|InterfaceDefinition|PortDefinition|ActionDefinition|CalculationDefinition|StateDefinition|ConstraintDefinition|RequirementDefinition|ConcernDefinition|CaseDefinition|AnalysisCaseDefinition|VerificationCaseDefinition|UseCaseDefinition|ViewDefinition|ViewpointDefinition|RenderingDefinition|MetadataDefinition|ExtendedDefinition + /// DefinitionElement:Element=Package|LibraryPackage|AnnotatingElement|Dependency|AttributeDefinition|EnumerationDefinition|OccurrenceDefinition|IndividualDefinition|ItemDefinition|PartDefinition|ConnectionDefinition|FlowDefinition|InterfaceDefinition|AllocationDefinition|PortDefinition|ActionDefinition|CalculationDefinition|StateDefinition|ConstraintDefinition|RequirementDefinition|ConcernDefinition|CaseDefinition|AnalysisCaseDefinition|VerificationCaseDefinition|UseCaseDefinition|ViewDefinition|ViewpointDefinition|RenderingDefinition|MetadataDefinition|ExtendedDefinition /// /// The from which the rule should be build /// The providing the serialization context for the current @@ -74,6 +74,9 @@ public static void BuildDefinitionElement(SysML2.NET.Core.POCO.Root.Elements.IEl case SysML2.NET.Core.POCO.Systems.Interfaces.IInterfaceDefinition pocoInterfaceDefinition: InterfaceDefinitionTextualNotationBuilder.BuildInterfaceDefinition(pocoInterfaceDefinition, writerContext, stringBuilder); break; + case SysML2.NET.Core.POCO.Systems.Allocations.IAllocationDefinition pocoAllocationDefinition: + AllocationDefinitionTextualNotationBuilder.BuildAllocationDefinition(pocoAllocationDefinition, writerContext, stringBuilder); + break; case SysML2.NET.Core.POCO.Systems.Connections.IConnectionDefinition pocoConnectionDefinition: ConnectionDefinitionTextualNotationBuilder.BuildConnectionDefinition(pocoConnectionDefinition, writerContext, stringBuilder); break; @@ -101,14 +104,14 @@ public static void BuildDefinitionElement(SysML2.NET.Core.POCO.Root.Elements.IEl case SysML2.NET.Core.POCO.Systems.Cases.ICaseDefinition pocoCaseDefinition: CaseDefinitionTextualNotationBuilder.BuildCaseDefinition(pocoCaseDefinition, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Systems.Views.IRenderingDefinition pocoRenderingDefinition: - RenderingDefinitionTextualNotationBuilder.BuildRenderingDefinition(pocoRenderingDefinition, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Systems.Metadata.IMetadataDefinition pocoMetadataDefinition: + MetadataDefinitionTextualNotationBuilder.BuildMetadataDefinition(pocoMetadataDefinition, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Systems.Views.IViewDefinition pocoViewDefinition: ViewDefinitionTextualNotationBuilder.BuildViewDefinition(pocoViewDefinition, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Systems.Metadata.IMetadataDefinition pocoMetadataDefinition: - MetadataDefinitionTextualNotationBuilder.BuildMetadataDefinition(pocoMetadataDefinition, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Systems.Views.IRenderingDefinition pocoRenderingDefinition: + RenderingDefinitionTextualNotationBuilder.BuildRenderingDefinition(pocoRenderingDefinition, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Systems.Calculations.ICalculationDefinition pocoCalculationDefinition: CalculationDefinitionTextualNotationBuilder.BuildCalculationDefinition(pocoCalculationDefinition, writerContext, stringBuilder);