diff --git a/SysML2.NET.CodeGenerator/Generators/UmlHandleBarsGenerators/UmlCoreTextualNotationBuilderGenerator.cs b/SysML2.NET.CodeGenerator/Generators/UmlHandleBarsGenerators/UmlCoreTextualNotationBuilderGenerator.cs
index 29812bdb2..c8fb60618 100644
--- a/SysML2.NET.CodeGenerator/Generators/UmlHandleBarsGenerators/UmlCoreTextualNotationBuilderGenerator.cs
+++ b/SysML2.NET.CodeGenerator/Generators/UmlHandleBarsGenerators/UmlCoreTextualNotationBuilderGenerator.cs
@@ -59,6 +59,12 @@ public class UmlCoreTextualNotationBuilderGenerator: UmlHandleBarsGenerator
///
private const string SharedBuilderTemplateName = "core-textual-notation-shared-builder-template";
+ ///
+ /// The root rule from which grammar reachability is computed to flag
+ /// methods.
+ ///
+ private const string RootRuleName = "RootNamespace";
+
///
/// Register the custom helpers
///
@@ -173,6 +179,10 @@ private async Task GenerateBuilderClassesInternal(XmiReaderResult xmiReaderResul
{
var template = this.Templates[BuilderTemplateName];
+ var unreachableRuleNames = textualNotationSpecification.ComputeUnreachableRuleNames(RootRuleName)
+ .Except(RulesHelper.HandCodedReachableRuleNames)
+ .ToHashSet();
+
var namedElements = xmiReaderResult.QueryContainedAndImported("SysML")
.SelectMany(x => x.PackagedElement.OfType())
.ToList();
@@ -202,7 +212,7 @@ private async Task GenerateBuilderClassesInternal(XmiReaderResult xmiReaderResul
{
var targetClassContext = namedElements.Single(x => x.Name == rulesPerType.Key);
- var generatedBuilder = template(new {Context = targetClassContext, Rules = rulesPerType.Value, AllRules = textualNotationSpecification.Rules});
+ var generatedBuilder = template(new {Context = targetClassContext, Rules = rulesPerType.Value, AllRules = textualNotationSpecification.Rules, UnreachableRuleNames = unreachableRuleNames});
generatedBuilder = this.CodeCleanup(generatedBuilder);
var fileName = $"{targetClassContext.Name.CapitalizeFirstLetter()}TextualNotationBuilder.cs";
@@ -282,7 +292,11 @@ private async Task GenerateSharedBuilderInternal(XmiReaderResult xmiReaderResult
return;
}
- var generatedBuilder = template(new { Entries = entries, AllRules = textualNotationSpecification.Rules });
+ var unreachableRuleNames = textualNotationSpecification.ComputeUnreachableRuleNames(RootRuleName)
+ .Except(RulesHelper.HandCodedReachableRuleNames)
+ .ToHashSet();
+
+ var generatedBuilder = template(new { Entries = entries, AllRules = textualNotationSpecification.Rules, UnreachableRuleNames = unreachableRuleNames });
generatedBuilder = this.CodeCleanup(generatedBuilder);
await WriteAsync(generatedBuilder, outputDirectory, $"{RulesHelper.SharedBuilderClassName}.cs");
diff --git a/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationRule.cs b/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationRule.cs
index c20e25336..bee5175a5 100644
--- a/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationRule.cs
+++ b/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationRule.cs
@@ -359,5 +359,88 @@ when string.Equals(assignmentElement.Property, propertyName, StringComparison.Or
}
}
}
+
+ ///
+ /// Recursively resolves the names of all rules transitively reachable from this rule via
+ /// NonTerminal references, including this rule itself.
+ ///
+ /// All available rules for resolving NonTerminal references
+ /// The set of reachable rule names
+ public IReadOnlySet QueryReachableRuleNames(IReadOnlyList allRules)
+ {
+ var visited = new HashSet();
+ CollectReachableRuleNames(this, allRules, visited);
+ return visited;
+ }
+
+ ///
+ /// Recursively collects the names of rules reachable from
+ ///
+ /// The rule to inspect
+ /// All available rules for resolving NonTerminal references
+ /// The accumulated set of reachable rule names
+ private static void CollectReachableRuleNames(TextualNotationRule rule, IReadOnlyList allRules, HashSet visited)
+ {
+ if (!visited.Add(rule.RuleName))
+ {
+ return;
+ }
+
+ foreach (var alternative in rule.Alternatives)
+ {
+ CollectReachableRuleNamesFromElements(alternative.Elements, allRules, visited);
+ }
+ }
+
+ ///
+ /// Recursively collects reachable rule names from a list of
+ ///
+ /// The elements to inspect
+ /// All available rules for resolving NonTerminal references
+ /// The accumulated set of reachable rule names
+ private static void CollectReachableRuleNamesFromElements(IEnumerable elements, IReadOnlyList allRules, HashSet visited)
+ {
+ foreach (var element in elements)
+ {
+ switch (element)
+ {
+ case AssignmentElement { Value: NonTerminalElement valueNonTerminal }:
+ var valueRule = allRules.SingleOrDefault(x => x.RuleName == valueNonTerminal.Name);
+
+ if (valueRule != null)
+ {
+ CollectReachableRuleNames(valueRule, allRules, visited);
+ }
+
+ break;
+
+ case AssignmentElement { Value: GroupElement valueGroupElement }:
+ foreach (var valueGroupAlternative in valueGroupElement.Alternatives)
+ {
+ CollectReachableRuleNamesFromElements(valueGroupAlternative.Elements, allRules, visited);
+ }
+
+ break;
+
+ case NonTerminalElement nonTerminalElement:
+ var referencedRule = allRules.SingleOrDefault(x => x.RuleName == nonTerminalElement.Name);
+
+ if (referencedRule != null)
+ {
+ CollectReachableRuleNames(referencedRule, allRules, visited);
+ }
+
+ break;
+
+ case GroupElement groupElement:
+ foreach (var groupAlternative in groupElement.Alternatives)
+ {
+ CollectReachableRuleNamesFromElements(groupAlternative.Elements, allRules, visited);
+ }
+
+ break;
+ }
+ }
+ }
}
}
diff --git a/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationSpecification.cs b/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationSpecification.cs
index affae75c2..964654219 100644
--- a/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationSpecification.cs
+++ b/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationSpecification.cs
@@ -20,7 +20,9 @@
namespace SysML2.NET.CodeGenerator.Grammar.Model
{
+ using System;
using System.Collections.Generic;
+ using System.Linq;
///
/// Provides access to all defined into the textual notation specification
@@ -31,5 +33,27 @@ public class TextualNotationSpecification
/// Gets the collection of all
///
public List Rules { get; } = [];
+
+ ///
+ /// Computes the names of rules that have no incoming reference — directly or transitively —
+ /// from the rule named , and are therefore unreachable when
+ /// generating from that root.
+ ///
+ /// The name of the root rule (e.g. RootNamespace)
+ /// The set of unreachable rule names
+ /// If no rule named exists
+ public IReadOnlySet ComputeUnreachableRuleNames(string rootRuleName)
+ {
+ var rootRule = this.Rules.SingleOrDefault(x => x.RuleName == rootRuleName);
+
+ if (rootRule == null)
+ {
+ throw new ArgumentException($"No rule named '{rootRuleName}' exists in this specification.", nameof(rootRuleName));
+ }
+
+ var reachableRuleNames = rootRule.QueryReachableRuleNames(this.Rules);
+
+ return this.Rules.Select(x => x.RuleName).Where(name => !reachableRuleNames.Contains(name)).ToHashSet();
+ }
}
}
diff --git a/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs b/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs
index bbeb610f1..0636da97d 100644
--- a/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs
+++ b/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs
@@ -51,6 +51,23 @@ public static void RegisterRulesHelper(this IHandlebars handlebars)
{
var processor = new RuleProcessor();
+ handlebars.RegisterHelper("RulesHelper.IsRuleUnreachable", (_, arguments) =>
+ {
+ if (arguments.Length != 2)
+ {
+ throw new ArgumentException("RulesHelper.IsRuleUnreachable expects to have 2 arguments");
+ }
+
+ if (arguments[0] is not string ruleName)
+ {
+ throw new ArgumentException("RulesHelper.IsRuleUnreachable expects a rule name string as first argument");
+ }
+
+ return arguments[1] is not IReadOnlySet unreachableRuleNames
+ ? throw new ArgumentException("RulesHelper.IsRuleUnreachable expects a set of unreachable rule names as second argument")
+ : unreachableRuleNames.Contains(ruleName);
+ });
+
handlebars.RegisterHelper("RulesHelper.ContainsAnyDispatcherRules", (_, arguments) =>
{
if (arguments.Length != 1)
@@ -183,6 +200,17 @@ private static bool RequiresHandCodedBody(string ruleName)
return string.Equals(ruleName, "FunctionOperationExpression", StringComparison.Ordinal)
;
}
+ ///
+ /// Rule names the KEBNF-text-only reachability walk cannot see being reached, because the
+ /// only remaining reference to them lives in a hand-coded Build{Rule}HandCoded companion
+ /// rather than in the merged grammar. PayloadFeatureMember is called from
+ /// SharedTextualNotationBuilder.BuildFlowDeclarationHandCoded, which reimplements KerML's
+ /// FlowDeclaration : Flow - a rule the SysML-overrides-KerML merge (keyed on bare rule name)
+ /// drops in favour of SysML's unrelated FlowDeclaration : FlowUsage, taking with it the
+ /// merged grammar's only textual reference to PayloadFeatureMember.
+ ///
+ public static readonly IReadOnlySet HandCodedReachableRuleNames = new HashSet { "PayloadFeatureMember" };
+
///
/// Determines whether targets an IOperatorExpression
/// (or any of its subclasses) as the rule's effective metaclass. Used by
diff --git a/SysML2.NET.CodeGenerator/Templates/Uml/core-textual-notation-builder-template.hbs b/SysML2.NET.CodeGenerator/Templates/Uml/core-textual-notation-builder-template.hbs
index 9707f02ab..4116fefbe 100644
--- a/SysML2.NET.CodeGenerator/Templates/Uml/core-textual-notation-builder-template.hbs
+++ b/SysML2.NET.CodeGenerator/Templates/Uml/core-textual-notation-builder-template.hbs
@@ -41,6 +41,9 @@ namespace SysML2.NET.Serializer.TextualNotation.Writers
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ {{#if (RulesHelper.IsRuleUnreachable rule.RuleName ../this.UnreachableRuleNames)}}
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
+ {{/if}}
public static void Build{{rule.RuleName}}({{ #NamedElement.WriteFullyQualifiedTypeName ../this.Context }} poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
{{RulesHelper.WriteRule rule ../this.Context ../this.AllRules}}
diff --git a/SysML2.NET.CodeGenerator/Templates/Uml/core-textual-notation-shared-builder-template.hbs b/SysML2.NET.CodeGenerator/Templates/Uml/core-textual-notation-shared-builder-template.hbs
index 943e07b80..f8251592e 100644
--- a/SysML2.NET.CodeGenerator/Templates/Uml/core-textual-notation-shared-builder-template.hbs
+++ b/SysML2.NET.CodeGenerator/Templates/Uml/core-textual-notation-shared-builder-template.hbs
@@ -44,6 +44,9 @@ namespace SysML2.NET.Serializer.TextualNotation.Writers
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ {{#if (RulesHelper.IsRuleUnreachable entry.Rule.RuleName ../this.UnreachableRuleNames)}}
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
+ {{/if}}
public static void Build{{entry.Rule.RuleName}}({{ #NamedElement.WriteFullyQualifiedTypeName entry.TargetClass }} poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
{{RulesHelper.WriteRule entry.Rule entry.TargetClass ../this.AllRules}}
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Arrowhead Framework Example/AHFNorwayTopics.sysml b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Arrowhead Framework Example/AHFNorwayTopics.sysml
new file mode 100644
index 000000000..d9aea63a8
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Arrowhead Framework Example/AHFNorwayTopics.sysml
@@ -0,0 +1,129 @@
+package AHFNorway {
+ doc
+ /* This is the Norwegian use-case for Arrowhead Framework */
+ private import AHFProfileLib::*;
+ private import AHFProfileMetadata::*;
+ private import AHFCoreLib::**;
+ private import ScalarValues::*;
+ #service def APISService {
+ doc
+ /* Service design */
+ attribute :>> SD::serviceDefinition = "APISPullService";
+ attribute :>> SD::intrfce_protocol = "{JSON}";
+ attribute :>> SD::serviceURL = "pull";
+ }
+ #servicedd port def APIS_DD :> APISService {
+ doc
+ /* Service design description with nested protocol-specific ports */
+ #idd port APIS_HTTP {
+ out cll: CallGiveItems;
+ in retrn: ResultGiveItems;
+ }
+ #idd port APIS_MQTT {
+ out pub: Publish;
+ out retall: Return_AllItems;
+ in subscr: Subscribe;
+ }
+ }
+ attribute def Publish {
+ ref nametopic: String;
+ }
+ attribute def Subscribe {
+ ref nametopic: String;
+ }
+ attribute def Return_AllItems {
+ ref itms: String;
+ }
+ attribute def Subscribe_giveItems {
+ ref itms: String;
+ }
+ attribute def Return_Ack {
+ ref ack: Boolean;
+ }
+ attribute def CallGiveItems {
+ ref itms: String;
+ }
+ attribute def ResultGiveItems {
+ ref ack: Boolean;
+ }
+ #clouddd AHFNorway_LocalCloudDD :> ArrowheadCore {
+ #systemdd TellUConsumer {
+ #servicedd serviceDiscovery: ~ServiceDiscoveryDD;
+ #servicedd apisp: APIS_DD;
+ attribute :>> SysD::systemname = "UngerApisClient";
+ attribute :>> SysD::address = "Unger_network_ip";
+ attribute :>> SysD::portno = 0;
+ state TellUbehavior {
+ entry send new CallGiveItems("All the items") via apisp.APIS_HTTP;
+ then Wait;
+ state Wait;
+ accept rs: ResultGiveItems then Wait;
+ }
+ }
+ #systemdd APISProducer {
+ #servicedd serviceDiscovery: ~ServiceDiscoveryDD;
+ #servicedd tellu: ~APIS_DD;
+ #servicedd apisc: APIS_DD;
+ :>> SysD::systemname = "PrediktorApisServer";
+ :>> SysD::address = "Prediktor_network_ip";
+ :>> SysD::portno = 6565;
+ attribute x: Boolean;
+ action giveItems :> SysDD::ServiceMethod {
+ in itms: String;
+ out ack: Boolean;
+ /* Forward itms and return an ack */
+ first start;
+ then send new Return_AllItems() via apisc.APIS_MQTT;
+ ref success = true;
+ bind ack = success;
+ }
+ state APISPbehavior {
+ entry send new Publish("Return_AllItems") via apisc.APIS_MQTT;
+ then WaitOnData;
+ state WaitOnData;
+ accept cl: CallGiveItems via tellu.APIS_HTTP do action {
+ first start;
+ then action giveItems {
+ in itms = cl.itms;
+ out ack = x;
+ }
+ then send new ResultGiveItems(x) via tellu.APIS_HTTP;
+ }
+ then WaitOnData;
+ }
+ }
+ #systemdd APISConsumer {
+ #servicedd serviceDiscovery: ~ServiceDiscovery;
+ #servicedd apisp: ~APIS_DD;
+ :>> SysD::systemname = "TellUClient";
+ :>> SysD::address = "Prediktor_network_ip";
+ :>> SysD::portno = 1;
+ state MQTT_APISP {
+ entry send new Subscribe("Return_AllItems") via apisp.APIS_MQTT;
+ then Idle;
+ state Idle;
+ accept Return_AllItems via apisp.APIS_MQTT then Idle;
+ }
+ }
+ part MQTTServer {
+ port getTopic: ~APIS_DD;
+ port giveTopic: APIS_DD;
+ state Serve {
+ entry;
+ then Publ;
+ state Publ;
+ accept pub: Publish via getTopic.APIS_MQTT then Subsr;
+ state Subsr;
+ accept Subscribe via giveTopic.APIS_MQTT then Idle;
+ state Idle;
+ accept retrnall: Return_AllItems via getTopic.APIS_MQTT do send retrnall via giveTopic.APIS_MQTT then Idle;
+ }
+ }
+ connect APISProducer.apisc to MQTTServer.getTopic;
+ connect MQTTServer.giveTopic to APISConsumer.apisp;
+ connect TellUConsumer.apisp to APISProducer.tellu;
+ connect APISProducer.serviceDiscovery to service_registry.serviceDiscovery;
+ connect TellUConsumer.serviceDiscovery to service_registry.serviceDiscovery;
+ connect APISConsumer.serviceDiscovery to service_registry.serviceDiscovery;
+ }
+}
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Binding Connectors Example/BindingConnectorsExample.sysml b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Binding Connectors Example/BindingConnectorsExample.sysml
new file mode 100644
index 000000000..015e486a4
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Binding Connectors Example/BindingConnectorsExample.sysml
@@ -0,0 +1,24 @@
+package 'Binding Connectors Example-1' {
+ private import 'Port Example'::*;
+ part def Vehicle;
+ part def FuelPump;
+ part def FuelTank;
+ part vehicle: Vehicle {
+ part tank: FuelTankAssembly {
+ port :>> fuelTankPort {
+ out item :>> fuelSupply;
+ in item :>> fuelReturn;
+ }
+ bind fuelTankPort.fuelSupply = pump.pumpOut;
+ bind fuelTankPort.fuelReturn = tank.fuelIn;
+ part pump: FuelPump {
+ out item pumpOut: Fuel;
+ in item pumpIn: Fuel;
+ }
+ part tank: FuelTank {
+ out item fuelOut: Fuel;
+ in item fuelIn: Fuel;
+ }
+ }
+ }
+}
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Flow Usage Example/FlowUsageExample.sysml b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Flow Usage Example/FlowUsageExample.sysml
new file mode 100644
index 000000000..6f9e4a077
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Flow Usage Example/FlowUsageExample.sysml
@@ -0,0 +1,10 @@
+package 'Flow Usage Example' {
+ private import 'Port Example'::*;
+ part def Vehicle;
+ part vehicle: Vehicle {
+ part tankAssy: FuelTankAssembly;
+ part eng: Engine;
+ flow of Fuel from tankAssy.fuelTankPort.fuelSupply to eng.engineFuelPort.fuelSupply;
+ flow of Fuel from eng.engineFuelPort.fuelReturn to tankAssy.fuelTankPort.fuelReturn;
+ }
+}
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Generalization Example/GeneralizationExample.sysml b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Generalization Example/GeneralizationExample.sysml
new file mode 100644
index 000000000..b59839f69
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Generalization Example/GeneralizationExample.sysml
@@ -0,0 +1,12 @@
+package 'Generalization Example' {
+ abstract part def Vehicle;
+ part def HumanDrivenVehicle :> Vehicle {
+ ref part driver: Person;
+ }
+ part def PoweredVehicle :> Vehicle {
+ part eng: Engine;
+ }
+ part def HumanDrivenPoweredVehicle :> HumanDrivenVehicle, PoweredVehicle;
+ part def Engine;
+ part def Person;
+}
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Interface Example/InterfaceExample.sysml b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Interface Example/InterfaceExample.sysml
new file mode 100644
index 000000000..42a99cacc
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Interface Example/InterfaceExample.sysml
@@ -0,0 +1,13 @@
+package 'Interface Example' {
+ private import 'Port Example'::*;
+ part def Vehicle;
+ interface def FuelInterface {
+ end supplierPort: FuelOutPort;
+ end consumerPort: FuelInPort;
+ }
+ part vehicle: Vehicle {
+ part tankAssy: FuelTankAssembly;
+ part eng: Engine;
+ interface : FuelInterface connect supplierPort ::> tankAssy.fuelTankPort to consumerPort ::> eng.engineFuelPort;
+ }
+}
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Redefinition Example/RedefinitionExample.sysml b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Redefinition Example/RedefinitionExample.sysml
new file mode 100644
index 000000000..a4641e690
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Expected/Redefinition Example/RedefinitionExample.sysml
@@ -0,0 +1,21 @@
+package 'Redefinition Example' {
+ part def Vehicle {
+ part eng: Engine;
+ }
+ part def SmallVehicle :> Vehicle {
+ part smallEng: SmallEngine :>> eng;
+ }
+ part def BigVehicle :> Vehicle {
+ part bigEng: BigEngine :>> eng;
+ }
+ part def Engine {
+ part cyl: Cylinder[4..6];
+ }
+ part def SmallEngine :> Engine {
+ part :>> cyl[4];
+ }
+ part def BigEngine :> Engine {
+ part :>> cyl[6];
+ }
+ part def Cylinder;
+}
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Arrowhead Framework Example/AHFCoreLib.sysmlx b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Arrowhead Framework Example/AHFCoreLib.sysmlx
new file mode 100644
index 000000000..a614ca0f4
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Arrowhead Framework Example/AHFCoreLib.sysmlx
@@ -0,0 +1,273 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Arrowhead Framework Example/AHFNorwayTopics.sysmlx b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Arrowhead Framework Example/AHFNorwayTopics.sysmlx
new file mode 100644
index 000000000..a9eb8796e
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Arrowhead Framework Example/AHFNorwayTopics.sysmlx
@@ -0,0 +1,1640 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Arrowhead Framework Example/AHFProfileLib.sysmlx b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Arrowhead Framework Example/AHFProfileLib.sysmlx
new file mode 100644
index 000000000..8a864d472
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Arrowhead Framework Example/AHFProfileLib.sysmlx
@@ -0,0 +1,558 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Binding Connectors Example/BindingConnectorsExample.sysmlx b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Binding Connectors Example/BindingConnectorsExample.sysmlx
new file mode 100644
index 000000000..6c0ec3110
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Binding Connectors Example/BindingConnectorsExample.sysmlx
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Binding Connectors Example/PortExample.sysmlx b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Binding Connectors Example/PortExample.sysmlx
new file mode 100644
index 000000000..12369ac60
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Binding Connectors Example/PortExample.sysmlx
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Flow Usage Example/FlowUsageExample.sysmlx b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Flow Usage Example/FlowUsageExample.sysmlx
new file mode 100644
index 000000000..f58861429
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Flow Usage Example/FlowUsageExample.sysmlx
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Flow Usage Example/PortExample.sysmlx b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Flow Usage Example/PortExample.sysmlx
new file mode 100644
index 000000000..12369ac60
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Flow Usage Example/PortExample.sysmlx
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Generalization Example/GeneralizationExample.sysmlx b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Generalization Example/GeneralizationExample.sysmlx
new file mode 100644
index 000000000..8e78644fa
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Generalization Example/GeneralizationExample.sysmlx
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Interface Example/InterfaceExample.sysmlx b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Interface Example/InterfaceExample.sysmlx
new file mode 100644
index 000000000..cf19cf4a8
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Interface Example/InterfaceExample.sysmlx
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Interface Example/PortExample.sysmlx b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Interface Example/PortExample.sysmlx
new file mode 100644
index 000000000..12369ac60
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Interface Example/PortExample.sysmlx
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Redefinition Example/RedefinitionExample.sysmlx b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Redefinition Example/RedefinitionExample.sysmlx
new file mode 100644
index 000000000..3022643f8
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Validation/Redefinition Example/RedefinitionExample.sysmlx
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationValidationTestFixture.cs b/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationValidationTestFixture.cs
index 4071f116e..b3f60384e 100644
--- a/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationValidationTestFixture.cs
+++ b/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationValidationTestFixture.cs
@@ -170,6 +170,12 @@ public void OneTimeTearDown()
[TestCase("Simple Tests", "ParameterTest.sysmlx")]
[TestCase("Simple Tests", "UseCaseTest.sysmlx")]
[TestCase("Simple Tests", "VariabilityTest.sysmlx")]
+ [TestCase("Arrowhead Framework Example", "AHFNorwayTopics.sysmlx")]
+ [TestCase("Redefinition Example", "RedefinitionExample.sysmlx")]
+ [TestCase("Generalization Example", "GeneralizationExample.sysmlx")]
+ [TestCase("Flow Usage Example", "FlowUsageExample.sysmlx")]
+ [TestCase("Binding Connectors Example", "BindingConnectorsExample.sysmlx")]
+ [TestCase("Interface Example", "InterfaceExample.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 51c243828..5b4669d84 100644
--- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs
+++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs
@@ -172,6 +172,7 @@ public static void BuildDefinitionElement(SysML2.NET.Core.POCO.Root.Elements.IEl
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildOwnedRelatedElement(SysML2.NET.Core.POCO.Root.Elements.IElement poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
switch (poco)
diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs
index b0621295d..753cb9186 100644
--- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs
+++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs
@@ -478,6 +478,7 @@ public static void BuildOwnedFeatureMember(SysML2.NET.Core.POCO.Core.Types.IFeat
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildOwnedExpressionReferenceMember(SysML2.NET.Core.POCO.Core.Types.IFeatureMembership poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship);
@@ -601,6 +602,7 @@ public static void BuildPayloadFeatureMember(SysML2.NET.Core.POCO.Core.Types.IFe
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildMetadataBodyFeatureMember(SysML2.NET.Core.POCO.Core.Types.IFeatureMembership poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
var effectiveOwnedMemberFeature = SysML2.NET.Serializer.TextualNotation.Writers.SharedTextualNotationBuilder.QueryEffectiveOwnedMemberFeature(poco);
diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs
index ad7952f84..600345cef 100644
--- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs
+++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs
@@ -894,6 +894,7 @@ public static void BuildPrimaryArgument(SysML2.NET.Core.POCO.Core.Features.IFeat
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildNonFeatureChainPrimaryArgument(SysML2.NET.Core.POCO.Core.Features.IFeature poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship);
@@ -1133,6 +1134,7 @@ public static void BuildNamedArgument(SysML2.NET.Core.POCO.Core.Features.IFeatur
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildMetadataBodyFeature(SysML2.NET.Core.POCO.Core.Features.IFeature poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship);
diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureValueTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureValueTextualNotationBuilder.cs
index 4744e113e..d52da19dc 100644
--- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureValueTextualNotationBuilder.cs
+++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureValueTextualNotationBuilder.cs
@@ -197,6 +197,7 @@ public static void BuildPrimaryArgumentValue(SysML2.NET.Core.POCO.Kernel.Feature
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildNonFeatureChainPrimaryArgumentValue(SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs
index c5b5e01f4..c73fdf2db 100644
--- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs
+++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs
@@ -181,6 +181,7 @@ public static void BuildInstantiatedTypeMember(SysML2.NET.Core.POCO.Root.Namespa
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildMetadataBodyElement(SysML2.NET.Core.POCO.Root.Namespaces.IMembership poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
switch (poco)
diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataFeatureTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataFeatureTextualNotationBuilder.cs
index 7e31719e5..24b45700e 100644
--- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataFeatureTextualNotationBuilder.cs
+++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataFeatureTextualNotationBuilder.cs
@@ -40,6 +40,7 @@ public static partial class MetadataFeatureTextualNotationBuilder
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildPrefixMetadataFeature(SysML2.NET.Core.POCO.Kernel.Metadata.IMetadataFeature poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship);
diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataUsageTextualNotationBuilder.cs
index 8552cb0f1..0d4f3d658 100644
--- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataUsageTextualNotationBuilder.cs
+++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataUsageTextualNotationBuilder.cs
@@ -64,6 +64,7 @@ public static void BuildPrefixMetadataUsage(SysML2.NET.Core.POCO.Systems.Metadat
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildMetadataUsageDeclaration(SysML2.NET.Core.POCO.Systems.Metadata.IMetadataUsage poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship);
@@ -96,6 +97,7 @@ public static void BuildMetadataUsageDeclaration(SysML2.NET.Core.POCO.Systems.Me
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildMetadataUsage(SysML2.NET.Core.POCO.Systems.Metadata.IMetadataUsage poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship);
diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityRangeTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityRangeTextualNotationBuilder.cs
index 1935d7c47..a8ec4d341 100644
--- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityRangeTextualNotationBuilder.cs
+++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityRangeTextualNotationBuilder.cs
@@ -40,6 +40,7 @@ public static partial class MultiplicityRangeTextualNotationBuilder
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildOwnedMultiplicityRange(SysML2.NET.Core.POCO.Kernel.Multiplicities.IMultiplicityRange poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
BuildMultiplicityBounds(poco, writerContext, stringBuilder);
@@ -53,6 +54,7 @@ public static void BuildOwnedMultiplicityRange(SysML2.NET.Core.POCO.Kernel.Multi
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildMultiplicityBounds(SysML2.NET.Core.POCO.Kernel.Multiplicities.IMultiplicityRange poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship);
diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs
index fc3da35b7..2eb3c5bea 100644
--- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs
+++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs
@@ -256,6 +256,7 @@ public static void BuildAssignmentTargetParameter(SysML2.NET.Core.POCO.Systems.D
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildForVariableDeclaration(SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder);
diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RelationshipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RelationshipTextualNotationBuilder.cs
index 5741eac69..15bedd8dd 100644
--- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RelationshipTextualNotationBuilder.cs
+++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RelationshipTextualNotationBuilder.cs
@@ -80,6 +80,7 @@ public static void BuildRelationshipBody(SysML2.NET.Core.POCO.Root.Elements.IRel
/// The from which the rule should be build
/// The providing the serialization context for the current
/// The that accumulates the entire textual notation with indentation
+ [GrammarUnreachable("No production in the effective SysML v2 textual grammar (SysML definitions override same-named KerML ones) references this rule, so it can never be reached from RootNamespace.")]
public static void BuildRelationshipOwnedElement(SysML2.NET.Core.POCO.Root.Elements.IRelationship poco, TextualNotationWriterContext writerContext, IndentedStringBuilder stringBuilder)
{
BuildRelationshipOwnedElementHandCoded(poco, writerContext, stringBuilder);
diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/GrammarUnreachableAttribute.cs b/SysML2.NET.Serializer.TextualNotation/Writers/GrammarUnreachableAttribute.cs
new file mode 100644
index 000000000..a187d7bb0
--- /dev/null
+++ b/SysML2.NET.Serializer.TextualNotation/Writers/GrammarUnreachableAttribute.cs
@@ -0,0 +1,47 @@
+// -------------------------------------------------------------------------------------------------
+//
+//
+// Copyright 2022-2026 Starion Group S.A.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+// ------------------------------------------------------------------------------------------------
+
+namespace SysML2.NET.Serializer.TextualNotation.Writers
+{
+ using System;
+
+ ///
+ /// Marks a generated Build{Rule} method whose grammar rule has no incoming reference,
+ /// directly or transitively, from any other production in the effective SysML v2 textual
+ /// grammar rooted at RootNamespace.
+ ///
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
+ public sealed class GrammarUnreachableAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Why the grammar rule this method implements cannot be reached.
+ public GrammarUnreachableAttribute(string reason)
+ {
+ this.Reason = reason;
+ }
+
+ ///
+ /// Gets why the grammar rule this method implements cannot be reached.
+ ///
+ public string Reason { get; }
+ }
+}