From 987871f9bfa88829f6e0fbdec764454f19755664 Mon Sep 17 00:00:00 2001 From: atheate Date: Tue, 19 May 2026 14:02:34 +0200 Subject: [PATCH 1/5] Fix skipped part and wrong naming --- .../Grammar/Model/TextualNotationRule.cs | 82 +++ .../RuleProcessor.CollectionProcessing.cs | 130 +++- .../RuleProcessor.ElementProcessing.cs | 35 +- .../HandleBarHelpers/RuleProcessor.cs | 167 ++++- ...AcceptActionUsageTextualNotationBuilder.cs | 11 +- .../ActionUsageTextualNotationBuilder.cs | 29 +- .../ActorMembershipTextualNotationBuilder.cs | 4 +- ...AnalysisCaseUsageTextualNotationBuilder.cs | 3 +- .../AnnotationTextualNotationBuilder.cs | 4 +- ...rtConstraintUsageTextualNotationBuilder.cs | 6 +- ...gnmentActionUsageTextualNotationBuilder.cs | 4 +- ...gConnectorAsUsageTextualNotationBuilder.cs | 10 +- ...BooleanExpressionTextualNotationBuilder.cs | 3 +- .../CaseUsageTextualNotationBuilder.cs | 3 +- .../ClassifierTextualNotationBuilder.cs | 8 +- ...CollectExpressionTextualNotationBuilder.cs | 8 +- ...tedPortDefinitionTextualNotationBuilder.cs | 4 +- .../ConnectionUsageTextualNotationBuilder.cs | 16 +- .../ConnectorTextualNotationBuilder.cs | 19 +- .../ConstraintUsageTextualNotationBuilder.cs | 3 +- ...tructorExpressionTextualNotationBuilder.cs | 8 +- .../DefinitionTextualNotationBuilder.cs | 7 +- ...tFilterMembershipTextualNotationBuilder.cs | 8 +- .../ElementTextualNotationBuilder.cs | 4 +- ...FeatureMembershipTextualNotationBuilder.cs | 20 +- ...ntOccurrenceUsageTextualNotationBuilder.cs | 12 +- ...ExhibitStateUsageTextualNotationBuilder.cs | 8 +- .../ExpressionTextualNotationBuilder.cs | 7 +- ...reChainExpressionTextualNotationBuilder.cs | 8 +- ...FeatureMembershipTextualNotationBuilder.cs | 72 +- ...ferenceExpressionTextualNotationBuilder.cs | 24 +- .../FeatureTextualNotationBuilder.cs | 110 ++-- .../FeatureValueTextualNotationBuilder.cs | 24 +- .../FlowEndTextualNotationBuilder.cs | 6 +- ...orLoopActionUsageTextualNotationBuilder.cs | 12 +- ...ConcernMembershipTextualNotationBuilder.cs | 4 +- .../IfActionUsageTextualNotationBuilder.cs | 8 +- ...cludeUseCaseUsageTextualNotationBuilder.cs | 8 +- .../IndexExpressionTextualNotationBuilder.cs | 8 +- .../InterfaceUsageTextualNotationBuilder.cs | 16 +- .../InvariantTextualNotationBuilder.cs | 3 +- ...ocationExpressionTextualNotationBuilder.cs | 20 +- .../MembershipTextualNotationBuilder.cs | 12 +- ...aAccessExpressionTextualNotationBuilder.cs | 8 +- .../MetadataFeatureTextualNotationBuilder.cs | 8 +- .../MetadataUsageTextualNotationBuilder.cs | 8 +- ...MultiplicityRangeTextualNotationBuilder.cs | 12 +- ...jectiveMembershipTextualNotationBuilder.cs | 4 +- ...urrenceDefinitionTextualNotationBuilder.cs | 4 +- ...peratorExpressionTextualNotationBuilder.cs | 80 +-- .../OwningMembershipTextualNotationBuilder.cs | 52 +- .../PackageTextualNotationBuilder.cs | 4 +- ...rameterMembershipTextualNotationBuilder.cs | 40 +- ...erformActionUsageTextualNotationBuilder.cs | 12 +- .../PortDefinitionTextualNotationBuilder.cs | 4 +- .../PortUsageTextualNotationBuilder.cs | 8 +- .../ReferenceUsageTextualNotationBuilder.cs | 32 +- ...straintMembershipTextualNotationBuilder.cs | 4 +- ...icationMembershipTextualNotationBuilder.cs | 4 +- ...ressionMembershipTextualNotationBuilder.cs | 4 +- ...rameterMembershipTextualNotationBuilder.cs | 16 +- ...yRequirementUsageTextualNotationBuilder.cs | 8 +- .../SelectExpressionTextualNotationBuilder.cs | 8 +- .../SendActionUsageTextualNotationBuilder.cs | 14 +- ...eholderMembershipTextualNotationBuilder.cs | 4 +- ...bactionMembershipTextualNotationBuilder.cs | 12 +- .../StepTextualNotationBuilder.cs | 3 +- ...SubjectMembershipTextualNotationBuilder.cs | 8 +- ...SuccessionAsUsageTextualNotationBuilder.cs | 22 +- .../SuccessionTextualNotationBuilder.cs | 8 +- ...minateActionUsageTextualNotationBuilder.cs | 2 +- ...FeatureMembershipTextualNotationBuilder.cs | 12 +- .../TransitionUsageTextualNotationBuilder.cs | 52 +- .../TypeTextualNotationBuilder.cs | 24 +- .../UsageTextualNotationBuilder.cs | 10 +- .../UseCaseUsageTextualNotationBuilder.cs | 3 +- ...VariantMembershipTextualNotationBuilder.cs | 4 +- ...ficationCaseUsageTextualNotationBuilder.cs | 3 +- ...nderingMembershipTextualNotationBuilder.cs | 4 +- .../ViewUsageTextualNotationBuilder.cs | 5 +- ...leLoopActionUsageTextualNotationBuilder.cs | 12 +- .../Writers/FeatureTextualNotationBuilder.cs | 6 +- .../Writers/NameResolutionCache.cs | 615 ++++++++++++++++++ .../Writers/SharedTextualNotationBuilder.cs | 171 ++--- .../Writers/TextualNotationWriterContext.cs | 234 +------ 85 files changed, 1612 insertions(+), 894 deletions(-) create mode 100644 SysML2.NET.Serializer.TextualNotation/Writers/NameResolutionCache.cs diff --git a/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationRule.cs b/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationRule.cs index 3ad8b099..c20e2533 100644 --- a/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationRule.cs +++ b/SysML2.NET.CodeGenerator/Grammar/Model/TextualNotationRule.cs @@ -20,6 +20,7 @@ namespace SysML2.NET.CodeGenerator.Grammar.Model { + using System; using System.Collections.Generic; using System.Linq; @@ -277,5 +278,86 @@ private static void CollectAllReferencedPropertyNamesFromElements(IEnumerable + /// Recursively collects the += items targeting + /// declared by this rule and any transitively-referenced + /// NonTerminal rules. Used by the generator to resolve the runtime type(s) an optional + /// non-terminal reference will consume from the named cursor, so the caller can emit a + /// type-strict cursor.Current is T guard. + /// + /// The property name whose += consumptions are collected + /// All available rules for resolving NonTerminal references + /// The collected += items + public IReadOnlyList QueryAllReferencedCollectionAssignments(string propertyName, IReadOnlyList allRules) + { + var result = new List(); + var visited = new HashSet(); + CollectAllReferencedCollectionAssignments(this, propertyName, allRules, result, visited); + return result; + } + + /// + /// Recursively collects += items targeting + /// from a rule and its referenced NonTerminal rules. + /// + /// The rule to inspect + /// The property name to match + /// All available rules for resolving NonTerminal references + /// The accumulated list of += assignments + /// Set of already-visited rule names to prevent infinite recursion + private static void CollectAllReferencedCollectionAssignments(TextualNotationRule rule, string propertyName, IReadOnlyList allRules, List result, HashSet visited) + { + if (!visited.Add(rule.RuleName)) + { + return; + } + + foreach (var alternative in rule.Alternatives) + { + CollectAllReferencedCollectionAssignmentsFromElements(alternative.Elements, propertyName, allRules, result, visited); + } + } + + /// + /// Recursively collects += items targeting + /// from a list of . + /// + /// The elements to inspect + /// The property name to match + /// All available rules for resolving NonTerminal references + /// The accumulated list of += assignments + /// Set of already-visited rule names to prevent infinite recursion + private static void CollectAllReferencedCollectionAssignmentsFromElements(IEnumerable elements, string propertyName, IReadOnlyList allRules, List result, HashSet visited) + { + foreach (var element in elements) + { + switch (element) + { + case AssignmentElement { Operator: "+=" } assignmentElement + when string.Equals(assignmentElement.Property, propertyName, StringComparison.OrdinalIgnoreCase): + result.Add(assignmentElement); + break; + + case NonTerminalElement nonTerminalElement: + var referencedRule = allRules.SingleOrDefault(x => x.RuleName == nonTerminalElement.Name); + + if (referencedRule != null) + { + CollectAllReferencedCollectionAssignments(referencedRule, propertyName, allRules, result, visited); + } + + break; + + case GroupElement groupElement: + foreach (var groupAlternative in groupElement.Alternatives) + { + CollectAllReferencedCollectionAssignmentsFromElements(groupAlternative.Elements, propertyName, allRules, result, visited); + } + + break; + } + } + } } } diff --git a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.CollectionProcessing.cs b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.CollectionProcessing.cs index 517c6c9d..011354d0 100644 --- a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.CollectionProcessing.cs +++ b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.CollectionProcessing.cs @@ -29,6 +29,7 @@ namespace SysML2.NET.CodeGenerator.HandleBarHelpers using SysML2.NET.CodeGenerator.Extensions; using SysML2.NET.CodeGenerator.Grammar.Model; + using uml4net.Classification; using uml4net.CommonStructure; using uml4net.Extensions; using uml4net.StructuredClassifiers; @@ -370,10 +371,24 @@ private string ResolveBuilderCall(IClass umlClass, NonTerminalElement nonTermina /// /// Generates an inline condition expression for an optional non-terminal reference. + /// For enumerable properties whose consumption type can be resolved from the referenced + /// rule's += assignments, emits a cursor-typed guard + /// ({prop}Cursor.Current is T) — declaring the cursor immediately into + /// when not already present in + /// . The cursor principle aligns the + /// caller's guard with the position the called rule will actually consume from. When the + /// type cannot be resolved or is not the top-level + /// poco, the legacy {var}.{Property}.Count != 0 form is preserved. /// - private string GenerateInlineOptionalCondition(TextualNotationRule referencedRule, IClass targetClass, IReadOnlyList allRules, string variableName) + /// The used to emit any required cursor declarations + /// The optional non-terminal's referenced rule + /// The host class (provides UML metadata) + /// The current + /// The variable name from which the property is accessed (typically poco) + /// The condition expression, or null when no property names are referenced + private string GenerateInlineOptionalCondition(EncodedTextWriter writer, TextualNotationRule referencedRule, IClass targetClass, RuleGenerationContext ruleGenerationContext, string variableName) { - var propertyNames = referencedRule.QueryAllReferencedPropertyNames(allRules); + var propertyNames = referencedRule.QueryAllReferencedPropertyNames(ruleGenerationContext.AllRules); if (propertyNames.Count == 0) { @@ -396,7 +411,25 @@ private string GenerateInlineOptionalCondition(TextualNotationRule referencedRul if (property.QueryIsEnumerable()) { - conditionParts.Add($"{variableName}.{umlPropertyName}.Count != 0"); + var cursorTypedCheck = TryBuildCursorTypedCheck(writer, referencedRule, targetClass, property, propertyName, ruleGenerationContext, variableName); + + if (cursorTypedCheck != null) + { + conditionParts.Add(cursorTypedCheck); + } + else if (referencedRule.QueryAllReferencedCollectionAssignments(propertyName, ruleGenerationContext.AllRules).Count > 0) + { + // The referenced rule has += consumptions of this property but the cursor + // types could not be resolved — fall back to the legacy collection-level + // non-empty check rather than skip the clause entirely. + conditionParts.Add($"{variableName}.{umlPropertyName}.Count != 0"); + } + + // No += consumptions exist for this property anywhere in the referenced rule + // tree (the property name reached the result set via a scalar `=` reference, + // typically pulled in by a transitive non-terminal walk). Skipping the clause + // tightens the guard to reflect what the called rule will actually consume + // and avoids evaluating derived properties that the caller never reads. } else { @@ -407,6 +440,95 @@ private string GenerateInlineOptionalCondition(TextualNotationRule referencedRul return conditionParts.Count != 0 ? string.Join(" || ", conditionParts) : null; } + /// + /// Resolves the runtime types the referenced rule's += assignments consume from the + /// supplied and, when all are resolvable AND + /// is poco, returns a cursor-typed boolean + /// expression (declaring or reusing a cursor as needed). Returns null to signal + /// that the caller should fall back to the legacy .Count != 0 form. + /// + /// The used to emit a cursor declaration when one is required + /// The optional non-terminal's referenced rule + /// The host class (provides the UML cache for class-name resolution) + /// The host class property targeted by the rule's += consumptions + /// The matching grammar property name + /// The current + /// The variable name the host method uses for the POCO + /// The cursor-typed boolean expression, or null if the legacy fallback should be used + private static string TryBuildCursorTypedCheck(EncodedTextWriter writer, TextualNotationRule referencedRule, IClass targetClass, IProperty property, string propertyName, RuleGenerationContext ruleGenerationContext, string variableName) + { + if (!string.Equals(variableName, "poco", StringComparison.Ordinal)) + { + return null; + } + + var collectionAssignments = referencedRule.QueryAllReferencedCollectionAssignments(propertyName, ruleGenerationContext.AllRules); + + if (collectionAssignments.Count == 0) + { + return null; + } + + var resolvedTypeNames = new List(); + + foreach (var assignmentElement in collectionAssignments) + { + var typeName = ResolveAssignmentTargetTypeName(assignmentElement, targetClass, ruleGenerationContext); + + if (typeName == null) + { + return null; + } + + if (!resolvedTypeNames.Contains(typeName)) + { + resolvedTypeNames.Add(typeName); + } + } + + var cursorVariableName = EnsureCursorDeclared(writer, property, ruleGenerationContext); + + if (resolvedTypeNames.Count == 1) + { + return $"{cursorVariableName}.Current is {resolvedTypeNames[0]}"; + } + + var typeChecks = resolvedTypeNames.Select(typeName => $"{cursorVariableName}.Current is {typeName}"); + + return $"({string.Join(" || ", typeChecks)})"; + } + + /// + /// Returns the cursor variable name for , reusing an + /// already-declared cursor when one is present in + /// and emitting a new declaration into + /// otherwise. The new declaration is registered in + /// so subsequent host-rule elements + /// targeting the same property reuse it. + /// + /// The that receives the cursor declaration line when emitted + /// The property whose cursor is needed + /// The current + /// The cursor variable name to use in the guard expression + private static string EnsureCursorDeclared(EncodedTextWriter writer, IProperty property, RuleGenerationContext ruleGenerationContext) + { + var existingCursor = ruleGenerationContext.DefinedCursors.FirstOrDefault(x => x.IsCursorValidForProperty(property)); + + if (existingCursor != null) + { + return existingCursor.CursorVariableName; + } + + var cursorDefinition = new CursorDefinition { DefinedForProperty = property }; + var propertyAccessName = property.QueryPropertyNameBasedOnUmlProperties(); + + writer.WriteSafeString($"var {cursorDefinition.CursorVariableName} = writerContext.CursorCache.GetOrCreateCursor(poco.Id, \"{property.Name}\", poco.{propertyAccessName});{Environment.NewLine}"); + + ruleGenerationContext.DefinedCursors.Add(cursorDefinition); + + return cursorDefinition.CursorVariableName; + } + /// /// Emits an optional condition wrapping block for an optional NonTerminal element. /// @@ -422,7 +544,7 @@ private bool TryEmitOptionalCondition(EncodedTextWriter writer, NonTerminalEleme return false; } - var condition = this.GenerateInlineOptionalCondition(referencedRule, targetClass, ruleGenerationContext.AllRules, variableName); + var condition = this.GenerateInlineOptionalCondition(writer, referencedRule, targetClass, ruleGenerationContext, variableName); if (condition == null) { diff --git a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.ElementProcessing.cs b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.ElementProcessing.cs index 91f55de6..d0c8cc5c 100644 --- a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.ElementProcessing.cs +++ b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.ElementProcessing.cs @@ -275,9 +275,16 @@ internal void ProcessAssignmentElement(EncodedTextWriter writer, IClass umlClass var previousCaller = ruleGenerationContext.CallerRule; ruleGenerationContext.CallerRule = assignmentElement; - var isInsideOptionalGroup = assignmentElement.Container is GroupElement { IsOptional: true, IsCollection: false }; - - if (isInsideOptionalGroup) + // Route the cursor Move() through PendingCursorMove so that ProcessNonTerminalElement + // emits it INSIDE the type-discrimination block — Move() then fires only when the + // runtime cast actually matches (cursor advances only on real += consumption, + // honouring the Move() ↔ += Golden Rule). When the assignment is inside a collection + // group `(...)*` / `(...)+`, the loop body's own emitter handles the move; when it is + // part of a multi-alternative dispatch, the dispatcher handles the move. + var shouldEmitCursorMove = !isPartOfMultipleAlternative + && assignmentElement.Container is not GroupElement { IsCollection: true }; + + if (shouldEmitCursorMove) { ruleGenerationContext.PendingCursorMove = $"{Environment.NewLine}{cursorToUse.CursorVariableName}.Move();{Environment.NewLine}"; } @@ -285,13 +292,6 @@ internal void ProcessAssignmentElement(EncodedTextWriter writer, IClass umlClass this.ProcessNonTerminalElement(writer, umlClass, nonTerminalElement, ruleGenerationContext); ruleGenerationContext.CurrentVariableName = previousVariableName; ruleGenerationContext.CallerRule = previousCaller; - - if (!isPartOfMultipleAlternative - && assignmentElement.Container is not GroupElement { IsCollection: true } - && !isInsideOptionalGroup) - { - writer.WriteSafeString($"{cursorToUse.CursorVariableName}.Move();{Environment.NewLine}"); - } } else if (assignmentElement.Value is GroupElement groupElement) { @@ -322,7 +322,16 @@ internal void ProcessAssignmentElement(EncodedTextWriter writer, IClass umlClass { writer.WriteSafeString($"{Environment.NewLine}if({targetProperty.QueryIfStatementContentForNonEmpty("poco")}){Environment.NewLine}"); writer.WriteSafeString($"{{{Environment.NewLine}"); - writer.WriteSafeString($"stringBuilder.Append(poco.{targetProperty.Name.CapitalizeFirstLetter()});{Environment.NewLine}"); + + if (assignmentElement.Value is NonTerminalElement { Name: "NAME" }) + { + writer.WriteSafeString($"SharedTextualNotationBuilder.AppendName(stringBuilder, poco.{targetProperty.Name.CapitalizeFirstLetter()});{Environment.NewLine}"); + } + else + { + writer.WriteSafeString($"stringBuilder.Append(poco.{targetProperty.Name.CapitalizeFirstLetter()});{Environment.NewLine}"); + } + writer.WriteSafeString("}"); } else @@ -335,6 +344,10 @@ internal void ProcessAssignmentElement(EncodedTextWriter writer, IClass umlClass { writer.WriteSafeString($"SharedTextualNotationBuilder.AppendRegularComment(stringBuilder, poco.{targetPropertyName});"); } + else if (assignmentElement.Value is NonTerminalElement { Name: "NAME" }) + { + writer.WriteSafeString($"SharedTextualNotationBuilder.AppendName(stringBuilder, poco.{targetPropertyName});"); + } else { writer.WriteSafeString($"stringBuilder.Append(poco.{targetPropertyName});"); diff --git a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.cs b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.cs index b8fda281..94a5d3e5 100644 --- a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.cs +++ b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.cs @@ -137,6 +137,137 @@ private void EmitHandCodedFallback(EncodedTextWriter writer, string ruleName, Ru writer.WriteSafeString($"Build{ruleName}HandCoded({ruleGenerationContext.CurrentVariableName ?? "poco"}, writerContext, stringBuilder);"); } + /// + /// Collects, in the order they will be consumed at runtime, the += + /// items that target . + /// The collected items are: first the += assignments declared inside the optional + /// group itself (), then the += + /// assignments declared by the parent alternative AFTER + /// (). + /// + /// The tail walk stops as soon as it encounters a sibling whose own contribution to the + /// target cursor is not statically determinable (an optional or collection + /// that nests a += on the same property, or a + /// that could indirectly consume the cursor). When the + /// tail offset is uncertain, only the optional group's own consumptions are returned — + /// callers can then emit a guard that type-checks the optional positions without making + /// claims about the tail. + /// + /// + /// The optional group's own elements + /// The parent alternative's elements + /// The index of the optional group within + /// The property name whose += consumptions are collected + /// The ordered list of cursor consumptions the optional path requires + private static List CollectCursorConsumptions(IReadOnlyList optionalGroupElements, IReadOnlyList siblingElements, int optionalElementIndex, string targetPropertyName) + { + var consumptionAssignments = new List(); + + if (optionalGroupElements != null) + { + foreach (var ruleElement in optionalGroupElements) + { + if (ruleElement is AssignmentElement { Operator: "+=" } assignmentElement + && string.Equals(assignmentElement.Property, targetPropertyName, StringComparison.OrdinalIgnoreCase)) + { + consumptionAssignments.Add(assignmentElement); + } + } + } + + if (siblingElements == null) + { + return consumptionAssignments; + } + + for (var siblingIndex = optionalElementIndex + 1; siblingIndex < siblingElements.Count; siblingIndex++) + { + switch (siblingElements[siblingIndex]) + { + case TerminalElement: + case NonParsingAssignmentElement: + case ValueLiteralElement: + continue; + + case AssignmentElement { Operator: "+=" } cursorAssignment + when string.Equals(cursorAssignment.Property, targetPropertyName, StringComparison.OrdinalIgnoreCase): + consumptionAssignments.Add(cursorAssignment); + continue; + + case AssignmentElement: + continue; + + case GroupElement groupElement when !GroupCanConsumeTargetCursor(groupElement, targetPropertyName): + continue; + + default: + return consumptionAssignments; + } + } + + return consumptionAssignments; + } + + /// + /// Determines whether the supplied (recursively) contains + /// any += targeting . + /// Used by to decide whether a sibling group + /// could shift the runtime offset of subsequent cursor consumptions. + /// + /// The to inspect + /// The property name whose consumption is detected + /// true if the group could consume the target cursor; false otherwise + private static bool GroupCanConsumeTargetCursor(GroupElement groupElement, string targetPropertyName) + { + foreach (var alternative in groupElement.Alternatives) + { + foreach (var element in alternative.Elements) + { + switch (element) + { + case AssignmentElement { Operator: "+=" } cursorAssignment + when string.Equals(cursorAssignment.Property, targetPropertyName, StringComparison.OrdinalIgnoreCase): + return true; + + case GroupElement nestedGroup when GroupCanConsumeTargetCursor(nestedGroup, targetPropertyName): + return true; + } + } + } + + return false; + } + + /// + /// Resolves the fully-qualified runtime type name (e.g. + /// SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) that an + /// 's consumed cursor element is expected to satisfy. + /// Returns null when the assignment's value is not a + /// or when the referenced rule has no resolvable target class. + /// + /// The += assignment to resolve the target type of + /// The class hosting the current rule (provides the UML cache) + /// The current + /// The fully-qualified target type name, or null if it cannot be resolved + private static string ResolveAssignmentTargetTypeName(AssignmentElement assignmentElement, IClass umlClass, RuleGenerationContext ruleGenerationContext) + { + if (assignmentElement.Value is not NonTerminalElement nonTerminalElement) + { + return null; + } + + var referencedRule = ruleGenerationContext.FindRule(nonTerminalElement.Name); + var typeTarget = referencedRule?.EffectiveTarget; + + if (typeTarget == null) + { + return null; + } + + var targetClass = RuleQueryUtilities.FindClass(umlClass.Cache, typeTarget); + return targetClass?.QueryFullyQualifiedTypeName(); + } + /// /// Processes a single alternative (no branching needed). Handles optional guard emission /// and iterates through the alternative's elements. @@ -171,7 +302,39 @@ private void ProcessSingleAlternative(EncodedTextWriter writer, IClass umlClass, { var assigment = elements.OfType().First(x => x.Property == targetPropertyName); var iterator = ruleGenerationContext.DefinedCursors.FirstOrDefault(x => x.ApplicableRuleElements.Contains(assigment)); - ifStatementContent.Add(iterator == null ? $"BuildGroupConditionFor{assigment.TextualNotationRule.RuleName}(poco)" : property.QueryIfStatementContentForNonEmpty(iterator.CursorVariableName)); + + if (iterator == null) + { + ifStatementContent.Add($"BuildGroupConditionFor{assigment.TextualNotationRule.RuleName}(poco)"); + } + else + { + var consumptionAssignments = CollectCursorConsumptions(elements, ruleGenerationContext.CurrentSiblingElements, ruleGenerationContext.CurrentElementIndex, targetPropertyName); + + if (consumptionAssignments.Count > 1) + { + var conditionParts = new List(); + + for (var consumptionIndex = 0; consumptionIndex < consumptionAssignments.Count; consumptionIndex++) + { + var cursorAccess = consumptionIndex == 0 + ? $"{iterator.CursorVariableName}.Current" + : $"{iterator.CursorVariableName}.GetNext({consumptionIndex})"; + + var typeName = ResolveAssignmentTargetTypeName(consumptionAssignments[consumptionIndex], umlClass, ruleGenerationContext); + + conditionParts.Add(typeName == null + ? $"{cursorAccess} != null" + : $"{cursorAccess} is {typeName}"); + } + + ifStatementContent.Add(string.Join(" && ", conditionParts)); + } + else + { + ifStatementContent.Add(property.QueryIfStatementContentForNonEmpty(iterator.CursorVariableName)); + } + } } else { @@ -209,7 +372,7 @@ private void ProcessSingleAlternative(EncodedTextWriter writer, IClass umlClass, if (referencedRule != null) { - var condition = this.GenerateInlineOptionalCondition(referencedRule, umlClass, ruleGenerationContext.AllRules, "poco"); + var condition = this.GenerateInlineOptionalCondition(writer, referencedRule, umlClass, ruleGenerationContext, "poco"); if (condition != null) { diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AcceptActionUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AcceptActionUsageTextualNotationBuilder.cs index 697b63a3..3a47c88f 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AcceptActionUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AcceptActionUsageTextualNotationBuilder.cs @@ -58,8 +58,9 @@ public static void BuildAcceptNode(SysML2.NET.Core.POCO.Systems.Actions.IAcceptA /// The that contains the entire textual notation public static void BuildAcceptNodeDeclaration(SysML2.NET.Core.POCO.Systems.Actions.IAcceptActionUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { ActionUsageTextualNotationBuilder.BuildActionNodeUsageDeclaration(poco, writerContext, stringBuilder); } @@ -85,10 +86,10 @@ public static void BuildAcceptParameterPart(SysML2.NET.Core.POCO.Systems.Actions if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildPayloadParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -146,12 +147,12 @@ public static void BuildTriggerAction(SysML2.NET.Core.POCO.Systems.Actions.IAcce public static void BuildTransitionAcceptActionUsage(SysML2.NET.Core.POCO.Systems.Actions.IAcceptActionUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { BuildAcceptNodeDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.importedMembership.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IImport || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IVariantMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership) || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { stringBuilder.Append(' '); stringBuilder.AppendLine("{"); - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); while (ownedRelationshipCursor.Current != null) { TypeTextualNotationBuilder.BuildActionBodyItem(poco, writerContext, stringBuilder); diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ActionUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ActionUsageTextualNotationBuilder.cs index 932bacf7..a72e1d18 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ActionUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ActionUsageTextualNotationBuilder.cs @@ -44,8 +44,9 @@ public static partial class ActionUsageTextualNotationBuilder public static void BuildActionUsageDeclaration(SysML2.NET.Core.POCO.Systems.Actions.IActionUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } @@ -101,8 +102,9 @@ public static void BuildActionNode(SysML2.NET.Core.POCO.Systems.Actions.IActionU public static void BuildActionNodeUsageDeclaration(SysML2.NET.Core.POCO.Systems.Actions.IActionUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { stringBuilder.Append("action "); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); } @@ -119,8 +121,9 @@ public static void BuildActionNodeUsageDeclaration(SysML2.NET.Core.POCO.Systems. public static void BuildActionNodePrefix(SysML2.NET.Core.POCO.Systems.Actions.IActionUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { OccurrenceUsageTextualNotationBuilder.BuildOccurrenceUsagePrefix(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { BuildActionNodeUsageDeclaration(poco, writerContext, stringBuilder); } @@ -138,7 +141,7 @@ public static void BuildAssignmentNodeDeclaration(SysML2.NET.Core.POCO.Systems.A { var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { BuildActionNodeUsageDeclaration(poco, writerContext, stringBuilder); stringBuilder.Append(' '); @@ -152,10 +155,10 @@ public static void BuildAssignmentNodeDeclaration(SysML2.NET.Core.POCO.Systems.A if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildAssignmentTargetMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -163,10 +166,10 @@ public static void BuildAssignmentNodeDeclaration(SysML2.NET.Core.POCO.Systems.A if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) { MembershipTextualNotationBuilder.BuildFeatureChainMember(elementAsMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append(":= "); if (ownedRelationshipCursor.Current != null) @@ -175,10 +178,10 @@ public static void BuildAssignmentNodeDeclaration(SysML2.NET.Core.POCO.Systems.A if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildNodeParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -191,12 +194,13 @@ public static void BuildAssignmentNodeDeclaration(SysML2.NET.Core.POCO.Systems.A /// The that contains the entire textual notation public static void BuildActionBodyParameter(SysML2.NET.Core.POCO.Systems.Actions.IActionUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { stringBuilder.Append("action "); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); } @@ -204,7 +208,6 @@ public static void BuildActionBodyParameter(SysML2.NET.Core.POCO.Systems.Actions stringBuilder.Append(' '); stringBuilder.AppendLine("{"); - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); while (ownedRelationshipCursor.Current != null) { TypeTextualNotationBuilder.BuildActionBodyItem(poco, writerContext, stringBuilder); diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ActorMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ActorMembershipTextualNotationBuilder.cs index 5b58df71..69a860d4 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ActorMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ActorMembershipTextualNotationBuilder.cs @@ -52,10 +52,10 @@ public static void BuildActorMember(SysML2.NET.Core.POCO.Systems.Requirements.IA if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Parts.IPartUsage elementAsPartUsage) { PartUsageTextualNotationBuilder.BuildActorUsage(elementAsPartUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AnalysisCaseUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AnalysisCaseUsageTextualNotationBuilder.cs index 0276da84..f8ea0293 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AnalysisCaseUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AnalysisCaseUsageTextualNotationBuilder.cs @@ -46,8 +46,9 @@ public static void BuildAnalysisCaseUsage(SysML2.NET.Core.POCO.Systems.AnalysisC OccurrenceUsageTextualNotationBuilder.BuildOccurrenceUsagePrefix(poco, writerContext, stringBuilder); stringBuilder.Append("analysis "); UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AnnotationTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AnnotationTextualNotationBuilder.cs index cd0a132e..5f317765 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AnnotationTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AnnotationTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildOwnedAnnotation(SysML2.NET.Core.POCO.Root.Annotations.IA if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Root.Annotations.IAnnotatingElement elementAsAnnotatingElement) { AnnotatingElementTextualNotationBuilder.BuildAnnotatingElement(elementAsAnnotatingElement, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AssertConstraintUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AssertConstraintUsageTextualNotationBuilder.cs index c01b6e7d..a736c77b 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AssertConstraintUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AssertConstraintUsageTextualNotationBuilder.cs @@ -62,12 +62,12 @@ public static void BuildAssertConstraintUsage(SysML2.NET.Core.POCO.Systems.Const if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting elementAsReferenceSubsetting) { ReferenceSubsettingTextualNotationBuilder.BuildOwnedReferenceSubsetting(elementAsReferenceSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { FeatureTextualNotationBuilder.BuildFeatureSpecializationPart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AssignmentActionUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AssignmentActionUsageTextualNotationBuilder.cs index 7b1c271e..67c0fb80 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AssignmentActionUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/AssignmentActionUsageTextualNotationBuilder.cs @@ -73,12 +73,12 @@ public static void BuildStateAssignmentActionUsage(SysML2.NET.Core.POCO.Systems. public static void BuildTransitionAssignmentActionUsage(SysML2.NET.Core.POCO.Systems.Actions.IAssignmentActionUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { ActionUsageTextualNotationBuilder.BuildAssignmentNodeDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.importedMembership.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IImport || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IVariantMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership) || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { stringBuilder.Append(' '); stringBuilder.AppendLine("{"); - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); while (ownedRelationshipCursor.Current != null) { TypeTextualNotationBuilder.BuildActionBodyItem(poco, writerContext, stringBuilder); diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/BindingConnectorAsUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/BindingConnectorAsUsageTextualNotationBuilder.cs index 17b487f7..559f6b51 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/BindingConnectorAsUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/BindingConnectorAsUsageTextualNotationBuilder.cs @@ -46,7 +46,7 @@ public static void BuildBindingConnectorAsUsage(SysML2.NET.Core.POCO.Systems.Con var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); UsageTextualNotationBuilder.BuildUsagePrefix(poco, writerContext, stringBuilder); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.OwnedRelatedElement.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { stringBuilder.Append("binding "); UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); @@ -61,10 +61,10 @@ public static void BuildBindingConnectorAsUsage(SysML2.NET.Core.POCO.Systems.Con if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("= "); if (ownedRelationshipCursor.Current != null) @@ -73,10 +73,10 @@ public static void BuildBindingConnectorAsUsage(SysML2.NET.Core.POCO.Systems.Con if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - UsageTextualNotationBuilder.BuildUsageBody(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/BooleanExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/BooleanExpressionTextualNotationBuilder.cs index dce55b1d..3363d73f 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/BooleanExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/BooleanExpressionTextualNotationBuilder.cs @@ -46,8 +46,9 @@ public static void BuildBooleanExpression(SysML2.NET.Core.POCO.Kernel.Functions. SharedTextualNotationBuilder.BuildFeaturePrefix(poco, writerContext, stringBuilder); stringBuilder.Append("bool "); FeatureTextualNotationBuilder.BuildFeatureDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CaseUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CaseUsageTextualNotationBuilder.cs index 08c5f8bd..b6f35d21 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CaseUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CaseUsageTextualNotationBuilder.cs @@ -46,8 +46,9 @@ public static void BuildCaseUsage(SysML2.NET.Core.POCO.Systems.Cases.ICaseUsage OccurrenceUsageTextualNotationBuilder.BuildOccurrenceUsagePrefix(poco, writerContext, stringBuilder); stringBuilder.Append("case "); UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ClassifierTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ClassifierTextualNotationBuilder.cs index b4e28292..7be640be 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ClassifierTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ClassifierTextualNotationBuilder.cs @@ -52,10 +52,10 @@ public static void BuildSubclassificationPart(SysML2.NET.Core.POCO.Core.Classifi if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Classifiers.ISubclassification elementAsSubclassification) { SubclassificationTextualNotationBuilder.BuildOwnedSubclassification(elementAsSubclassification, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current != null && ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Classifiers.ISubclassification) { @@ -137,10 +137,10 @@ public static void BuildSuperclassingPart(SysML2.NET.Core.POCO.Core.Classifiers. if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Classifiers.ISubclassification elementAsSubclassification) { SubclassificationTextualNotationBuilder.BuildOwnedSubclassification(elementAsSubclassification, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current != null && ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Classifiers.ISubclassification) { diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CollectExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CollectExpressionTextualNotationBuilder.cs index 1a006248..45fc8182 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CollectExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CollectExpressionTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildCollectExpression(SysML2.NET.Core.POCO.Kernel.Expression if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("."); if (ownedRelationshipCursor.Current != null) @@ -63,10 +63,10 @@ public static void BuildCollectExpression(SysML2.NET.Core.POCO.Kernel.Expression if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildBodyArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConjugatedPortDefinitionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConjugatedPortDefinitionTextualNotationBuilder.cs index c5465d4c..fb5bc489 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConjugatedPortDefinitionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConjugatedPortDefinitionTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildConjugatedPortDefinition(SysML2.NET.Core.POCO.Systems.Po if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Systems.Ports.IPortConjugation elementAsPortConjugation) { PortConjugationTextualNotationBuilder.BuildPortConjugation(elementAsPortConjugation, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConnectionUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConnectionUsageTextualNotationBuilder.cs index 442525d5..b0bcfe60 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConnectionUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConnectionUsageTextualNotationBuilder.cs @@ -72,10 +72,10 @@ public static void BuildBinaryConnectorPart(SysML2.NET.Core.POCO.Systems.Connect if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("to "); if (ownedRelationshipCursor.Current != null) @@ -84,10 +84,10 @@ public static void BuildBinaryConnectorPart(SysML2.NET.Core.POCO.Systems.Connect if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -109,10 +109,10 @@ public static void BuildNaryConnectorPart(SysML2.NET.Core.POCO.Systems.Connectio if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append(", "); if (ownedRelationshipCursor.Current != null) @@ -121,10 +121,10 @@ public static void BuildNaryConnectorPart(SysML2.NET.Core.POCO.Systems.Connectio if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership endFeatureMembershipGuard && endFeatureMembershipGuard.OwnedRelatedElement.OfType().Any()) { diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConnectorTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConnectorTextualNotationBuilder.cs index ef2f0e89..22e1a092 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConnectorTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConnectorTextualNotationBuilder.cs @@ -73,10 +73,10 @@ public static void BuildBinaryConnectorDeclaration(SysML2.NET.Core.POCO.Kernel.C if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("to "); if (ownedRelationshipCursor.Current != null) @@ -85,10 +85,10 @@ public static void BuildBinaryConnectorDeclaration(SysML2.NET.Core.POCO.Kernel.C if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -102,8 +102,9 @@ public static void BuildBinaryConnectorDeclaration(SysML2.NET.Core.POCO.Kernel.C public static void BuildNaryConnectorDeclaration(SysML2.NET.Core.POCO.Kernel.Connectors.IConnector poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); + var ownedTypeFeaturingCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedTypeFeaturing", poco.ownedTypeFeaturing); - if (poco.IsSufficient || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (poco.IsSufficient || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IConjugation || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IDisjoining || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IUnioning || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IIntersecting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IDifferencing || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureChaining || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureInverting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ITypeFeaturing) || poco.IsOrdered || ownedTypeFeaturingCursor.Current is SysML2.NET.Core.POCO.Core.Features.ITypeFeaturing) { FeatureTextualNotationBuilder.BuildFeatureDeclaration(poco, writerContext, stringBuilder); } @@ -115,10 +116,10 @@ public static void BuildNaryConnectorDeclaration(SysML2.NET.Core.POCO.Kernel.Con if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append(", "); if (ownedRelationshipCursor.Current != null) @@ -127,10 +128,10 @@ public static void BuildNaryConnectorDeclaration(SysML2.NET.Core.POCO.Kernel.Con if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership endFeatureMembershipGuard && endFeatureMembershipGuard.OwnedRelatedElement.OfType().Any()) { diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConstraintUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConstraintUsageTextualNotationBuilder.cs index 3c14615e..8b5ebbc2 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConstraintUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConstraintUsageTextualNotationBuilder.cs @@ -44,8 +44,9 @@ public static partial class ConstraintUsageTextualNotationBuilder public static void BuildConstraintUsageDeclaration(SysML2.NET.Core.POCO.Systems.Constraints.IConstraintUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConstructorExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConstructorExpressionTextualNotationBuilder.cs index 63b753bf..fce66c33 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConstructorExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConstructorExpressionTextualNotationBuilder.cs @@ -52,10 +52,10 @@ public static void BuildConstructorExpression(SysML2.NET.Core.POCO.Kernel.Expres if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) { MembershipTextualNotationBuilder.BuildInstantiatedTypeMember(elementAsMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -63,10 +63,10 @@ public static void BuildConstructorExpression(SysML2.NET.Core.POCO.Kernel.Expres if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) { ReturnParameterMembershipTextualNotationBuilder.BuildConstructorResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/DefinitionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/DefinitionTextualNotationBuilder.cs index 07bfd004..8a6bec17 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/DefinitionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/DefinitionTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildDefinitionExtensionKeyword(SysML2.NET.Core.POCO.Systems. if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildPrefixMetadataMember(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -91,8 +91,9 @@ public static void BuildDefinitionPrefix(SysML2.NET.Core.POCO.Systems.Definition public static void BuildDefinitionDeclaration(SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IDefinition poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { ElementTextualNotationBuilder.BuildIdentification(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Classifiers.ISubclassification) { ClassifierTextualNotationBuilder.BuildSubclassificationPart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementFilterMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementFilterMembershipTextualNotationBuilder.cs index 98f8d459..d9b123b1 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementFilterMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementFilterMembershipTextualNotationBuilder.cs @@ -53,10 +53,10 @@ public static void BuildElementFilterMember(SysML2.NET.Core.POCO.Kernel.Packages if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IExpression elementAsExpression) { ExpressionTextualNotationBuilder.BuildOwnedExpression(elementAsExpression, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - stringBuilder.AppendLine(";"); } @@ -79,10 +79,10 @@ public static void BuildFilterPackageMember(SysML2.NET.Core.POCO.Kernel.Packages if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IExpression elementAsExpression) { ExpressionTextualNotationBuilder.BuildOwnedExpression(elementAsExpression, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - stringBuilder.Append("] "); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs index 47784cee..6144e55d 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs @@ -47,7 +47,7 @@ public static void BuildIdentification(SysML2.NET.Core.POCO.Root.Elements.IEleme if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName)) { stringBuilder.Append("<"); - stringBuilder.Append(poco.DeclaredShortName); + SharedTextualNotationBuilder.AppendName(stringBuilder, poco.DeclaredShortName); stringBuilder.Append(">"); stringBuilder.Append(' '); } @@ -55,7 +55,7 @@ public static void BuildIdentification(SysML2.NET.Core.POCO.Root.Elements.IEleme if (!string.IsNullOrWhiteSpace(poco.DeclaredName)) { - stringBuilder.Append(poco.DeclaredName); + SharedTextualNotationBuilder.AppendName(stringBuilder, poco.DeclaredName); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/EndFeatureMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/EndFeatureMembershipTextualNotationBuilder.cs index 43373cfd..a491571a 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/EndFeatureMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/EndFeatureMembershipTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildSourceEndMember(SysML2.NET.Core.POCO.Core.Features.IEndF if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildSourceEnd(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -75,10 +75,10 @@ public static void BuildConnectorEndMember(SysML2.NET.Core.POCO.Core.Features.IE if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildConnectorEnd(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -99,10 +99,10 @@ public static void BuildInterfaceEndMember(SysML2.NET.Core.POCO.Core.Features.IE if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Ports.IPortUsage elementAsPortUsage) { PortUsageTextualNotationBuilder.BuildInterfaceEnd(elementAsPortUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -123,10 +123,10 @@ public static void BuildFlowEndMember(SysML2.NET.Core.POCO.Core.Features.IEndFea if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Interactions.IFlowEnd elementAsFlowEnd) { FlowEndTextualNotationBuilder.BuildFlowEnd(elementAsFlowEnd, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -147,10 +147,10 @@ public static void BuildEmptyEndMember(SysML2.NET.Core.POCO.Core.Features.IEndFe if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildEmptyFeature(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/EventOccurrenceUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/EventOccurrenceUsageTextualNotationBuilder.cs index 6ce4c793..1a5cd12a 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/EventOccurrenceUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/EventOccurrenceUsageTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildMessageEvent(SysML2.NET.Core.POCO.Systems.Occurrences.IE if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting elementAsReferenceSubsetting) { ReferenceSubsettingTextualNotationBuilder.BuildOwnedReferenceSubsetting(elementAsReferenceSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -79,12 +79,12 @@ public static void BuildEventOccurrenceUsage(SysML2.NET.Core.POCO.Systems.Occurr if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting elementAsReferenceSubsetting) { ReferenceSubsettingTextualNotationBuilder.BuildOwnedReferenceSubsetting(elementAsReferenceSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { FeatureTextualNotationBuilder.BuildFeatureSpecializationPart(poco, writerContext, stringBuilder); } @@ -93,7 +93,7 @@ public static void BuildEventOccurrenceUsage(SysML2.NET.Core.POCO.Systems.Occurr { stringBuilder.Append("occurrence "); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExhibitStateUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExhibitStateUsageTextualNotationBuilder.cs index f585aedc..aa34003f 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExhibitStateUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExhibitStateUsageTextualNotationBuilder.cs @@ -55,12 +55,12 @@ public static void BuildExhibitStateUsage(SysML2.NET.Core.POCO.Systems.States.IE if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting elementAsReferenceSubsetting) { ReferenceSubsettingTextualNotationBuilder.BuildOwnedReferenceSubsetting(elementAsReferenceSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { FeatureTextualNotationBuilder.BuildFeatureSpecializationPart(poco, writerContext, stringBuilder); } @@ -73,7 +73,7 @@ public static void BuildExhibitStateUsage(SysML2.NET.Core.POCO.Systems.States.IE stringBuilder.Append(' '); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs index 5d354fe8..1ae32838 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs @@ -174,10 +174,10 @@ public static void BuildFunctionReference(SysML2.NET.Core.POCO.Kernel.Functions. if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping elementAsFeatureTyping) { FeatureTypingTextualNotationBuilder.BuildReferenceTyping(elementAsFeatureTyping, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -245,8 +245,9 @@ public static void BuildExpression(SysML2.NET.Core.POCO.Kernel.Functions.IExpres SharedTextualNotationBuilder.BuildFeaturePrefix(poco, writerContext, stringBuilder); stringBuilder.Append("expr "); FeatureTextualNotationBuilder.BuildFeatureDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureChainExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureChainExpressionTextualNotationBuilder.cs index 579caa9e..7226a74a 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureChainExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureChainExpressionTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildFeatureChainExpression(SysML2.NET.Core.POCO.Kernel.Expre if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildNonFeatureChainPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("."); if (ownedRelationshipCursor.Current != null) @@ -63,10 +63,10 @@ public static void BuildFeatureChainExpression(SysML2.NET.Core.POCO.Kernel.Expre if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) { MembershipTextualNotationBuilder.BuildFeatureChainMember(elementAsMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs index ff088b8e..1d39bbe6 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs @@ -52,10 +52,10 @@ public static void BuildNonOccurrenceUsageMember(SysML2.NET.Core.POCO.Core.Types if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage elementAsUsage) { UsageTextualNotationBuilder.BuildNonOccurrenceUsageElement(elementAsUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -77,10 +77,10 @@ public static void BuildOccurrenceUsageMember(SysML2.NET.Core.POCO.Core.Types.IF if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage elementAsUsage) { UsageTextualNotationBuilder.BuildOccurrenceUsageElement(elementAsUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -102,10 +102,10 @@ public static void BuildStructureUsageMember(SysML2.NET.Core.POCO.Core.Types.IFe if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage elementAsUsage) { UsageTextualNotationBuilder.BuildStructureUsageElement(elementAsUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -127,10 +127,10 @@ public static void BuildBehaviorUsageMember(SysML2.NET.Core.POCO.Core.Types.IFea if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage elementAsUsage) { UsageTextualNotationBuilder.BuildBehaviorUsageElement(elementAsUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -152,10 +152,10 @@ public static void BuildSourceSuccessionMember(SysML2.NET.Core.POCO.Core.Types.I if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Connections.ISuccessionAsUsage elementAsSuccessionAsUsage) { SuccessionAsUsageTextualNotationBuilder.BuildSourceSuccession(elementAsSuccessionAsUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -177,10 +177,10 @@ public static void BuildInterfaceNonOccurrenceUsageMember(SysML2.NET.Core.POCO.C if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage elementAsUsage) { UsageTextualNotationBuilder.BuildInterfaceNonOccurrenceUsageElement(elementAsUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -202,10 +202,10 @@ public static void BuildInterfaceOccurrenceUsageMember(SysML2.NET.Core.POCO.Core if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage elementAsUsage) { UsageTextualNotationBuilder.BuildInterfaceOccurrenceUsageElement(elementAsUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -226,10 +226,10 @@ public static void BuildFlowPayloadFeatureMember(SysML2.NET.Core.POCO.Core.Types if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Interactions.IPayloadFeature elementAsPayloadFeature) { PayloadFeatureTextualNotationBuilder.BuildFlowPayloadFeature(elementAsPayloadFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -250,10 +250,10 @@ public static void BuildFlowFeatureMember(SysML2.NET.Core.POCO.Core.Types.IFeatu if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildFlowFeature(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -312,10 +312,10 @@ public static void BuildActionNodeMember(SysML2.NET.Core.POCO.Core.Types.IFeatur if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Actions.IActionUsage elementAsActionUsage) { ActionUsageTextualNotationBuilder.BuildActionNode(elementAsActionUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -337,10 +337,10 @@ public static void BuildActionTargetSuccessionMember(SysML2.NET.Core.POCO.Core.T if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage elementAsUsage) { UsageTextualNotationBuilder.BuildActionTargetSuccession(elementAsUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -362,10 +362,10 @@ public static void BuildGuardedSuccessionMember(SysML2.NET.Core.POCO.Core.Types. if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.States.ITransitionUsage elementAsTransitionUsage) { TransitionUsageTextualNotationBuilder.BuildGuardedSuccession(elementAsTransitionUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -386,10 +386,10 @@ public static void BuildForVariableDeclarationMember(SysML2.NET.Core.POCO.Core.T if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage elementAsUsage) { UsageTextualNotationBuilder.BuildUsageDeclaration(elementAsUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -427,10 +427,10 @@ public static void BuildTransitionUsageMember(SysML2.NET.Core.POCO.Core.Types.IF if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.States.ITransitionUsage elementAsTransitionUsage) { TransitionUsageTextualNotationBuilder.BuildTransitionUsage(elementAsTransitionUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -452,10 +452,10 @@ public static void BuildTargetTransitionUsageMember(SysML2.NET.Core.POCO.Core.Ty if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.States.ITransitionUsage elementAsTransitionUsage) { TransitionUsageTextualNotationBuilder.BuildTargetTransitionUsage(elementAsTransitionUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -498,10 +498,10 @@ public static void BuildOwnedFeatureMember(SysML2.NET.Core.POCO.Core.Types.IFeat if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildFeatureElement(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -522,10 +522,10 @@ public static void BuildOwnedExpressionReferenceMember(SysML2.NET.Core.POCO.Core if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Expressions.IFeatureReferenceExpression elementAsFeatureReferenceExpression) { FeatureReferenceExpressionTextualNotationBuilder.BuildOwnedExpressionReference(elementAsFeatureReferenceExpression, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -639,10 +639,10 @@ public static void BuildPayloadFeatureMember(SysML2.NET.Core.POCO.Core.Types.IFe if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildPayloadFeature(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureReferenceExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureReferenceExpressionTextualNotationBuilder.cs index a4d8c155..2fe415ed 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureReferenceExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureReferenceExpressionTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildSatisfactionReferenceExpression(SysML2.NET.Core.POCO.Ker if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) { MembershipTextualNotationBuilder.BuildFeatureChainMember(elementAsMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -75,10 +75,10 @@ public static void BuildOwnedExpressionReference(SysML2.NET.Core.POCO.Kernel.Exp if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) { FeatureMembershipTextualNotationBuilder.BuildOwnedExpressionMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -99,10 +99,10 @@ public static void BuildFunctionReferenceExpression(SysML2.NET.Core.POCO.Kernel. if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) { FeatureMembershipTextualNotationBuilder.BuildFunctionReferenceMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -123,10 +123,10 @@ public static void BuildFeatureReferenceExpression(SysML2.NET.Core.POCO.Kernel.E if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) { MembershipTextualNotationBuilder.BuildFeatureReferenceMember(elementAsMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -134,10 +134,10 @@ public static void BuildFeatureReferenceExpression(SysML2.NET.Core.POCO.Kernel.E if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) { ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -158,10 +158,10 @@ public static void BuildBodyExpression(SysML2.NET.Core.POCO.Kernel.Expressions.I if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) { FeatureMembershipTextualNotationBuilder.BuildExpressionBodyMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs index 90805799..655dfcdf 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildValuePart(SysML2.NET.Core.POCO.Core.Features.IFeature po if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildFeatureValue(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -148,10 +148,10 @@ public static void BuildTypedBy(SysML2.NET.Core.POCO.Core.Features.IFeature poco if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping elementAsFeatureTyping) { FeatureTypingTextualNotationBuilder.BuildFeatureTyping(elementAsFeatureTyping, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -203,10 +203,10 @@ public static void BuildSubsets(SysML2.NET.Core.POCO.Core.Features.IFeature poco if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting elementAsSubsetting) { SubsettingTextualNotationBuilder.BuildOwnedSubsetting(elementAsSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -228,10 +228,10 @@ public static void BuildReferences(SysML2.NET.Core.POCO.Core.Features.IFeature p if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting elementAsReferenceSubsetting) { ReferenceSubsettingTextualNotationBuilder.BuildOwnedReferenceSubsetting(elementAsReferenceSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -253,10 +253,10 @@ public static void BuildCrosses(SysML2.NET.Core.POCO.Core.Features.IFeature poco if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting elementAsCrossSubsetting) { CrossSubsettingTextualNotationBuilder.BuildOwnedCrossSubsetting(elementAsCrossSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -308,10 +308,10 @@ public static void BuildRedefines(SysML2.NET.Core.POCO.Core.Features.IFeature po if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition elementAsRedefinition) { RedefinitionTextualNotationBuilder.BuildOwnedRedefinition(elementAsRedefinition, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -332,10 +332,10 @@ public static void BuildOwnedFeatureChain(SysML2.NET.Core.POCO.Core.Features.IFe if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureChaining elementAsFeatureChaining) { FeatureChainingTextualNotationBuilder.BuildOwnedFeatureChaining(elementAsFeatureChaining, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current != null && ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureChaining) { @@ -384,10 +384,10 @@ public static void BuildOwnedCrossMultiplicity(SysML2.NET.Core.POCO.Core.Feature if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildOwnedMultiplicity(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -449,10 +449,10 @@ public static void BuildFeatureChainPrefix(SysML2.NET.Core.POCO.Core.Features.IF if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureChaining elementAsFeatureChaining) { FeatureChainingTextualNotationBuilder.BuildOwnedFeatureChaining(elementAsFeatureChaining, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("."); } @@ -474,10 +474,10 @@ public static void BuildTriggerValuePart(SysML2.NET.Core.POCO.Core.Features.IFea if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildTriggerFeatureValue(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -498,10 +498,10 @@ public static void BuildArgument(SysML2.NET.Core.POCO.Core.Features.IFeature poc if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildArgumentValue(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -522,10 +522,10 @@ public static void BuildArgumentExpression(SysML2.NET.Core.POCO.Core.Features.IF if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildArgumentExpressionValue(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -753,10 +753,10 @@ public static void BuildInvertingPart(SysML2.NET.Core.POCO.Core.Features.IFeatur if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureInverting elementAsFeatureInverting) { FeatureInvertingTextualNotationBuilder.BuildOwnedFeatureInverting(elementAsFeatureInverting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -780,10 +780,10 @@ public static void BuildTypeFeaturingPart(SysML2.NET.Core.POCO.Core.Features.IFe if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ITypeFeaturing elementAsTypeFeaturing) { TypeFeaturingTextualNotationBuilder.BuildOwnedTypeFeaturing(elementAsTypeFeaturing, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedTypeFeaturingCursor.Current != null && ownedTypeFeaturingCursor.Current is SysML2.NET.Core.POCO.Core.Features.ITypeFeaturing) { @@ -820,10 +820,10 @@ public static void BuildFeatureChain(SysML2.NET.Core.POCO.Core.Features.IFeature if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureChaining elementAsFeatureChaining) { FeatureChainingTextualNotationBuilder.BuildOwnedFeatureChaining(elementAsFeatureChaining, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current != null && ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureChaining) { @@ -860,10 +860,10 @@ public static void BuildMetadataArgument(SysML2.NET.Core.POCO.Core.Features.IFea if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildMetadataValue(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -884,10 +884,10 @@ public static void BuildTypeReference(SysML2.NET.Core.POCO.Core.Features.IFeatur if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping elementAsFeatureTyping) { FeatureTypingTextualNotationBuilder.BuildReferenceTyping(elementAsFeatureTyping, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -908,10 +908,10 @@ public static void BuildPrimaryArgument(SysML2.NET.Core.POCO.Core.Features.IFeat if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildPrimaryArgumentValue(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -932,10 +932,10 @@ public static void BuildNonFeatureChainPrimaryArgument(SysML2.NET.Core.POCO.Core if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildNonFeatureChainPrimaryArgumentValue(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -956,10 +956,10 @@ public static void BuildBodyArgument(SysML2.NET.Core.POCO.Core.Features.IFeature if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildBodyArgumentValue(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -980,10 +980,10 @@ public static void BuildFunctionReferenceArgument(SysML2.NET.Core.POCO.Core.Feat if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildFunctionReferenceArgumentValue(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -1055,10 +1055,10 @@ public static void BuildPositionalArgumentList(SysML2.NET.Core.POCO.Core.Feature if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current != null && ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership) { @@ -1095,10 +1095,10 @@ public static void BuildNamedArgumentList(SysML2.NET.Core.POCO.Core.Features.IFe if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) { FeatureMembershipTextualNotationBuilder.BuildNamedArgumentMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current != null && ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership) { @@ -1135,10 +1135,10 @@ public static void BuildNamedArgument(SysML2.NET.Core.POCO.Core.Features.IFeatur if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition elementAsRedefinition) { RedefinitionTextualNotationBuilder.BuildParameterRedefinition(elementAsRedefinition, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("= "); if (ownedRelationshipCursor.Current != null) @@ -1147,10 +1147,10 @@ public static void BuildNamedArgument(SysML2.NET.Core.POCO.Core.Features.IFeatur if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildArgumentValue(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -1173,17 +1173,17 @@ public static void BuildMetadataBodyFeature(SysML2.NET.Core.POCO.Core.Features.I if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition elementAsRedefinition) { RedefinitionTextualNotationBuilder.BuildOwnedRedefinition(elementAsRedefinition, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { BuildFeatureSpecializationPart(poco, writerContext, stringBuilder); } - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { BuildValuePart(poco, writerContext, stringBuilder); } @@ -1204,7 +1204,7 @@ public static void BuildFeature(SysML2.NET.Core.POCO.Core.Features.IFeature poco BuildFeatureHandCoded(poco, writerContext, stringBuilder); stringBuilder.Append(' '); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureValueTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureValueTextualNotationBuilder.cs index 48298831..2c23f5a7 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureValueTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureValueTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildTriggerFeatureValue(SysML2.NET.Core.POCO.Kernel.FeatureV if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Actions.ITriggerInvocationExpression elementAsTriggerInvocationExpression) { TriggerInvocationExpressionTextualNotationBuilder.BuildTriggerExpression(elementAsTriggerInvocationExpression, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -92,10 +92,10 @@ public static void BuildArgumentExpressionValue(SysML2.NET.Core.POCO.Kernel.Feat if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Expressions.IFeatureReferenceExpression elementAsFeatureReferenceExpression) { FeatureReferenceExpressionTextualNotationBuilder.BuildOwnedExpressionReference(elementAsFeatureReferenceExpression, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -116,10 +116,10 @@ public static void BuildFeatureBinding(SysML2.NET.Core.POCO.Kernel.FeatureValues if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IExpression elementAsExpression) { ExpressionTextualNotationBuilder.BuildOwnedExpression(elementAsExpression, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -140,10 +140,10 @@ public static void BuildAssignmentTargetBinding(SysML2.NET.Core.POCO.Kernel.Feat if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IExpression elementAsExpression) { ExpressionTextualNotationBuilder.BuildNonFeatureChainPrimaryExpression(elementAsExpression, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -164,10 +164,10 @@ public static void BuildSatisfactionFeatureValue(SysML2.NET.Core.POCO.Kernel.Fea if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Expressions.IFeatureReferenceExpression elementAsFeatureReferenceExpression) { FeatureReferenceExpressionTextualNotationBuilder.BuildSatisfactionReferenceExpression(elementAsFeatureReferenceExpression, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -287,10 +287,10 @@ public static void BuildFeatureValue(SysML2.NET.Core.POCO.Kernel.FeatureValues.I if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IExpression elementAsExpression) { ExpressionTextualNotationBuilder.BuildOwnedExpression(elementAsExpression, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FlowEndTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FlowEndTextualNotationBuilder.cs index 5bb6bd99..f4e29c24 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FlowEndTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FlowEndTextualNotationBuilder.cs @@ -45,7 +45,7 @@ public static void BuildFlowEnd(SysML2.NET.Core.POCO.Kernel.Interactions.IFlowEn { var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current != null) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting && ownedRelationshipCursor.GetNext(1) is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership) { if (ownedRelationshipCursor.Current != null) @@ -68,10 +68,10 @@ public static void BuildFlowEnd(SysML2.NET.Core.POCO.Kernel.Interactions.IFlowEn if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) { FeatureMembershipTextualNotationBuilder.BuildFlowFeatureMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ForLoopActionUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ForLoopActionUsageTextualNotationBuilder.cs index 8ef714f3..f8bcf75b 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ForLoopActionUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ForLoopActionUsageTextualNotationBuilder.cs @@ -53,10 +53,10 @@ public static void BuildForLoopNode(SysML2.NET.Core.POCO.Systems.Actions.IForLoo if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) { FeatureMembershipTextualNotationBuilder.BuildForVariableDeclarationMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("in "); if (ownedRelationshipCursor.Current != null) @@ -65,10 +65,10 @@ public static void BuildForLoopNode(SysML2.NET.Core.POCO.Systems.Actions.IForLoo if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildNodeParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -76,10 +76,10 @@ public static void BuildForLoopNode(SysML2.NET.Core.POCO.Systems.Actions.IForLoo if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildActionBodyParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FramedConcernMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FramedConcernMembershipTextualNotationBuilder.cs index bf5e1391..f0cd26a8 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FramedConcernMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FramedConcernMembershipTextualNotationBuilder.cs @@ -57,10 +57,10 @@ public static void BuildFramedConcernMember(SysML2.NET.Core.POCO.Systems.Require if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Requirements.IConcernUsage elementAsConcernUsage) { ConcernUsageTextualNotationBuilder.BuildFramedConcernUsage(elementAsConcernUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IfActionUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IfActionUsageTextualNotationBuilder.cs index adc601d5..49665086 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IfActionUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IfActionUsageTextualNotationBuilder.cs @@ -53,10 +53,10 @@ public static void BuildIfNode(SysML2.NET.Core.POCO.Systems.Actions.IIfActionUsa if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildExpressionParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -64,10 +64,10 @@ public static void BuildIfNode(SysML2.NET.Core.POCO.Systems.Actions.IIfActionUsa if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildActionBodyParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IncludeUseCaseUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IncludeUseCaseUsageTextualNotationBuilder.cs index 4645d12e..b3d20776 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IncludeUseCaseUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IncludeUseCaseUsageTextualNotationBuilder.cs @@ -55,12 +55,12 @@ public static void BuildIncludeUseCaseUsage(SysML2.NET.Core.POCO.Systems.UseCase if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting elementAsReferenceSubsetting) { ReferenceSubsettingTextualNotationBuilder.BuildOwnedReferenceSubsetting(elementAsReferenceSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { FeatureTextualNotationBuilder.BuildFeatureSpecializationPart(poco, writerContext, stringBuilder); } @@ -74,7 +74,7 @@ public static void BuildIncludeUseCaseUsage(SysML2.NET.Core.POCO.Systems.UseCase stringBuilder.Append(' '); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IndexExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IndexExpressionTextualNotationBuilder.cs index c9b50030..493bc3e4 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IndexExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IndexExpressionTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildIndexExpression(SysML2.NET.Core.POCO.Kernel.Expressions. if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("#"); stringBuilder.Append("("); @@ -64,10 +64,10 @@ public static void BuildIndexExpression(SysML2.NET.Core.POCO.Kernel.Expressions. if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) { FeatureMembershipTextualNotationBuilder.BuildSequenceExpressionListMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append(") "); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InterfaceUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InterfaceUsageTextualNotationBuilder.cs index 74b66b18..8f757ee8 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InterfaceUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InterfaceUsageTextualNotationBuilder.cs @@ -84,10 +84,10 @@ public static void BuildBinaryInterfacePart(SysML2.NET.Core.POCO.Systems.Interfa if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildInterfaceEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("to "); if (ownedRelationshipCursor.Current != null) @@ -96,10 +96,10 @@ public static void BuildBinaryInterfacePart(SysML2.NET.Core.POCO.Systems.Interfa if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildInterfaceEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -121,10 +121,10 @@ public static void BuildNaryInterfacePart(SysML2.NET.Core.POCO.Systems.Interface if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildInterfaceEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append(", "); if (ownedRelationshipCursor.Current != null) @@ -133,10 +133,10 @@ public static void BuildNaryInterfacePart(SysML2.NET.Core.POCO.Systems.Interface if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildInterfaceEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership endFeatureMembershipGuard && endFeatureMembershipGuard.OwnedRelatedElement.OfType().Any()) { diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InvariantTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InvariantTextualNotationBuilder.cs index b6cb5d3c..12b8a48d 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InvariantTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InvariantTextualNotationBuilder.cs @@ -55,8 +55,9 @@ public static void BuildInvariant(SysML2.NET.Core.POCO.Kernel.Functions.IInvaria stringBuilder.Append(" false "); } FeatureTextualNotationBuilder.BuildFeatureDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InvocationExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InvocationExpressionTextualNotationBuilder.cs index d1f9e6ca..b2603e6e 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InvocationExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/InvocationExpressionTextualNotationBuilder.cs @@ -51,18 +51,18 @@ public static void BuildFunctionOperationExpression(SysML2.NET.Core.POCO.Kernel. if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("-> "); if (ownedRelationshipCursor.Current != null) { BuildInvocationTypeMember(poco, writerContext, stringBuilder); - } - ownedRelationshipCursor.Move(); + ownedRelationshipCursor.Move(); + } if (ownedRelationshipCursor.Current != null) { @@ -99,10 +99,10 @@ public static void BuildFunctionOperationExpression(SysML2.NET.Core.POCO.Kernel. if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) { ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -123,10 +123,10 @@ public static void BuildInvocationExpression(SysML2.NET.Core.POCO.Kernel.Express if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) { MembershipTextualNotationBuilder.BuildInstantiatedTypeMember(elementAsMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - FeatureTextualNotationBuilder.BuildArgumentList(poco, writerContext, stringBuilder); if (ownedRelationshipCursor.Current != null) @@ -135,10 +135,10 @@ public static void BuildInvocationExpression(SysML2.NET.Core.POCO.Kernel.Express if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) { ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs index 2742edc8..76368111 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs @@ -68,7 +68,7 @@ public static void BuildAliasMember(SysML2.NET.Core.POCO.Root.Namespaces.IMember if (!string.IsNullOrWhiteSpace(poco.MemberShortName)) { stringBuilder.Append("<"); - stringBuilder.Append(poco.MemberShortName); + SharedTextualNotationBuilder.AppendName(stringBuilder, poco.MemberShortName); stringBuilder.Append(">"); stringBuilder.Append(' '); } @@ -76,7 +76,7 @@ public static void BuildAliasMember(SysML2.NET.Core.POCO.Root.Namespaces.IMember if (!string.IsNullOrWhiteSpace(poco.MemberName)) { - stringBuilder.Append(poco.MemberName); + SharedTextualNotationBuilder.AppendName(stringBuilder, poco.MemberName); stringBuilder.Append(' '); } @@ -116,10 +116,10 @@ public static void BuildFeatureChainMember(SysML2.NET.Core.POCO.Root.Namespaces. if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildOwnedFeatureChain(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } @@ -191,10 +191,10 @@ public static void BuildInstantiatedTypeMember(SysML2.NET.Core.POCO.Root.Namespa if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildOwnedFeatureChain(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataAccessExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataAccessExpressionTextualNotationBuilder.cs index b94bceaf..81599f37 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataAccessExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataAccessExpressionTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildMetadataReference(SysML2.NET.Core.POCO.Kernel.Expression if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) { MembershipTextualNotationBuilder.BuildElementReferenceMember(elementAsMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -75,10 +75,10 @@ public static void BuildMetadataAccessExpression(SysML2.NET.Core.POCO.Kernel.Exp if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) { MembershipTextualNotationBuilder.BuildElementReferenceMember(elementAsMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("."); stringBuilder.Append("metadata "); diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataFeatureTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataFeatureTextualNotationBuilder.cs index 173b315e..35641e35 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataFeatureTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataFeatureTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildPrefixMetadataFeature(SysML2.NET.Core.POCO.Kernel.Metada if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping elementAsFeatureTyping) { FeatureTypingTextualNotationBuilder.BuildOwnedFeatureTyping(elementAsFeatureTyping, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -83,10 +83,10 @@ public static void BuildMetadataFeatureDeclaration(SysML2.NET.Core.POCO.Kernel.M if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping elementAsFeatureTyping) { FeatureTypingTextualNotationBuilder.BuildOwnedFeatureTyping(elementAsFeatureTyping, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataUsageTextualNotationBuilder.cs index e2b7121f..faf5e7ce 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MetadataUsageTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildPrefixMetadataUsage(SysML2.NET.Core.POCO.Systems.Metadat if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping elementAsFeatureTyping) { FeatureTypingTextualNotationBuilder.BuildOwnedFeatureTyping(elementAsFeatureTyping, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -83,10 +83,10 @@ public static void BuildMetadataUsageDeclaration(SysML2.NET.Core.POCO.Systems.Me if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping elementAsFeatureTyping) { FeatureTypingTextualNotationBuilder.BuildOwnedFeatureTyping(elementAsFeatureTyping, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityRangeTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityRangeTextualNotationBuilder.cs index 8d81376a..b62ba902 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityRangeTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityRangeTextualNotationBuilder.cs @@ -59,7 +59,7 @@ public static void BuildMultiplicityBounds(SysML2.NET.Core.POCO.Kernel.Multiplic var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); stringBuilder.Append("["); - if (ownedRelationshipCursor.Current != null) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership && ownedRelationshipCursor.GetNext(1) is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) { if (ownedRelationshipCursor.Current != null) @@ -83,10 +83,10 @@ public static void BuildMultiplicityBounds(SysML2.NET.Core.POCO.Kernel.Multiplic if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildMultiplicityExpressionMember(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("] "); } @@ -103,7 +103,7 @@ public static void BuildMultiplicityRange(SysML2.NET.Core.POCO.Kernel.Multiplici var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); stringBuilder.Append("["); - if (ownedRelationshipCursor.Current != null) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership && ownedRelationshipCursor.GetNext(1) is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) { if (ownedRelationshipCursor.Current != null) @@ -127,10 +127,10 @@ public static void BuildMultiplicityRange(SysML2.NET.Core.POCO.Kernel.Multiplici if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildMultiplicityExpressionMember(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("] "); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ObjectiveMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ObjectiveMembershipTextualNotationBuilder.cs index fe272ead..ece95ef6 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ObjectiveMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ObjectiveMembershipTextualNotationBuilder.cs @@ -53,10 +53,10 @@ public static void BuildObjectiveMember(SysML2.NET.Core.POCO.Systems.Cases.IObje if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Requirements.IRequirementUsage elementAsRequirementUsage) { RequirementUsageTextualNotationBuilder.BuildObjectiveRequirementUsage(elementAsRequirementUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OccurrenceDefinitionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OccurrenceDefinitionTextualNotationBuilder.cs index 9086ae7c..32cd40e5 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OccurrenceDefinitionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OccurrenceDefinitionTextualNotationBuilder.cs @@ -108,10 +108,10 @@ public static void BuildIndividualDefinition(SysML2.NET.Core.POCO.Systems.Occurr if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildEmptyMultiplicityMember(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OperatorExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OperatorExpressionTextualNotationBuilder.cs index 7a8e803e..c61fdefa 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OperatorExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OperatorExpressionTextualNotationBuilder.cs @@ -52,10 +52,10 @@ public static void BuildConditionalExpression(SysML2.NET.Core.POCO.Kernel.Expres if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("? "); if (ownedRelationshipCursor.Current != null) @@ -64,10 +64,10 @@ public static void BuildConditionalExpression(SysML2.NET.Core.POCO.Kernel.Expres if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildArgumentExpressionMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("else "); if (ownedRelationshipCursor.Current != null) @@ -76,10 +76,10 @@ public static void BuildConditionalExpression(SysML2.NET.Core.POCO.Kernel.Expres if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildArgumentExpressionMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -87,10 +87,10 @@ public static void BuildConditionalExpression(SysML2.NET.Core.POCO.Kernel.Expres if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) { ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -111,10 +111,10 @@ public static void BuildConditionalBinaryOperatorExpression(SysML2.NET.Core.POCO if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append(poco.Operator); if (ownedRelationshipCursor.Current != null) @@ -123,10 +123,10 @@ public static void BuildConditionalBinaryOperatorExpression(SysML2.NET.Core.POCO if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildArgumentExpressionMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -134,10 +134,10 @@ public static void BuildConditionalBinaryOperatorExpression(SysML2.NET.Core.POCO if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) { ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -158,10 +158,10 @@ public static void BuildBinaryOperatorExpression(SysML2.NET.Core.POCO.Kernel.Exp if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append(poco.Operator); if (ownedRelationshipCursor.Current != null) @@ -170,10 +170,10 @@ public static void BuildBinaryOperatorExpression(SysML2.NET.Core.POCO.Kernel.Exp if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -181,10 +181,10 @@ public static void BuildBinaryOperatorExpression(SysML2.NET.Core.POCO.Kernel.Exp if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) { ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -206,10 +206,10 @@ public static void BuildUnaryOperatorExpression(SysML2.NET.Core.POCO.Kernel.Expr if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -217,10 +217,10 @@ public static void BuildUnaryOperatorExpression(SysML2.NET.Core.POCO.Kernel.Expr if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) { ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -260,10 +260,10 @@ public static void BuildClassificationExpression(SysML2.NET.Core.POCO.Kernel.Exp if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) { ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -284,10 +284,10 @@ public static void BuildMetaclassificationExpression(SysML2.NET.Core.POCO.Kernel if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildMetadataArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - BuildMetaclassificationExpressionHandCoded(poco, writerContext, stringBuilder); stringBuilder.Append(' '); @@ -297,10 +297,10 @@ public static void BuildMetaclassificationExpression(SysML2.NET.Core.POCO.Kernel if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) { ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -322,10 +322,10 @@ public static void BuildExtentExpression(SysML2.NET.Core.POCO.Kernel.Expressions if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildTypeReferenceMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -346,10 +346,10 @@ public static void BuildBracketExpression(SysML2.NET.Core.POCO.Kernel.Expression if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append(poco.Operator); if (ownedRelationshipCursor.Current != null) @@ -358,10 +358,10 @@ public static void BuildBracketExpression(SysML2.NET.Core.POCO.Kernel.Expression if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) { FeatureMembershipTextualNotationBuilder.BuildSequenceExpressionListMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("] "); } @@ -383,10 +383,10 @@ public static void BuildSequenceOperatorExpression(SysML2.NET.Core.POCO.Kernel.E if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) { FeatureMembershipTextualNotationBuilder.BuildOwnedExpressionMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append(poco.Operator); if (ownedRelationshipCursor.Current != null) @@ -395,10 +395,10 @@ public static void BuildSequenceOperatorExpression(SysML2.NET.Core.POCO.Kernel.E if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) { FeatureMembershipTextualNotationBuilder.BuildSequenceExpressionListMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OwningMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OwningMembershipTextualNotationBuilder.cs index 1da74140..b3de9f74 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OwningMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OwningMembershipTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildAnnotatingMember(SysML2.NET.Core.POCO.Root.Namespaces.IO if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Root.Annotations.IAnnotatingElement elementAsAnnotatingElement) { AnnotatingElementTextualNotationBuilder.BuildAnnotatingElement(elementAsAnnotatingElement, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -104,10 +104,10 @@ public static void BuildDefinitionMember(SysML2.NET.Core.POCO.Root.Namespaces.IO if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Root.Elements.IElement elementAsElement) { ElementTextualNotationBuilder.BuildDefinitionElement(elementAsElement, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -128,10 +128,10 @@ public static void BuildOwnedCrossFeatureMember(SysML2.NET.Core.POCO.Root.Namesp if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildOwnedCrossFeature(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -152,10 +152,10 @@ public static void BuildOwnedMultiplicity(SysML2.NET.Core.POCO.Root.Namespaces.I if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Multiplicities.IMultiplicityRange elementAsMultiplicityRange) { MultiplicityRangeTextualNotationBuilder.BuildMultiplicityRange(elementAsMultiplicityRange, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -200,10 +200,10 @@ public static void BuildEmptyMultiplicityMember(SysML2.NET.Core.POCO.Root.Namesp if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Types.IMultiplicity elementAsMultiplicity) { MultiplicityTextualNotationBuilder.BuildEmptyMultiplicity(elementAsMultiplicity, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -224,10 +224,10 @@ public static void BuildConjugatedPortDefinitionMember(SysML2.NET.Core.POCO.Root if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Ports.IConjugatedPortDefinition elementAsConjugatedPortDefinition) { ConjugatedPortDefinitionTextualNotationBuilder.BuildConjugatedPortDefinition(elementAsConjugatedPortDefinition, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -248,10 +248,10 @@ public static void BuildOwnedCrossMultiplicityMember(SysML2.NET.Core.POCO.Root.N if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildOwnedCrossMultiplicity(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -272,10 +272,10 @@ public static void BuildOwnedFeatureChainMember(SysML2.NET.Core.POCO.Root.Namesp if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildOwnedFeatureChain(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -296,10 +296,10 @@ public static void BuildTransitionSuccessionMember(SysML2.NET.Core.POCO.Root.Nam if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Connectors.ISuccession elementAsSuccession) { SuccessionTextualNotationBuilder.BuildTransitionSuccession(elementAsSuccession, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -321,10 +321,10 @@ public static void BuildPrefixMetadataMember(SysML2.NET.Core.POCO.Root.Namespace if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Metadata.IMetadataUsage elementAsMetadataUsage) { MetadataUsageTextualNotationBuilder.BuildPrefixMetadataUsage(elementAsMetadataUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -367,10 +367,10 @@ public static void BuildNonFeatureMember(SysML2.NET.Core.POCO.Root.Namespaces.IO if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Root.Elements.IElement elementAsElement) { ElementTextualNotationBuilder.BuildMemberElement(elementAsElement, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -392,10 +392,10 @@ public static void BuildNamespaceFeatureMember(SysML2.NET.Core.POCO.Root.Namespa if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildFeatureElement(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -439,10 +439,10 @@ public static void BuildTypeFeatureMember(SysML2.NET.Core.POCO.Root.Namespaces.I if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildFeatureElement(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PackageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PackageTextualNotationBuilder.cs index c014ee95..35991f0f 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PackageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PackageTextualNotationBuilder.cs @@ -124,9 +124,9 @@ public static void BuildFilterPackage(SysML2.NET.Core.POCO.Kernel.Packages.IPack if (ownedRelationshipCursor.Current != null) { BuildFilterPackageImport(poco, writerContext, stringBuilder); - } - ownedRelationshipCursor.Move(); + ownedRelationshipCursor.Move(); + } while (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Packages.IElementFilterMembership elementFilterMembershipGuard && elementFilterMembershipGuard.OwnedRelatedElement.OfType().Any()) { diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ParameterMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ParameterMembershipTextualNotationBuilder.cs index ccf74fa1..e1bc58f3 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ParameterMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ParameterMembershipTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildMessageEventMember(SysML2.NET.Core.POCO.Kernel.Behaviors if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Occurrences.IEventOccurrenceUsage elementAsEventOccurrenceUsage) { EventOccurrenceUsageTextualNotationBuilder.BuildMessageEvent(elementAsEventOccurrenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -75,10 +75,10 @@ public static void BuildPayloadParameterMember(SysML2.NET.Core.POCO.Kernel.Behav if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildPayloadParameter(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -116,10 +116,10 @@ public static void BuildArgumentExpressionMember(SysML2.NET.Core.POCO.Kernel.Beh if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildArgumentExpression(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -140,10 +140,10 @@ public static void BuildNodeParameterMember(SysML2.NET.Core.POCO.Kernel.Behavior if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildNodeParameter(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -164,10 +164,10 @@ public static void BuildEmptyParameterMember(SysML2.NET.Core.POCO.Kernel.Behavio if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildEmptyUsage(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -188,10 +188,10 @@ public static void BuildAssignmentTargetMember(SysML2.NET.Core.POCO.Kernel.Behav if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildAssignmentTargetParameter(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -212,10 +212,10 @@ public static void BuildExpressionParameterMember(SysML2.NET.Core.POCO.Kernel.Be if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IExpression elementAsExpression) { ExpressionTextualNotationBuilder.BuildOwnedExpression(elementAsExpression, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -236,10 +236,10 @@ public static void BuildActionBodyParameterMember(SysML2.NET.Core.POCO.Kernel.Be if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Actions.IActionUsage elementAsActionUsage) { ActionUsageTextualNotationBuilder.BuildActionBodyParameter(elementAsActionUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -260,10 +260,10 @@ public static void BuildIfNodeParameterMember(SysML2.NET.Core.POCO.Kernel.Behavi if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Actions.IIfActionUsage elementAsIfActionUsage) { IfActionUsageTextualNotationBuilder.BuildIfNode(elementAsIfActionUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -284,10 +284,10 @@ public static void BuildMetadataArgumentMember(SysML2.NET.Core.POCO.Kernel.Behav if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildMetadataArgument(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PerformActionUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PerformActionUsageTextualNotationBuilder.cs index 6faf3922..c1aafdb3 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PerformActionUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PerformActionUsageTextualNotationBuilder.cs @@ -53,12 +53,12 @@ public static void BuildPerformActionUsageDeclaration(SysML2.NET.Core.POCO.Syste if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting elementAsReferenceSubsetting) { ReferenceSubsettingTextualNotationBuilder.BuildOwnedReferenceSubsetting(elementAsReferenceSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { FeatureTextualNotationBuilder.BuildFeatureSpecializationPart(poco, writerContext, stringBuilder); } @@ -71,7 +71,7 @@ public static void BuildPerformActionUsageDeclaration(SysML2.NET.Core.POCO.Syste stringBuilder.Append(' '); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } @@ -102,12 +102,12 @@ public static void BuildStatePerformActionUsage(SysML2.NET.Core.POCO.Systems.Act public static void BuildTransitionPerformActionUsage(SysML2.NET.Core.POCO.Systems.Actions.IPerformActionUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { BuildPerformActionUsageDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.importedMembership.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IImport || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IVariantMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership) || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { stringBuilder.Append(' '); stringBuilder.AppendLine("{"); - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); while (ownedRelationshipCursor.Current != null) { TypeTextualNotationBuilder.BuildActionBodyItem(poco, writerContext, stringBuilder); diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PortDefinitionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PortDefinitionTextualNotationBuilder.cs index aea841ed..41bedcea 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PortDefinitionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PortDefinitionTextualNotationBuilder.cs @@ -55,10 +55,10 @@ public static void BuildPortDefinition(SysML2.NET.Core.POCO.Systems.Ports.IPortD if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildConjugatedPortDefinitionMember(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - // NonParsing Assignment Element : conjugatedPortDefinition.ownedPortConjugator.originalPortDefinition = this => Does not have to be process } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PortUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PortUsageTextualNotationBuilder.cs index 8ee0a314..44ce7bd0 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PortUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/PortUsageTextualNotationBuilder.cs @@ -62,7 +62,7 @@ public static void BuildInterfaceEnd(SysML2.NET.Core.POCO.Systems.Ports.IPortUsa { var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current != null) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership && ownedRelationshipCursor.GetNext(1) is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting) { if (ownedRelationshipCursor.Current != null) @@ -81,7 +81,7 @@ public static void BuildInterfaceEnd(SysML2.NET.Core.POCO.Systems.Ports.IPortUsa if (!string.IsNullOrWhiteSpace(poco.DeclaredName)) { - stringBuilder.Append(poco.DeclaredName); + SharedTextualNotationBuilder.AppendName(stringBuilder, poco.DeclaredName); stringBuilder.Append(" ::> "); stringBuilder.Append(' '); } @@ -93,10 +93,10 @@ public static void BuildInterfaceEnd(SysML2.NET.Core.POCO.Systems.Ports.IPortUsa if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting elementAsReferenceSubsetting) { ReferenceSubsettingTextualNotationBuilder.BuildOwnedReferenceSubsetting(elementAsReferenceSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs index fdcfe8d3..e19ec23a 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs @@ -79,10 +79,10 @@ public static void BuildVariantReference(SysML2.NET.Core.POCO.Systems.Definition if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting elementAsReferenceSubsetting) { ReferenceSubsettingTextualNotationBuilder.BuildOwnedReferenceSubsetting(elementAsReferenceSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current is not null and not SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage) { FeatureTextualNotationBuilder.BuildFeatureSpecialization(poco, writerContext, stringBuilder); @@ -132,7 +132,7 @@ public static void BuildConnectorEnd(SysML2.NET.Core.POCO.Systems.DefinitionAndU { var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current != null) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership && ownedRelationshipCursor.GetNext(1) is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting) { if (ownedRelationshipCursor.Current != null) @@ -151,7 +151,7 @@ public static void BuildConnectorEnd(SysML2.NET.Core.POCO.Systems.DefinitionAndU if (!string.IsNullOrWhiteSpace(poco.DeclaredName)) { - stringBuilder.Append(poco.DeclaredName); + SharedTextualNotationBuilder.AppendName(stringBuilder, poco.DeclaredName); stringBuilder.Append(" ::> "); stringBuilder.Append(' '); } @@ -163,10 +163,10 @@ public static void BuildConnectorEnd(SysML2.NET.Core.POCO.Systems.DefinitionAndU if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting elementAsReferenceSubsetting) { ReferenceSubsettingTextualNotationBuilder.BuildOwnedReferenceSubsetting(elementAsReferenceSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -187,10 +187,10 @@ public static void BuildFlowFeature(SysML2.NET.Core.POCO.Systems.DefinitionAndUs if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition elementAsRedefinition) { RedefinitionTextualNotationBuilder.BuildFlowFeatureRedefinition(elementAsRedefinition, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -223,10 +223,10 @@ public static void BuildNodeParameter(SysML2.NET.Core.POCO.Systems.DefinitionAnd if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildFeatureBinding(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -334,10 +334,10 @@ public static void BuildSatisfactionParameter(SysML2.NET.Core.POCO.Systems.Defin if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue elementAsFeatureValue) { FeatureValueTextualNotationBuilder.BuildSatisfactionFeatureValue(elementAsFeatureValue, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -360,17 +360,17 @@ public static void BuildMetadataBodyUsage(SysML2.NET.Core.POCO.Systems.Definitio if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition elementAsRedefinition) { RedefinitionTextualNotationBuilder.BuildOwnedRedefinition(elementAsRedefinition, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { FeatureTextualNotationBuilder.BuildFeatureSpecializationPart(poco, writerContext, stringBuilder); } - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RequirementConstraintMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RequirementConstraintMembershipTextualNotationBuilder.cs index 93167d7f..5b735a63 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RequirementConstraintMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RequirementConstraintMembershipTextualNotationBuilder.cs @@ -57,10 +57,10 @@ public static void BuildRequirementConstraintMember(SysML2.NET.Core.POCO.Systems if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Constraints.IConstraintUsage elementAsConstraintUsage) { ConstraintUsageTextualNotationBuilder.BuildRequirementConstraintUsage(elementAsConstraintUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RequirementVerificationMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RequirementVerificationMembershipTextualNotationBuilder.cs index 59ff02d2..6bd705f4 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RequirementVerificationMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/RequirementVerificationMembershipTextualNotationBuilder.cs @@ -54,10 +54,10 @@ public static void BuildRequirementVerificationMember(SysML2.NET.Core.POCO.Syste if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Requirements.IRequirementUsage elementAsRequirementUsage) { RequirementUsageTextualNotationBuilder.BuildRequirementVerificationUsage(elementAsRequirementUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ResultExpressionMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ResultExpressionMembershipTextualNotationBuilder.cs index 16b7729f..346723bd 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ResultExpressionMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ResultExpressionMembershipTextualNotationBuilder.cs @@ -56,10 +56,10 @@ public static void BuildResultExpressionMember(SysML2.NET.Core.POCO.Kernel.Funct if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IExpression elementAsExpression) { ExpressionTextualNotationBuilder.BuildOwnedExpression(elementAsExpression, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReturnParameterMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReturnParameterMembershipTextualNotationBuilder.cs index fdca3e7c..2d19870b 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReturnParameterMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReturnParameterMembershipTextualNotationBuilder.cs @@ -57,10 +57,10 @@ public static void BuildReturnParameterMember(SysML2.NET.Core.POCO.Kernel.Functi if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage elementAsUsage) { UsageTextualNotationBuilder.BuildUsageElement(elementAsUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -83,10 +83,10 @@ public static void BuildReturnFeatureMember(SysML2.NET.Core.POCO.Kernel.Function if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildFeatureElement(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -107,10 +107,10 @@ public static void BuildEmptyResultMember(SysML2.NET.Core.POCO.Kernel.Functions. if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildEmptyFeature(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -131,10 +131,10 @@ public static void BuildConstructorResultMember(SysML2.NET.Core.POCO.Kernel.Func if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeature elementAsFeature) { FeatureTextualNotationBuilder.BuildConstructorResult(elementAsFeature, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SatisfyRequirementUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SatisfyRequirementUsageTextualNotationBuilder.cs index 3feb425b..9ab5c9a0 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SatisfyRequirementUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SatisfyRequirementUsageTextualNotationBuilder.cs @@ -62,12 +62,12 @@ public static void BuildSatisfyRequirementUsage(SysML2.NET.Core.POCO.Systems.Req if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting elementAsReferenceSubsetting) { ReferenceSubsettingTextualNotationBuilder.BuildOwnedReferenceSubsetting(elementAsReferenceSubsetting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { FeatureTextualNotationBuilder.BuildFeatureSpecializationPart(poco, writerContext, stringBuilder); } @@ -80,7 +80,7 @@ public static void BuildSatisfyRequirementUsage(SysML2.NET.Core.POCO.Systems.Req stringBuilder.Append(' '); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SelectExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SelectExpressionTextualNotationBuilder.cs index a71bbc3c..a66e9b8d 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SelectExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SelectExpressionTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildSelectExpression(SysML2.NET.Core.POCO.Kernel.Expressions if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append(".? "); if (ownedRelationshipCursor.Current != null) @@ -63,10 +63,10 @@ public static void BuildSelectExpression(SysML2.NET.Core.POCO.Kernel.Expressions if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildBodyArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SendActionUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SendActionUsageTextualNotationBuilder.cs index af11f0f7..d21d6f0a 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SendActionUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SendActionUsageTextualNotationBuilder.cs @@ -46,7 +46,7 @@ public static void BuildSendNode(SysML2.NET.Core.POCO.Systems.Actions.ISendActio var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); OccurrenceUsageTextualNotationBuilder.BuildOccurrenceUsagePrefix(poco, writerContext, stringBuilder); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue) || poco.IsOrdered || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { ActionUsageTextualNotationBuilder.BuildActionUsageDeclaration(poco, writerContext, stringBuilder); } @@ -67,7 +67,7 @@ public static void BuildSendNodeDeclaration(SysML2.NET.Core.POCO.Systems.Actions { var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { ActionUsageTextualNotationBuilder.BuildActionNodeUsageDeclaration(poco, writerContext, stringBuilder); } @@ -79,12 +79,12 @@ public static void BuildSendNodeDeclaration(SysML2.NET.Core.POCO.Systems.Actions if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildNodeParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { BuildSenderReceiverPart(poco, writerContext, stringBuilder); } @@ -127,12 +127,12 @@ public static void BuildStateSendActionUsage(SysML2.NET.Core.POCO.Systems.Action public static void BuildTransitionSendActionUsage(SysML2.NET.Core.POCO.Systems.Actions.ISendActionUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { BuildSendNodeDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.importedMembership.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IImport || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IVariantMembership || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership) || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsVariation || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.isReference || poco.IsIndividual || poco.PortionKind.HasValue || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { stringBuilder.Append(' '); stringBuilder.AppendLine("{"); - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); while (ownedRelationshipCursor.Current != null) { TypeTextualNotationBuilder.BuildActionBodyItem(poco, writerContext, stringBuilder); diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StakeholderMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StakeholderMembershipTextualNotationBuilder.cs index c96097bc..68386416 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StakeholderMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StakeholderMembershipTextualNotationBuilder.cs @@ -52,10 +52,10 @@ public static void BuildStakeholderMember(SysML2.NET.Core.POCO.Systems.Requireme if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Parts.IPartUsage elementAsPartUsage) { PartUsageTextualNotationBuilder.BuildStakeholderUsage(elementAsPartUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StateSubactionMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StateSubactionMembershipTextualNotationBuilder.cs index 9c0aadd3..382442d1 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StateSubactionMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StateSubactionMembershipTextualNotationBuilder.cs @@ -54,10 +54,10 @@ public static void BuildEntryActionMember(SysML2.NET.Core.POCO.Systems.States.IS if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Actions.IActionUsage elementAsActionUsage) { ActionUsageTextualNotationBuilder.BuildStateActionUsage(elementAsActionUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -81,10 +81,10 @@ public static void BuildDoActionMember(SysML2.NET.Core.POCO.Systems.States.IStat if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Actions.IActionUsage elementAsActionUsage) { ActionUsageTextualNotationBuilder.BuildStateActionUsage(elementAsActionUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -108,10 +108,10 @@ public static void BuildExitActionMember(SysML2.NET.Core.POCO.Systems.States.ISt if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Actions.IActionUsage elementAsActionUsage) { ActionUsageTextualNotationBuilder.BuildStateActionUsage(elementAsActionUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StepTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StepTextualNotationBuilder.cs index 4234b47f..d87c4c97 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StepTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/StepTextualNotationBuilder.cs @@ -46,8 +46,9 @@ public static void BuildStep(SysML2.NET.Core.POCO.Kernel.Behaviors.IStep poco, T SharedTextualNotationBuilder.BuildFeaturePrefix(poco, writerContext, stringBuilder); stringBuilder.Append("step "); FeatureTextualNotationBuilder.BuildFeatureDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SubjectMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SubjectMembershipTextualNotationBuilder.cs index 7c5e12cb..45a9fa4c 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SubjectMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SubjectMembershipTextualNotationBuilder.cs @@ -52,10 +52,10 @@ public static void BuildSubjectMember(SysML2.NET.Core.POCO.Systems.Requirements. if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildSubjectUsage(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -76,10 +76,10 @@ public static void BuildSatisfactionSubjectMember(SysML2.NET.Core.POCO.Systems.R if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage elementAsReferenceUsage) { ReferenceUsageTextualNotationBuilder.BuildSatisfactionParameter(elementAsReferenceUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SuccessionAsUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SuccessionAsUsageTextualNotationBuilder.cs index efb9d268..ac3a8205 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SuccessionAsUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SuccessionAsUsageTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildSourceSuccession(SysML2.NET.Core.POCO.Systems.Connection if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildSourceEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -75,10 +75,10 @@ public static void BuildTargetSuccession(SysML2.NET.Core.POCO.Systems.Connection if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildSourceEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("then "); if (ownedRelationshipCursor.Current != null) @@ -87,10 +87,10 @@ public static void BuildTargetSuccession(SysML2.NET.Core.POCO.Systems.Connection if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -106,7 +106,7 @@ public static void BuildSuccessionAsUsage(SysML2.NET.Core.POCO.Systems.Connectio var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); UsageTextualNotationBuilder.BuildUsagePrefix(poco, writerContext, stringBuilder); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.OwnedRelatedElement.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { stringBuilder.Append("succession "); UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); @@ -121,10 +121,10 @@ public static void BuildSuccessionAsUsage(SysML2.NET.Core.POCO.Systems.Connectio if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("then "); if (ownedRelationshipCursor.Current != null) @@ -133,10 +133,10 @@ public static void BuildSuccessionAsUsage(SysML2.NET.Core.POCO.Systems.Connectio if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - UsageTextualNotationBuilder.BuildUsageBody(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SuccessionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SuccessionTextualNotationBuilder.cs index 7b7d83f7..371fbc63 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SuccessionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SuccessionTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildTransitionSuccession(SysML2.NET.Core.POCO.Kernel.Connect if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildEmptyEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -62,10 +62,10 @@ public static void BuildTransitionSuccession(SysML2.NET.Core.POCO.Kernel.Connect if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IEndFeatureMembership elementAsEndFeatureMembership) { EndFeatureMembershipTextualNotationBuilder.BuildConnectorEndMember(elementAsEndFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TerminateActionUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TerminateActionUsageTextualNotationBuilder.cs index 09e476c0..b2d22066 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TerminateActionUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TerminateActionUsageTextualNotationBuilder.cs @@ -46,7 +46,7 @@ public static void BuildTerminateNode(SysML2.NET.Core.POCO.Systems.Actions.ITerm var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); OccurrenceUsageTextualNotationBuilder.BuildOccurrenceUsagePrefix(poco, writerContext, stringBuilder); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { ActionUsageTextualNotationBuilder.BuildActionNodeUsageDeclaration(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TransitionFeatureMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TransitionFeatureMembershipTextualNotationBuilder.cs index 5859047f..3d31bb02 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TransitionFeatureMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TransitionFeatureMembershipTextualNotationBuilder.cs @@ -53,10 +53,10 @@ public static void BuildTriggerActionMember(SysML2.NET.Core.POCO.Systems.States. if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Actions.IAcceptActionUsage elementAsAcceptActionUsage) { AcceptActionUsageTextualNotationBuilder.BuildTriggerAction(elementAsAcceptActionUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -79,10 +79,10 @@ public static void BuildGuardExpressionMember(SysML2.NET.Core.POCO.Systems.State if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IExpression elementAsExpression) { ExpressionTextualNotationBuilder.BuildOwnedExpression(elementAsExpression, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } @@ -105,10 +105,10 @@ public static void BuildEffectBehaviorMember(SysML2.NET.Core.POCO.Systems.States if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Actions.IActionUsage elementAsActionUsage) { ActionUsageTextualNotationBuilder.BuildEffectBehaviorUsage(elementAsActionUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TransitionUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TransitionUsageTextualNotationBuilder.cs index c1fc35b6..4f601269 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TransitionUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TransitionUsageTextualNotationBuilder.cs @@ -51,10 +51,10 @@ public static void BuildGuardedTargetSuccession(SysML2.NET.Core.POCO.Systems.Sta if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Systems.States.ITransitionFeatureMembership elementAsTransitionFeatureMembership) { TransitionFeatureMembershipTextualNotationBuilder.BuildGuardExpressionMember(elementAsTransitionFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("then "); if (ownedRelationshipCursor.Current != null) @@ -63,10 +63,10 @@ public static void BuildGuardedTargetSuccession(SysML2.NET.Core.POCO.Systems.Sta if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildTransitionSuccessionMember(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -88,10 +88,10 @@ public static void BuildDefaultTargetSuccession(SysML2.NET.Core.POCO.Systems.Sta if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildTransitionSuccessionMember(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -106,7 +106,7 @@ public static void BuildGuardedSuccession(SysML2.NET.Core.POCO.Systems.States.IT { var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { stringBuilder.Append("succession "); UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); @@ -121,10 +121,10 @@ public static void BuildGuardedSuccession(SysML2.NET.Core.POCO.Systems.States.IT if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) { MembershipTextualNotationBuilder.BuildFeatureChainMember(elementAsMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -132,10 +132,10 @@ public static void BuildGuardedSuccession(SysML2.NET.Core.POCO.Systems.States.IT if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Systems.States.ITransitionFeatureMembership elementAsTransitionFeatureMembership) { TransitionFeatureMembershipTextualNotationBuilder.BuildGuardExpressionMember(elementAsTransitionFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - stringBuilder.Append("then "); if (ownedRelationshipCursor.Current != null) @@ -144,10 +144,10 @@ public static void BuildGuardedSuccession(SysML2.NET.Core.POCO.Systems.States.IT if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildTransitionSuccessionMember(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - UsageTextualNotationBuilder.BuildUsageBody(poco, writerContext, stringBuilder); } @@ -169,10 +169,10 @@ public static void BuildTargetTransitionUsage(SysML2.NET.Core.POCO.Systems.State if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildEmptyParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - BuildTargetTransitionUsageHandCoded(poco, writerContext, stringBuilder); stringBuilder.Append("then "); @@ -182,10 +182,10 @@ public static void BuildTargetTransitionUsage(SysML2.NET.Core.POCO.Systems.State if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildTransitionSuccessionMember(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - TypeTextualNotationBuilder.BuildActionBody(poco, writerContext, stringBuilder); } @@ -202,7 +202,7 @@ public static void BuildTransitionUsage(SysML2.NET.Core.POCO.Systems.States.ITra var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); stringBuilder.Append("transition "); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); stringBuilder.Append("first "); @@ -216,10 +216,10 @@ public static void BuildTransitionUsage(SysML2.NET.Core.POCO.Systems.States.ITra if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) { MembershipTextualNotationBuilder.BuildFeatureChainMember(elementAsMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { @@ -227,12 +227,12 @@ public static void BuildTransitionUsage(SysML2.NET.Core.POCO.Systems.States.ITra if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildEmptyParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - - if (ownedRelationshipCursor.Current != null) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership && ownedRelationshipCursor.GetNext(1) is SysML2.NET.Core.POCO.Systems.States.ITransitionFeatureMembership) { if (ownedRelationshipCursor.Current != null) @@ -277,7 +277,7 @@ public static void BuildTransitionUsage(SysML2.NET.Core.POCO.Systems.States.ITra } - if (ownedRelationshipCursor.Current != null) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Systems.States.ITransitionFeatureMembership && ownedRelationshipCursor.GetNext(1) is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) { if (ownedRelationshipCursor.Current != null) @@ -301,10 +301,10 @@ public static void BuildTransitionUsage(SysML2.NET.Core.POCO.Systems.States.ITra if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildTransitionSuccessionMember(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - TypeTextualNotationBuilder.BuildActionBody(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TypeTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TypeTextualNotationBuilder.cs index be014762..3ebd6a79 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TypeTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/TypeTextualNotationBuilder.cs @@ -538,10 +538,10 @@ public static void BuildSpecializationPart(SysML2.NET.Core.POCO.Core.Types.IType if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.ISpecialization elementAsSpecialization) { SpecializationTextualNotationBuilder.BuildOwnedSpecialization(elementAsSpecialization, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current != null && ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.ISpecialization) { @@ -579,10 +579,10 @@ public static void BuildConjugationPart(SysML2.NET.Core.POCO.Core.Types.IType po if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IConjugation elementAsConjugation) { ConjugationTextualNotationBuilder.BuildOwnedConjugation(elementAsConjugation, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -632,10 +632,10 @@ public static void BuildDisjoiningPart(SysML2.NET.Core.POCO.Core.Types.IType poc if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IDisjoining elementAsDisjoining) { DisjoiningTextualNotationBuilder.BuildOwnedDisjoining(elementAsDisjoining, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current != null && ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IDisjoining) { @@ -673,10 +673,10 @@ public static void BuildUnioningPart(SysML2.NET.Core.POCO.Core.Types.IType poco, if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IUnioning elementAsUnioning) { UnioningTextualNotationBuilder.BuildUnioning(elementAsUnioning, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IUnioning unioningGuard && unioningGuard.OwnedRelatedElement.OfType().Any()) { @@ -714,10 +714,10 @@ public static void BuildIntersectingPart(SysML2.NET.Core.POCO.Core.Types.IType p if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IIntersecting elementAsIntersecting) { IntersectingTextualNotationBuilder.BuildIntersecting(elementAsIntersecting, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IIntersecting intersectingGuard && intersectingGuard.OwnedRelatedElement.OfType().Any()) { @@ -755,10 +755,10 @@ public static void BuildDifferencingPart(SysML2.NET.Core.POCO.Core.Types.IType p if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IDifferencing elementAsDifferencing) { DifferencingTextualNotationBuilder.BuildDifferencing(elementAsDifferencing, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - while (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IDifferencing differencingGuard && differencingGuard.OwnedRelatedElement.OfType().Any()) { diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UsageTextualNotationBuilder.cs index b4a63358..4ad0db69 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UsageTextualNotationBuilder.cs @@ -166,10 +166,10 @@ public static void BuildUsageExtensionKeyword(SysML2.NET.Core.POCO.Systems.Defin if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership elementAsOwningMembership) { OwningMembershipTextualNotationBuilder.BuildPrefixMetadataMember(elementAsOwningMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } @@ -223,8 +223,9 @@ public static void BuildUsagePrefix(SysML2.NET.Core.POCO.Systems.DefinitionAndUs public static void BuildUsageDeclaration(SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { ElementTextualNotationBuilder.BuildIdentification(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if ((ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { FeatureTextualNotationBuilder.BuildFeatureSpecializationPart(poco, writerContext, stringBuilder); } @@ -240,8 +241,9 @@ public static void BuildUsageDeclaration(SysML2.NET.Core.POCO.Systems.Definition /// The that contains the entire textual notation public static void BuildUsageCompletion(SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UseCaseUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UseCaseUsageTextualNotationBuilder.cs index 2e4eddc3..9280610d 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UseCaseUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UseCaseUsageTextualNotationBuilder.cs @@ -47,8 +47,9 @@ public static void BuildUseCaseUsage(SysML2.NET.Core.POCO.Systems.UseCases.IUseC stringBuilder.Append("use "); stringBuilder.Append("case "); UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/VariantMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/VariantMembershipTextualNotationBuilder.cs index 1fde1fab..74eddeb7 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/VariantMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/VariantMembershipTextualNotationBuilder.cs @@ -71,10 +71,10 @@ public static void BuildEnumerationUsageMember(SysML2.NET.Core.POCO.Systems.Defi if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Enumerations.IEnumerationUsage elementAsEnumerationUsage) { EnumerationUsageTextualNotationBuilder.BuildEnumeratedValue(elementAsEnumerationUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/VerificationCaseUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/VerificationCaseUsageTextualNotationBuilder.cs index 743f8ba2..a86d75d0 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/VerificationCaseUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/VerificationCaseUsageTextualNotationBuilder.cs @@ -46,8 +46,9 @@ public static void BuildVerificationCaseUsage(SysML2.NET.Core.POCO.Systems.Verif OccurrenceUsageTextualNotationBuilder.BuildOccurrenceUsagePrefix(poco, writerContext, stringBuilder); stringBuilder.Append("verification "); UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ViewRenderingMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ViewRenderingMembershipTextualNotationBuilder.cs index 26ceed31..cc7fc463 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ViewRenderingMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ViewRenderingMembershipTextualNotationBuilder.cs @@ -53,10 +53,10 @@ public static void BuildViewRenderingMember(SysML2.NET.Core.POCO.Systems.Views.I if (ownedRelatedElementCursor.Current is SysML2.NET.Core.POCO.Systems.Views.IRenderingUsage elementAsRenderingUsage) { RenderingUsageTextualNotationBuilder.BuildViewRenderingUsage(elementAsRenderingUsage, writerContext, stringBuilder); + ownedRelatedElementCursor.Move(); + } } - ownedRelatedElementCursor.Move(); - } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ViewUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ViewUsageTextualNotationBuilder.cs index 21d34c59..1203ff75 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ViewUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ViewUsageTextualNotationBuilder.cs @@ -104,13 +104,14 @@ public static void BuildViewUsage(SysML2.NET.Core.POCO.Systems.Views.IViewUsage { OccurrenceUsageTextualNotationBuilder.BuildOccurrenceUsagePrefix(poco, writerContext, stringBuilder); stringBuilder.Append("view "); + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || poco.IsOrdered) + if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IFeatureTyping || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ISubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.ICrossSubsetting || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Features.IRedefinition || ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership) || poco.IsOrdered) { UsageTextualNotationBuilder.BuildUsageDeclaration(poco, writerContext, stringBuilder); } - if (poco.OwnedRelationship.Count != 0 || poco.type.Count != 0 || poco.chainingFeature.Count != 0 || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.importedMembership.Count != 0 || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient || poco.unioningType.Count != 0 || poco.intersectingType.Count != 0 || poco.differencingType.Count != 0 || poco.featuringType.Count != 0 || poco.ownedTypeFeaturing.Count != 0) + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.FeatureValues.IFeatureValue || !string.IsNullOrWhiteSpace(poco.DeclaredShortName) || !string.IsNullOrWhiteSpace(poco.DeclaredName) || poco.Direction.HasValue || poco.IsDerived || poco.IsAbstract || poco.IsConstant || poco.IsOrdered || poco.IsEnd || poco.IsComposite || poco.IsPortion || poco.IsVariable || poco.IsSufficient) { FeatureTextualNotationBuilder.BuildValuePart(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/WhileLoopActionUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/WhileLoopActionUsageTextualNotationBuilder.cs index 076c78f6..eead486b 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/WhileLoopActionUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/WhileLoopActionUsageTextualNotationBuilder.cs @@ -55,10 +55,10 @@ public static void BuildWhileLoopNode(SysML2.NET.Core.POCO.Systems.Actions.IWhil if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildEmptyParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } else if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership) { @@ -70,10 +70,10 @@ public static void BuildWhileLoopNode(SysML2.NET.Core.POCO.Systems.Actions.IWhil if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildExpressionParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - } stringBuilder.Append(' '); @@ -84,10 +84,10 @@ public static void BuildWhileLoopNode(SysML2.NET.Core.POCO.Systems.Actions.IWhil if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) { ParameterMembershipTextualNotationBuilder.BuildActionBodyParameterMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + } } - ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) { diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/FeatureTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/FeatureTextualNotationBuilder.cs index 859728f1..7eace692 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/FeatureTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/FeatureTextualNotationBuilder.cs @@ -197,20 +197,20 @@ private static void BuildFeatureIdentificationHandCoded(IFeature poco, TextualNo if (!string.IsNullOrWhiteSpace(poco.DeclaredShortName)) { stringBuilder.Append('<'); - stringBuilder.Append(poco.DeclaredShortName); + SharedTextualNotationBuilder.AppendName(stringBuilder, poco.DeclaredShortName); stringBuilder.Append('>'); if (!string.IsNullOrWhiteSpace(poco.DeclaredName)) { stringBuilder.Append(' '); - stringBuilder.Append(poco.DeclaredName); + SharedTextualNotationBuilder.AppendName(stringBuilder, poco.DeclaredName); } stringBuilder.Append(' '); } else if (!string.IsNullOrWhiteSpace(poco.DeclaredName)) { - stringBuilder.Append(poco.DeclaredName); + SharedTextualNotationBuilder.AppendName(stringBuilder, poco.DeclaredName); stringBuilder.Append(' '); } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/NameResolutionCache.cs b/SysML2.NET.Serializer.TextualNotation/Writers/NameResolutionCache.cs new file mode 100644 index 00000000..5a1b4548 --- /dev/null +++ b/SysML2.NET.Serializer.TextualNotation/Writers/NameResolutionCache.cs @@ -0,0 +1,615 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// 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; + using System.Collections.Generic; + using System.Linq; + + using SysML2.NET.Core.POCO.Core.Features; + using SysML2.NET.Core.POCO.Core.Types; + using SysML2.NET.Core.POCO.Kernel.Behaviors; + using SysML2.NET.Core.POCO.Kernel.Expressions; + using SysML2.NET.Core.POCO.Root.Elements; + using SysML2.NET.Core.POCO.Root.Namespaces; + using SysML2.NET.Extensions; + + /// + /// Performant single-place cache for textual-notation qualified-name resolution. + /// Owns three caches: + /// + /// Eager structural: per-namespace simple-name → member set, populated + /// by a single walk of the model on construction. Keys are the namespaces reachable + /// transitively from the root namespace via containment and imports. + /// Lazy source-scope chain: per-source-POCO upward walk result. The + /// chain is materialised on first encounter of the source and cached for subsequent + /// references rooted at the same source. + /// Lazy resolved emission: per-(target, sourceLocalScope) + /// pair, the final string to emit (bare simple name, escaped unrestricted name, or full + /// qualified name). Reused on every subsequent reference that hits the same pair. + /// + /// Resolution policy mirrors KerML §8.2.3.5 with two short-circuits: + /// + /// targets (import declarations) keep their full + /// qualified path — the path identifies WHAT is being imported. + /// Chain accessors (the .X of a feature-chain expression / multi-segment + /// feature chain) resolve X against the target's own owning namespace so the bare + /// simple name is emitted, since the parser establishes the resolution scope from the + /// preceding chain segment's type. + /// + /// + public sealed class NameResolutionCache + { + /// + /// Shared empty index returned for unknown / null namespaces. + /// + private static readonly IReadOnlyDictionary> EmptyIndex + = new Dictionary>(StringComparer.Ordinal); + + /// + /// Eager structural cache: namespace → (simple-name → member set). Populated once on + /// construction by . + /// + private readonly Dictionary>> simpleNameIndices; + + /// + /// Lazy upward-walk cache: source-POCO id → containment-chain of s + /// terminated at the root namespace (or wherever the upward walk first hits an empty + /// owningNamespace). Populated by . + /// + private readonly Dictionary> sourceScopeChains + = new (); + + /// + /// Lazy resolved-emission cache: (target.Id, sourceLocalScope.Id) → emitted string. + /// + private readonly Dictionary<(Guid TargetId, Guid SourceScopeId), string> resolvedReferences + = new (); + + /// + /// Initializes a new rooted at + /// and eagerly populates the per-namespace simple-name + /// index for every namespace reachable from the root. + /// + /// The root being serialized. + public NameResolutionCache(INamespace rootNamespace) + { + this.RootNamespace = rootNamespace ?? throw new ArgumentNullException(nameof(rootNamespace)); + this.simpleNameIndices = BuildSimpleNameIndices(rootNamespace); + } + + /// + /// Gets the root the cache was rooted at — used as the fallback + /// local scope when a source POCO has no resolvable enclosing namespace. + /// + public INamespace RootNamespace { get; } + + /// + /// Resolves the textual notation for a reference to at the + /// site of . The result is cached by + /// (target.Id, sourceLocalScope.Id) — repeat calls with the same pair are O(1) + /// dictionary lookups. + /// + /// The referenced ; may be . + /// The POCO at whose syntactic position the reference appears. + /// The string to emit; empty when is . + public string Resolve(IElement target, IElement sourcePoco) + { + switch (target) + { + case null: + return string.Empty; + + // Short-circuit 1 — IMembership targets: import declarations keep their full path. + case IMembership membership: + return membership.MemberElement?.qualifiedName ?? string.Empty; + } + + // Short-circuit 2 — no usable simple name on the target: emit the qualified name. + var escapedName = target.EscapedName(); + + if (string.IsNullOrWhiteSpace(escapedName)) + { + return target.qualifiedName ?? string.Empty; + } + + // Short-circuit 3 — chain accessor: the parser establishes the resolution scope + // from the preceding chain segment's type at parse time, so the simple name is + // sufficient. We do NOT cache this because the chain accessor's resolution is a + // function of (target, sourcePoco) — and sourcePoco changes per reference site. + // The work is cheap (one type test + EscapedName already computed above). + if (IsChainAccessor(sourcePoco)) + { + return ResolveChainAccessor(target, escapedName); + } + + // Memoised path — look up by (target.Id, sourceLocalScope.Id). + var sourceLocalScope = this.GetSourceLocalScope(sourcePoco); + var cacheKey = (target.Id, sourceLocalScope?.Id ?? Guid.Empty); + + if (this.resolvedReferences.TryGetValue(cacheKey, out var cached)) + { + return cached; + } + + var resolved = this.ResolveFresh(target, sourcePoco, sourceLocalScope, escapedName); + this.resolvedReferences[cacheKey] = resolved; + return resolved; + } + + /// + /// First-time resolution: walks the cached source-scope chain and probes each scope's + /// simple-name index. Falls back to . + /// + /// The referenced element. + /// The reference site's source POCO. + /// The previously-computed local scope (may be ). + /// The target's escaped raw name. + /// The resolved emission string. + private string ResolveFresh(IElement target, IElement sourcePoco, INamespace sourceLocalScope, string escapedName) + { + var rawName = target.name; + var rawShortName = target.shortName; + + var escapedShortName = string.IsNullOrWhiteSpace(rawShortName) + ? null + : (rawShortName.QueryIsValidBasicName() ? rawShortName : rawShortName.ToUnrestrictedName()); + + // Walk the cached source-scope chain. First hit wins. + foreach (var scope in this.GetSourceScopeChain(sourcePoco, sourceLocalScope)) + { + if (this.TryResolveSimpleNameInScope(scope, target, rawName, escapedName, rawShortName, escapedShortName, out var matched)) + { + return matched; + } + } + + // Fall back to the fully-qualified name. + return target.qualifiedName ?? string.Empty; + } + + /// + /// Returns the resolved simple name for a chain accessor: tries the target's own + /// name first, then its shortName. Both go through the same KEBNF + /// basic-name / unrestricted-name escape as a non-chain reference. + /// + /// The chain-accessor target element. + /// The pre-computed escaped name form (long-form preference). + /// The escaped simple name, or target.qualifiedName as a last resort. + private static string ResolveChainAccessor(IElement target, string escapedName) + { + if (!string.IsNullOrWhiteSpace(target.name)) + { + return escapedName; + } + + var rawShortName = target.shortName; + + if (!string.IsNullOrWhiteSpace(rawShortName)) + { + return rawShortName.QueryIsValidBasicName() ? rawShortName : rawShortName.ToUnrestrictedName(); + } + + return target.qualifiedName ?? string.Empty; + } + + /// + /// Returns the per-scope simple-name index that was built eagerly on construction. + /// Returns for namespaces the eager pass did not reach. + /// + /// The whose index is requested. + /// The simple-name → member-set lookup. + private IReadOnlyDictionary> GetSimpleNameIndex(INamespace scope) + { + return scope == null ? EmptyIndex : this.simpleNameIndices.GetValueOrDefault(scope, EmptyIndex); + } + + /// + /// Returns the cached upward-walk chain for , building it + /// on first encounter. The chain starts at (the + /// reference's local scope) and walks owningNamespace up to the root. + /// + /// The source POCO bearing the reference; may be . + /// The pre-computed local scope (may be ). + /// The cached chain. + private IReadOnlyList GetSourceScopeChain(IElement sourcePoco, INamespace sourceLocalScope) + { + if (sourcePoco == null) + { + return BuildChain(sourceLocalScope ?? this.RootNamespace); + } + + if (this.sourceScopeChains.TryGetValue(sourcePoco.Id, out var cached)) + { + return cached; + } + + var chain = BuildChain(sourceLocalScope ?? this.RootNamespace); + this.sourceScopeChains[sourcePoco.Id] = chain; + + return chain; + } + + /// + /// Walks up via owningNamespace and materialises the + /// chain. Stops at the first NotSupportedException or null. + /// + /// The starting namespace. + /// The chain. + private static IReadOnlyList BuildChain(INamespace start) + { + if (start == null) + { + return []; + } + + var chain = new List(); + var current = start; + + while (current != null) + { + chain.Add(current); + + INamespace next; + + try + { + next = current.owningNamespace; + } + catch (NotSupportedException) + { + break; + } + + current = next; + } + + return chain; + } + + /// + /// Resolves the local scope of : the first + /// reached by climbing + /// , then + /// , then . Falls + /// back to when nothing is reachable. + /// + /// The source POCO; may be . + /// The local scope or . + private INamespace GetSourceLocalScope(IElement sourcePoco) + { + if (sourcePoco == null) + { + return this.RootNamespace; + } + + var visited = new HashSet(); + var current = sourcePoco; + + while (current != null && visited.Add(current)) + { + switch (current) + { + case INamespace asNamespace: + return asNamespace; + case IRelationship { OwningRelatedElement: not null } relationship: + current = relationship.OwningRelatedElement; + continue; + } + + INamespace owningNs = null; + + try + { + owningNs = current.owningNamespace; + } + catch (NotSupportedException) + { + // owningNamespace not implemented — fall through to owner walk. + } + + if (owningNs != null) + { + return owningNs; + } + + IElement nextOwner; + + try + { + nextOwner = current.owner; + } + catch (NotSupportedException) + { + nextOwner = null; + } + + current = nextOwner; + } + + return this.RootNamespace; + } + + /// + /// Tests the simple-name index of for a hit on + /// . Tries the raw name key first, then the raw + /// shortName key. On a hit, receives the + /// corresponding escaped form. + /// + /// The scope whose index is inspected. + /// The element to look up. + /// The target's raw name; may be / whitespace. + /// The escaped form emitted on a long-form hit. + /// The target's raw shortName; may be / whitespace. + /// The escaped form emitted on a short-form hit. + /// On , the simple name to emit. + /// when a hit was found. + private bool TryResolveSimpleNameInScope(INamespace scope, IElement target, string rawName, string escapedName, string rawShortName, string escapedShortName, out string matchedSimpleName) + { + var index = this.GetSimpleNameIndex(scope); + + if (!string.IsNullOrWhiteSpace(rawName) + && index.TryGetValue(rawName, out var elements) + && elements.Contains(target)) + { + matchedSimpleName = escapedName; + return true; + } + + if (!string.IsNullOrWhiteSpace(rawShortName) + && index.TryGetValue(rawShortName, out var shortElements) + && shortElements.Contains(target)) + { + matchedSimpleName = escapedShortName; + return true; + } + + matchedSimpleName = null; + return false; + } + + /// + /// Determines whether is the right-hand side of a chain + /// accessor — see grammar rules FeatureChainExpression (KerML §8.2.4.X) and + /// FeatureChain (KerML §8.2.4.3.5). Two patterns match: + /// + /// An sitting as the chain-accessor RHS + /// of a . + /// An at any index after the FIRST + /// in its container's OwnedRelationship list. + /// + /// + /// The source POCO at the reference site. + /// when the source is a chain accessor. + private static bool IsChainAccessor(IElement sourcePoco) + { + if (sourcePoco is IMembership { OwningRelatedElement: IFeatureChainExpression } and not IParameterMembership) + { + return true; + } + + if (sourcePoco is not IFeatureChaining { OwningRelatedElement: IFeature chainOwner } chaining) + { + return false; + } + + var siblings = chainOwner.OwnedRelationship.OfType().ToList(); + var index = siblings.IndexOf(chaining); + return index > 0; + } + + /// + /// Eagerly walks the model rooted at and builds the + /// simple-name index for every reachable . Reachability follows + /// . for + /// nested namespaces, plus direct ownedImport targets (so imported namespaces are + /// also indexed once). + /// + /// The root namespace. + /// The full structural cache. + private static Dictionary>> BuildSimpleNameIndices(INamespace rootNamespace) + { + var result = new Dictionary>>(); + var pending = new Queue(); + var visited = new HashSet(); + + pending.Enqueue(rootNamespace); + + while (pending.Count != 0) + { + var scope = pending.Dequeue(); + + if (scope == null || !visited.Add(scope)) + { + continue; + } + + var index = new Dictionary>(StringComparer.Ordinal); + + BuildOwnedAndImportedEntries(scope, index, pending); + + if (scope is IType type) + { + BuildInheritedEntries(type, index, pending); + } + + result[scope] = index; + } + + return result; + } + + /// + /// Populates with entries for 's + /// owned memberships and direct imports. Imported namespaces are enqueued onto + /// so they too are indexed in the eager pass. + /// + /// The namespace whose entries are populated. + /// The destination index. + /// Queue of namespaces yet to be indexed. + private static void BuildOwnedAndImportedEntries(INamespace scope, Dictionary> index, Queue pending) + { + try + { + foreach (var ownedMember in scope.ownedMembership) + { + AddMembershipEntry(index, ownedMember, pending); + } + } + catch (NotSupportedException) + { + // ownedMembership may not be implemented; skip. + } + + try + { + foreach (var ownedImport in scope.ownedImport) + { + switch (ownedImport) + { + case IMembershipImport { ImportedMembership: { } importedMembership }: + AddMembershipEntry(index, importedMembership, pending); + break; + case INamespaceImport { ImportedNamespace: not null } namespaceImport: + { + pending.Enqueue(namespaceImport.ImportedNamespace); + + // Isolate the inner ownedMembership walk in its own try/catch so a + // NotSupportedException from one imported namespace does not abort + // the outer ownedImport loop and lose every remaining import. + try + { + foreach (var importedMember in namespaceImport.ImportedNamespace.ownedMembership) + { + AddMembershipEntry(index, importedMember, pending); + } + } + catch (NotSupportedException) + { + // ownedMembership not implemented for this imported namespace; skip it. + } + + break; + } + } + } + } + catch (NotSupportedException) + { + // ownedImport may not be implemented; skip. + } + } + + /// + /// Indexes the entries inherited from the transitive supertypes of + /// . Bypasses the RemoveRedefinedFeatures filter so + /// references such as :>> elements remain reachable. + /// + /// The type whose inherited memberships are indexed. + /// The destination index. + /// Queue of namespaces yet to be indexed (so supertypes that are + /// also namespaces get their own index built). + private static void BuildInheritedEntries(IType type, Dictionary> index, Queue pending) + { + List supertypes; + + try + { + supertypes = type.AllSupertypes(); + } + catch (NotSupportedException) + { + return; + } + + foreach (var supertype in supertypes.Where(supertype => supertype != null && !ReferenceEquals(supertype, type))) + { + if (supertype is INamespace supertypeAsNamespace) + { + pending.Enqueue(supertypeAsNamespace); + } + + try + { + foreach (var ownedMember in supertype.ownedMembership) + { + AddMembershipEntry(index, ownedMember, pending); + } + } + catch (NotSupportedException) + { + // ownedMembership not implemented for this supertype; skip. + } + } + } + + /// + /// Adds the of + /// to under both its + /// and , and enqueues the target onto + /// if it is itself an (so nested + /// namespaces are indexed too). + /// + /// The destination index. + /// The membership whose target is indexed. + /// Queue of namespaces yet to be indexed. + private static void AddMembershipEntry(Dictionary> index, IMembership membership, Queue pending) + { + var target = membership?.MemberElement; + + if (target == null) + { + return; + } + + AddIndexEntry(index, membership.MemberShortName, target); + AddIndexEntry(index, membership.MemberName, target); + + if (target is INamespace targetAsNamespace) + { + pending.Enqueue(targetAsNamespace); + } + } + + /// + /// Adds to under + /// when the name is non-blank. + /// + /// The destination index. + /// The simple name to use as the index key. + /// The element to record under . + private static void AddIndexEntry(Dictionary> index, string simpleName, IElement element) + { + if (string.IsNullOrWhiteSpace(simpleName) || element == null) + { + return; + } + + if (!index.TryGetValue(simpleName, out var bucket)) + { + bucket = []; + index[simpleName] = bucket; + } + + bucket.Add(element); + } + } +} diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/SharedTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/SharedTextualNotationBuilder.cs index b8aae3c2..0b061e82 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/SharedTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/SharedTextualNotationBuilder.cs @@ -21,19 +21,21 @@ namespace SysML2.NET.Serializer.TextualNotation.Writers { using System; - using System.Collections.Generic; using System.Linq; using System.Text; using SysML2.NET.Core.POCO.Core.Features; using SysML2.NET.Core.POCO.Core.Types; + using SysML2.NET.Core.POCO.Kernel.Behaviors; using SysML2.NET.Core.POCO.Kernel.Expressions; + using SysML2.NET.Core.POCO.Kernel.FeatureValues; using SysML2.NET.Core.POCO.Kernel.Functions; using SysML2.NET.Core.POCO.Kernel.Interactions; using SysML2.NET.Core.POCO.Root.Elements; using SysML2.NET.Core.POCO.Root.Namespaces; using SysML2.NET.Core.POCO.Systems.DefinitionAndUsage; using SysML2.NET.Core.POCO.Systems.Metadata; + using SysML2.NET.Extensions; /// /// Hand-coded part of the . @@ -544,6 +546,28 @@ internal static void BuildFeatureSpecializationPartHandCoded(IFeature poco, Text } } + /// + /// Appends a name token in its textual-notation form: emit the raw identifier when it + /// satisfies the KEBNF basic-name production (and is not a reserved keyword), otherwise + /// emit the unrestricted-name form (single-quoted, with internal special characters + /// escaped per Section 8.2.2.3 of the KerML specification). + /// This helper is intended for code-generated assignments of the form + /// property = NAME (e.g. declaredName, declaredShortName), where + /// the raw string is stored on the POCO but the emitted token must respect the + /// lexical-rule constraints of the grammar. + /// + /// The to append to + /// The raw name string as stored on the POCO; or whitespace is a no-op + internal static void AppendName(StringBuilder stringBuilder, string name) + { + if (string.IsNullOrWhiteSpace(name)) + { + return; + } + + stringBuilder.Append(name.QueryIsValidBasicName() ? name : name.ToUnrestrictedName()); + } + /// /// Appends a body text formatted as a REGULAR_COMMENT (/* ... */). /// The grammar defines REGULAR_COMMENT = '/*' COMMENT_TEXT '*/'. @@ -555,6 +579,8 @@ internal static void BuildFeatureSpecializationPartHandCoded(IFeature poco, Text /// The body text to format as a REGULAR_COMMENT internal static void AppendRegularComment(StringBuilder stringBuilder, string body) { + stringBuilder.AppendLine(); + if (string.IsNullOrWhiteSpace(body)) { stringBuilder.AppendLine("/* */"); @@ -588,23 +614,21 @@ internal static void AppendRegularComment(StringBuilder stringBuilder, string bo /// Appends the shortest resolvable name of the /// for the textual notation, per KerML specification section /// 8.2.3.5. - /// The local scope of the reference is derived as - /// sourcePoco?.owningNamespace ?? writerContext.ContextNamespace. The resolver - /// walks up from that local scope through each containing namespace, asking - /// the per-scope simple-name index cached on whether - /// the target's resolves locally. The first hit - /// wins. If no scope along the chain resolves the simple name to the target, the full - /// is emitted as a fallback. - /// Membership references in import declarations bypass shortening — the path - /// identifies WHAT is imported and must remain fully qualified. + /// This method is a thin facade over + /// on the writer context's + /// . The cache owns all + /// resolution state: the eager per-namespace simple-name indices, the lazy + /// source-POCO scope chains, and the lazy memoised resolved-emission strings. Repeated + /// references to the same (target, source-scope) pair are returned from the + /// memo without re-walking any chain. /// /// The to append to /// The referenced whose name is appended - /// The providing the cache + root + /// The providing the cache /// /// The at whose syntactic position the reference appears (typically the - /// relationship POCO whose property is being unparsed). Its owningNamespace is the - /// local scope of the reference. Pass the enclosing-builder's poco at every call site. + /// relationship POCO whose property is being unparsed). Its local scope drives the + /// memoisation key. Pass the enclosing-builder's poco at every call site. /// internal static void AppendQualifiedName(StringBuilder stringBuilder, IElement target, TextualNotationWriterContext writerContext, IElement sourcePoco) { @@ -613,126 +637,7 @@ internal static void AppendQualifiedName(StringBuilder stringBuilder, IElement t return; } - if (target is IMembership membership) - { - // Membership references (used in import declarations) must retain - // their full qualified name — the path identifies WHAT is being imported. - stringBuilder.Append(membership.MemberElement?.qualifiedName); - return; - } - - var simpleName = target.EscapedName(); - - if (string.IsNullOrWhiteSpace(simpleName)) - { - stringBuilder.Append(target.qualifiedName ?? string.Empty); - return; - } - - var scope = QueryLocalScope(sourcePoco) ?? writerContext?.ContextNamespace; - - while (scope != null) - { - var index = writerContext.GetOrBuildSimpleNameIndex(scope); - - if (index.TryGetValue(simpleName, out var elements) && elements.Contains(target)) - { - stringBuilder.Append(simpleName); - return; - } - - INamespace nextScope; - - try - { - nextScope = scope.owningNamespace; - } - catch (NotSupportedException) - { - // owningNamespace not implemented for this scope — stop the upward walk - // and fall through to the qualifiedName fallback below. - break; - } - - scope = nextScope; - } - - stringBuilder.Append(target.qualifiedName ?? string.Empty); - } - - /// - /// Returns the local where a reference rooted at - /// syntactically appears, by climbing the source's - /// containment chain until a Namespace is reached. - /// The chain is followed in this priority order at each hop: - /// - /// The current element itself, if it is already an . - /// The when the - /// current element is an . Required for relationship POCOs - /// such as / / - /// whose is null because they are owned via - /// ownedRelationship, not via a membership. - /// when non-null. - /// as a final fallback. - /// - /// A visited set guards against accidental cycles in malformed models. - /// - /// The source bearing the reference, or . - /// The local , or when none can be derived. - private static INamespace QueryLocalScope(IElement sourcePoco) - { - if (sourcePoco == null) - { - return null; - } - - var visited = new HashSet(); - var current = sourcePoco; - - while (current != null && visited.Add(current)) - { - if (current is INamespace asNamespace) - { - return asNamespace; - } - - if (current is IRelationship relationship && relationship.OwningRelatedElement != null) - { - current = relationship.OwningRelatedElement; - continue; - } - - INamespace owningNs = null; - - try - { - owningNs = current.owningNamespace; - } - catch (NotSupportedException) - { - // owningNamespace not implemented — fall through to owner walk. - } - - if (owningNs != null) - { - return owningNs; - } - - IElement nextOwner = null; - - try - { - nextOwner = current.owner; - } - catch (NotSupportedException) - { - nextOwner = null; - } - - current = nextOwner; - } - - return null; + stringBuilder.Append(writerContext.NameResolutionCache.Resolve(target, sourcePoco)); } } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs b/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs index 011b119a..1dc046fa 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs @@ -21,44 +21,34 @@ namespace SysML2.NET.Serializer.TextualNotation.Writers { using System; - using System.Collections.Generic; - using SysML2.NET.Core.POCO.Core.Features; - using SysML2.NET.Core.POCO.Core.Types; - using SysML2.NET.Core.POCO.Root.Elements; using SysML2.NET.Core.POCO.Root.Namespaces; /// - /// Provides the serialization context for the textual notation builders. - /// Carries the for cursor-based element traversal, - /// the context for qualified name resolution (KerML 8.2.3.5), - /// a per-namespace simple-name index cache used by - /// , and future writer - /// settings (indentation, short/long notation preferences, etc.). + /// Provides the serialization context for the textual notation builders. Carries the + /// for cursor-based element traversal, the root + /// being serialized, and the + /// that owns all name-resolution state used by + /// . /// public class TextualNotationWriterContext : IDisposable { - /// - /// Lazily-populated per-namespace simple-name index. For each - /// scope previously queried, maps each visible simple name (member shortName / name) - /// to the set of s reachable by that simple name from that scope. - /// Built on demand in . - /// - private readonly Dictionary>> simpleNameIndex - = new Dictionary>>(); - /// /// Initializes a new instance of the class. + /// Eagerly builds the per-namespace simple-name index for every namespace reachable + /// from via owned-relationship containment and + /// direct imports. /// /// /// The root being serialized. Used as the upper-bound of the - /// upward-walk in , and - /// as the fallback local scope when a source POCO has no owningNamespace. + /// upward-walk in qualified name resolution per KerML §8.2.3.5 and as the fallback + /// local scope when a source POCO has no owningNamespace. /// public TextualNotationWriterContext(INamespace contextNamespace) { this.CursorCache = new CursorCache(); this.ContextNamespace = contextNamespace ?? throw new ArgumentNullException(nameof(contextNamespace)); + this.NameResolutionCache = new NameResolutionCache(contextNamespace); } /// @@ -67,53 +57,17 @@ public TextualNotationWriterContext(INamespace contextNamespace) public ICursorCache CursorCache { get; } /// - /// Gets the root being serialized, providing the - /// upper bound for the upward-walk performed in qualified name resolution - /// per KerML specification section 8.2.3.5. + /// Gets the root being serialized, providing the upper bound + /// for the upward-walk performed in qualified name resolution per KerML §8.2.3.5. /// public INamespace ContextNamespace { get; } /// - /// Returns the cached simple-name index for the given , building - /// it on first access. The index maps every simple name that resolves locally in - /// to the set of s reachable by that - /// simple name. The set covers: - /// - /// Owned memberships (scope.ownedMembership). - /// Direct imports (scope.ownedImport) — both IMembershipImport - /// and INamespaceImport. - /// Inherited feature memberships when is an - /// IType, by walking type.featureMembership (which already unions owned - /// and inherited per TypeExtensions.ComputeFeatureMembership). - /// + /// Gets the that owns all name-resolution state for + /// this serialization context: eager per-namespace simple-name indices, lazy + /// source-POCO scope chains, and lazy memoised resolved-emission strings. /// - /// The whose simple-name index is requested. - /// The simple-name → set lookup for . - internal IReadOnlyDictionary> GetOrBuildSimpleNameIndex(INamespace scope) - { - if (scope == null) - { - return EmptyIndex; - } - - if (this.simpleNameIndex.TryGetValue(scope, out var cached)) - { - return cached; - } - - var index = new Dictionary>(StringComparer.Ordinal); - - BuildOwnedAndImportedEntries(scope, index); - - if (scope is IType type) - { - BuildInheritedEntries(type, index); - } - - this.simpleNameIndex[scope] = index; - - return index; - } + public NameResolutionCache NameResolutionCache { get; } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting @@ -123,159 +77,5 @@ public void Dispose() { this.CursorCache.Dispose(); } - - /// - /// Single shared empty result returned by when - /// the requested scope is . - /// - private static readonly IReadOnlyDictionary> EmptyIndex - = new Dictionary>(StringComparer.Ordinal); - - /// - /// Adds entries for 's ownedMembership and direct - /// ownedImports into . Handles both - /// and ; for the latter, - /// the imported namespace's ownedMembership entries are projected into the index - /// keyed by the member-relative names exposed by the import. - /// - /// The namespace whose owned + imported members are indexed. - /// The destination index to populate. - private static void BuildOwnedAndImportedEntries(INamespace scope, Dictionary> index) - { - try - { - foreach (var ownedMember in scope.ownedMembership) - { - AddMembershipEntry(index, ownedMember); - } - } - catch (NotSupportedException) - { - // ownedMembership may not be implemented for this namespace; skip. - } - - try - { - foreach (var ownedImport in scope.ownedImport) - { - if (ownedImport is IMembershipImport membershipImport - && membershipImport.ImportedMembership is IMembership importedMembership) - { - AddMembershipEntry(index, importedMembership); - } - else if (ownedImport is INamespaceImport namespaceImport - && namespaceImport.ImportedNamespace != null) - { - foreach (var importedMember in namespaceImport.ImportedNamespace.ownedMembership) - { - AddMembershipEntry(index, importedMember); - } - } - } - } - catch (NotSupportedException) - { - // ownedImport / ImportedMemberships may not be implemented; skip. - } - } - - /// - /// Adds entries for inherited memberships of into - /// , keyed by each inherited 's - /// MemberShortName / MemberName and mapped to its MemberElement. - /// Walks the transitive supertype graph (via AllSupertypes) and indexes - /// each supertype's own ownedMembership entries directly. This is - /// intentionally different from - /// TypeExtensions.ComputeInheritedMembership: that operation runs the - /// RemoveRedefinedFeatures filter (which strips inherited Features that have - /// been redefined by the local Type), so references such as :>> elements - /// — whose very purpose is to redefine elements — would be excluded by name - /// resolution that relied on it. For name-resolution purposes the redefined target - /// MUST stay reachable, so we bypass that filter and index the raw owned memberships - /// of every transitive supertype. - /// - /// The type whose transitive-supertype memberships are indexed. - /// The destination index to populate. - private static void BuildInheritedEntries(IType type, Dictionary> index) - { - List supertypes; - - try - { - supertypes = type.AllSupertypes(); - } - catch (NotSupportedException) - { - return; - } - - foreach (var supertype in supertypes) - { - if (supertype == null || ReferenceEquals(supertype, type)) - { - continue; - } - - try - { - foreach (var ownedMember in supertype.ownedMembership) - { - AddMembershipEntry(index, ownedMember); - } - } - catch (NotSupportedException) - { - // ownedMembership not implemented for this supertype; skip. - } - } - } - - /// - /// Adds the of - /// to the index under both its and - /// , when present. - /// - /// The destination index to populate. - /// The membership whose target is indexed. - private static void AddMembershipEntry(Dictionary> index, IMembership membership) - { - if (membership == null) - { - return; - } - - var target = membership.MemberElement; - - if (target == null) - { - return; - } - - AddIndexEntry(index, membership.MemberShortName, target); - AddIndexEntry(index, membership.MemberName, target); - } - - /// - /// Adds to under - /// when the name is non-blank. - /// - /// The destination index to populate. - /// The simple name to use as the index key. - /// The element to record under . - private static void AddIndexEntry(Dictionary> index, string simpleName, IElement element) - { - if (string.IsNullOrWhiteSpace(simpleName) || element == null) - { - return; - } - - if (!index.TryGetValue(simpleName, out var bucket)) - { - bucket = new HashSet(); - index[simpleName] = bucket; - } - - bucket.Add(element); - } } } From e4346adda283ddab1a02621fb645895c4b8bfecd Mon Sep 17 00:00:00 2001 From: atheate Date: Thu, 21 May 2026 09:01:20 +0200 Subject: [PATCH 2/5] Fix wrong output on expression --- .../RuleProcessor.ElementProcessing.cs | 17 +- .../RuleProcessor.PatternHandlers.cs | 399 ++++++++++++++++-- .../HandleBarHelpers/RulesHelper.cs | 59 +++ ...CollectExpressionTextualNotationBuilder.cs | 36 +- ...jugatedPortTypingTextualNotationBuilder.cs | 2 +- .../ExpressionTextualNotationBuilder.cs | 29 +- ...reChainExpressionTextualNotationBuilder.cs | 36 +- ...FeatureMembershipTextualNotationBuilder.cs | 4 +- .../FeatureTextualNotationBuilder.cs | 30 +- .../IndexExpressionTextualNotationBuilder.cs | 40 +- .../MembershipTextualNotationBuilder.cs | 8 +- .../MultiplicityTextualNotationBuilder.cs | 4 +- ...peratorExpressionTextualNotationBuilder.cs | 385 ++++++++++------- .../OwningMembershipTextualNotationBuilder.cs | 4 +- .../SelectExpressionTextualNotationBuilder.cs | 36 +- ...jugatedPortTypingTextualNotationBuilder.cs | 17 +- ...FeatureMembershipTextualNotationBuilder.cs | 41 ++ .../Writers/OperatorPrecedence.cs | 279 ++++++++++++ .../TextualNotationValidationExtensions.cs | 28 +- .../Writers/TextualNotationWriterContext.cs | 13 + 20 files changed, 1158 insertions(+), 309 deletions(-) create mode 100644 SysML2.NET.Serializer.TextualNotation/Writers/OperatorPrecedence.cs diff --git a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.ElementProcessing.cs b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.ElementProcessing.cs index d0c8cc5c..aa9458a6 100644 --- a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.ElementProcessing.cs +++ b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.ElementProcessing.cs @@ -348,6 +348,15 @@ internal void ProcessAssignmentElement(EncodedTextWriter writer, IClass umlClass { writer.WriteSafeString($"SharedTextualNotationBuilder.AppendName(stringBuilder, poco.{targetPropertyName});"); } + else if (string.Equals(targetPropertyName, "Operator", StringComparison.Ordinal)) + { + // Operator tokens (binary, unary, conditional) need a trailing + // space to separate them from the next operand. Matches the + // convention used by the operator-switch dispatch path + // (RuleProcessor.PatternHandlers.cs:94-95). + writer.WriteSafeString($"stringBuilder.Append(poco.{targetPropertyName});{Environment.NewLine}"); + writer.WriteSafeString("stringBuilder.Append(' ');"); + } else { writer.WriteSafeString($"stringBuilder.Append(poco.{targetPropertyName});"); @@ -433,7 +442,13 @@ internal void ProcessAssignmentElement(EncodedTextWriter writer, IClass umlClass } else { - writer.WriteSafeString($"Build{assignmentElement.Property.CapitalizeFirstLetter()}(poco, writerContext, stringBuilder);"); + // The grammar's assignment property does not resolve against the target + // metamodel class (e.g. the OMG kebnf carries a one-off `ownedFeatureMember` + // vs. metamodel `ownedMemberFeature` typo for `OwnedExpressionMember`). + // Delegate to the HandCoded sibling per the documented convention rather + // than emitting a name-collision-prone `Build{Property}(poco, …)` call. + var handCodedRuleName = assignmentElement.TextualNotationRule?.RuleName ?? "Unknown"; + this.EmitHandCodedFallback(writer, handCodedRuleName, ruleGenerationContext); } } diff --git a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.PatternHandlers.cs b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.PatternHandlers.cs index 3fb1995c..10d0e11f 100644 --- a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.PatternHandlers.cs +++ b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleProcessor.PatternHandlers.cs @@ -694,6 +694,67 @@ private void ProcessUnitypedAlternativesWithOneElement(EncodedTextWriter writer, } } + // Self-default inheritance-ambiguity guard synthesis. + // + // The criterion: emit guards only when one of the switch's alternatives + // has the same UML class as the rule's `NamedElementToGenerate`. That is + // the "self-default" shape — the rule uses its own target class as one + // alternative and that alternative becomes the default catch-all arm + // for inline/non-named subclass forms. The canonical example is + // FeatureElement: `FeatureElement : Feature = Feature | Step | Expression | …` + // where `Feature` is both an alternative and the rule's target. An + // inline IOperatorExpression (subclass of IExpression with no declared + // name) reaching the switch would match `case IExpression` and be + // mis-rendered; a property-derived guard like `DeclaredName != null` + // makes that arm decline the match and fall through to `BuildFeature`. + // + // When the rule does NOT exhibit this self-default pattern + // (BuildAnnotatingElement, BuildDefinitionElement, BuildNonFeatureElement + // — `NamedElementToGenerate` is `Element`/`AnnotatingElement` but no + // alternative targets that class), the most-derived-first ordering + // alone is sufficient: every legitimate runtime metaclass maps to its + // own arm. No guards are emitted, regardless of any speculative + // metamodel inheritance overlap. + // + // For each non-default alternative under a self-default rule, run the + // depth-aware synthesizer on the called rule's parsed body. Every + // synthesized clause (with property-mismatch and scalar-on-`+=` filters + // already applied) becomes part of the arm's `when` predicate, joined + // by `&&`. Shared clauses across siblings are harmless — they filter + // out subclass forms uniformly while runtime metaclass + most-derived + // ordering still routes named instances to the correct concrete arm. + var generatingClassForSelfDefault = ruleGenerationContext.NamedElementToGenerate as IClass; + var isSelfDefault = generatingClassForSelfDefault != null + && mappedNonTerminalElements.Any(element => element.UmlClass == generatingClassForSelfDefault); + + if (isSelfDefault) + { + var ambiguousElements = mappedNonTerminalElements + .Where(element => !duplicateClasses.ContainsKey(element.UmlClass)) + .Where(element => element.UmlClass != generatingClassForSelfDefault) + .Where(element => !whenGuards.ContainsKey(element.RuleElement)) + .Where(element => !IsTypeDispatcherRule(ruleGenerationContext.AllRules.SingleOrDefault(rule => rule.RuleName == element.RuleElement.Name))) + .ToList(); + + foreach (var ambiguous in ambiguousElements) + { + var referencedRule = ruleGenerationContext.AllRules + .SingleOrDefault(rule => rule.RuleName == ambiguous.RuleElement.Name); + + if (referencedRule == null) + { + continue; + } + + var clauses = CollectGuardClausesForRule(referencedRule, ambiguous.UmlClass, umlClass.Cache, ruleGenerationContext.AllRules, 3); + + if (clauses.Count > 0) + { + whenGuards[ambiguous.RuleElement] = string.Join(" && ", clauses); + } + } + } + var reorderedElements = new List<(NonTerminalElement RuleElement, IClass UmlClass)>(); var processedDuplicateClasses = new HashSet(); @@ -1019,21 +1080,131 @@ private void EmitCompoundPocoTypeBranch(EncodedTextWriter writer, IClass umlClas /// case variable name placeholder) ready for insertion into whenGuards, or /// null when the rule body carries no usable parsed assignments. /// - private static string SynthesiseGuardFromRuleBody(TextualNotationRule rule, IClass targetClass, IXmiElementCache cache, IReadOnlyList allRules) + private static string SynthesiseGuardFromRuleBody(TextualNotationRule rule, IClass targetClass, IXmiElementCache cache, IReadOnlyList allRules, int maxDepth = 0) { if (rule == null || targetClass == null) { return null; } + var clauses = CollectGuardClausesForRule(rule, targetClass, cache, allRules, maxDepth); + + return clauses.Count == 0 ? null : string.Join(" && ", clauses); + } + + /// + /// Determines whether is itself a type-dispatcher — i.e. + /// a rule whose body is exclusively a union of single-NonTerminal alternatives + /// (Subclass1 | Subclass2 | …) that delegate to per-subclass builders. + /// + /// Used by the inheritance-ambiguity pass to suppress guard emission on a switch + /// arm whose called rule already routes subclasses internally. For example, the + /// LiteralExpression rule body is + /// LiteralBoolean | LiteralInteger | LiteralRational | LiteralString | LiteralInfinity + /// — any subclass that reaches a + /// case ILiteralExpression arm is correctly dispatched to its concrete + /// builder by BuildLiteralExpression's inner switch. Contrast with the + /// Expression rule body + /// FeaturePrefix 'expr' FeatureDeclaration ValuePart? FunctionBody: a + /// concrete construction rule that only renders the base form, so a subclass + /// (e.g. ) reaching a case IExpression + /// arm would be mis-rendered as a standalone Expression declaration and DOES + /// need a guard. + /// + /// + /// The rule to test, or null + /// true when is a multi-alternative type-dispatcher + private static bool IsTypeDispatcherRule(TextualNotationRule rule) + { + if (rule == null || rule.Alternatives.Count < 2) + { + return false; + } + + return rule.Alternatives.All(alternative => + alternative.Elements.Count == 1 + && alternative.Elements[0] is NonTerminalElement); + } + + /// + /// Runs the structural-predicate walk for and returns the raw list + /// of synthesised clauses, before they are joined with &&. Centralises the + /// per-walk seeding of (visited-rules) and the cursor-state + /// bookkeeping. + /// + /// The entry to walk. + /// The dispatch-time target (the alternative's UML class). + /// The for resolving NonTerminal RHS targets. + /// All available rules for NonTerminal resolution. + /// Recursion budget: 0 = shallow (current/legacy behavior), N>0 = recurse up to NonTerminal references deep. + /// The per-clause list (unjoined) in source-order. + private static List CollectGuardClausesForRule(TextualNotationRule rule, IClass targetClass, IXmiElementCache cache, IReadOnlyList allRules, int maxDepth) + { var targetProperties = targetClass.QueryAllProperties(); - var clauses = new List(); - var firstCursorEmitted = false; - var cursorMayHaveAdvanced = false; + var perAlternativeClauses = new List>(); - CollectGuardClauses(rule.Alternatives.SelectMany(alternative => alternative.Elements), targetProperties, cache, allRules, clauses, ref firstCursorEmitted, ref cursorMayHaveAdvanced); + foreach (var alternative in rule.Alternatives) + { + var altClauses = new List(); + var firstCursorEmitted = false; + var cursorMayHaveAdvanced = false; + var visitedRules = new HashSet(StringComparer.Ordinal); - return clauses.Count == 0 ? null : string.Join(" && ", clauses); + if (!string.IsNullOrEmpty(rule.RuleName)) + { + visitedRules.Add(rule.RuleName); + } + + CollectGuardClauses(alternative.Elements, targetProperties, cache, allRules, altClauses, ref firstCursorEmitted, ref cursorMayHaveAdvanced, visitedRules, maxDepth); + + perAlternativeClauses.Add(altClauses); + } + + var combined = CombineAlternativesAsOr(perAlternativeClauses); + + return combined == null + ? new List() + : new List { combined }; + } + + /// + /// Combines per-grammar-alternative clause lists into a single OR-disjunction + /// string, respecting grammar semantics: a rule body of the shape + /// alt1 | alt2 | … means "exactly one of these paths is taken at parse + /// time" → the corresponding dispatch-time predicate is the disjunction of the + /// per-alternative AND-conjunctions. + /// + /// Each non-empty alternative's clause list is joined by && + /// (wrapped in parens when it has 2+ clauses to keep operator precedence + /// explicit). Empty alternatives are dropped. Identical alternatives collapse + /// to a single clause. When 2+ distinct alternatives remain, the overall result + /// is wrapped in parens and joined by ||. + /// + /// + /// One list of synthesized clauses per grammar alternative. + /// A single combined predicate string, or null when every alternative is empty. + private static string CombineAlternativesAsOr(List> perAlternativeClauses) + { + var nonEmpty = perAlternativeClauses + .Where(altClauses => altClauses.Count > 0) + .Select(altClauses => altClauses.Count == 1 + ? altClauses[0] + : "(" + string.Join(" && ", altClauses) + ")") + .ToList(); + + if (nonEmpty.Count == 0) + { + return null; + } + + var distinct = nonEmpty.Distinct(StringComparer.Ordinal).ToList(); + + if (distinct.Count == 1) + { + return distinct[0]; + } + + return "(" + string.Join(" || ", distinct) + ")"; } /// @@ -1064,7 +1235,7 @@ private static string SynthesiseGuardFromRuleBody(TextualNotationRule rule, ICla /// trailing ownedRelationship += EmptyMultiplicityMember) therefore correctly /// produce no cursor clause and fall back to leaving the rule as the unguarded default. /// - private static void CollectGuardClauses(IEnumerable elements, IEnumerable targetProperties, IXmiElementCache cache, IReadOnlyList allRules, List clauses, ref bool firstCursorEmitted, ref bool cursorMayHaveAdvanced) + private static void CollectGuardClauses(IEnumerable elements, IEnumerable targetProperties, IXmiElementCache cache, IReadOnlyList allRules, List clauses, ref bool firstCursorEmitted, ref bool cursorMayHaveAdvanced, HashSet visitedRules, int remainingDepth) { foreach (var element in elements) { @@ -1072,6 +1243,16 @@ private static void CollectGuardClauses(IEnumerable elements, IEnum { case AssignmentElement assignment: { + // Skip optional assignments (`?` / `*` suffix on the assignment + // itself). Their target property may legitimately be unset on a + // valid runtime POCO, so an emitted `&&`-joined predicate would + // wrongly reject those instances at dispatch time. Only mandatory + // assignments (no suffix or `+` suffix) yield guard clauses. + if (assignment.IsOptional) + { + break; + } + var clause = TryBuildClauseForAssignment(assignment, targetProperties, cache, allRules, ref firstCursorEmitted, cursorMayHaveAdvanced); if (!string.IsNullOrEmpty(clause)) @@ -1088,21 +1269,92 @@ private static void CollectGuardClauses(IEnumerable elements, IEnum break; } - case NonTerminalElement: + case NonTerminalElement nonTerminal: { - // A NonTerminal reference may advance the dispatch cursor at runtime - // because the referenced rule may consume `ownedRelationship +=` - // internally. Conservatively assume it does so that we don't synthesise - // a stale cursor-0 predicate for a later `ownedRelationship +=`. + // Deep walk: if there is still depth budget and the referenced rule + // has not yet been visited on this walk, descend into its body so + // structural predicates further down the rule chain (e.g. + // FeatureDeclaration → FeatureIdentification → declaredName = NAME) + // are surfaced as additional clauses. Per-alternative OR-combine: a + // referenced rule with multiple alternatives means exactly one path + // fires at parse-time, so the dispatch-time predicate must be the + // disjunction of the per-alternative AND-conjunctions (not their + // conjunction). Once any NonTerminal is walked, the dispatch cursor + // may have advanced (we cannot statically replay the entire builder), + // so cursor-predicate emission is suppressed for the rest of this + // walk via cursorMayHaveAdvanced = true. + if (remainingDepth > 0) + { + var referencedRule = allRules.SingleOrDefault(rule => rule.RuleName == nonTerminal.Name); + + if (referencedRule != null && visitedRules.Add(nonTerminal.Name)) + { + cursorMayHaveAdvanced = true; + + var perReferencedAlternativeClauses = new List>(); + + foreach (var referencedAlternative in referencedRule.Alternatives) + { + var altClauses = new List(); + CollectGuardClauses(referencedAlternative.Elements, targetProperties, cache, allRules, altClauses, ref firstCursorEmitted, ref cursorMayHaveAdvanced, visitedRules, remainingDepth - 1); + perReferencedAlternativeClauses.Add(altClauses); + } + + var combinedReferenced = CombineAlternativesAsOr(perReferencedAlternativeClauses); + + if (!string.IsNullOrEmpty(combinedReferenced)) + { + clauses.Add(combinedReferenced); + } + + break; + } + } + + // Shallow fallback: depth budget exhausted, rule not found, or + // already visited. A NonTerminal reference may advance the dispatch + // cursor at runtime, so conservatively suppress any later cursor + // predicates. cursorMayHaveAdvanced = true; break; } case GroupElement group: { + // Skip optional groups (`?` and `*` suffix). Assignments inside an + // optional group are not guaranteed to fire at parse-time and + // therefore the associated property may legitimately be unset on a + // valid runtime POCO. Emitting them as mandatory `&&` clauses would + // wrongly reject those POCOs at dispatch time. Only walk groups + // that are guaranteed to execute: a group with no suffix or with + // `+` (one-or-more — at least one iteration is mandatory). + if (group.IsOptional) + { + break; + } + + // Per-alternative walk + OR-combine: each `group.Alternatives` + // entry represents an "or-branch" of the group (`(a | b | c)`). + // At runtime exactly one branch is taken, so the dispatch-time + // predicate is the disjunction of per-branch AND-conjunctions. + // Cursor-state (`firstCursorEmitted`, `cursorMayHaveAdvanced`) is + // shared across branches because any branch may consume the + // dispatch cursor; once that happens for any branch we must + // conservatively suppress subsequent cursor predicates. + var perGroupAlternativeClauses = new List>(); + foreach (var groupAlternative in group.Alternatives) { - CollectGuardClauses(groupAlternative.Elements, targetProperties, cache, allRules, clauses, ref firstCursorEmitted, ref cursorMayHaveAdvanced); + var altClauses = new List(); + CollectGuardClauses(groupAlternative.Elements, targetProperties, cache, allRules, altClauses, ref firstCursorEmitted, ref cursorMayHaveAdvanced, visitedRules, remainingDepth); + perGroupAlternativeClauses.Add(altClauses); + } + + var combined = CombineAlternativesAsOr(perGroupAlternativeClauses); + + if (!string.IsNullOrEmpty(combined)) + { + clauses.Add(combined); } break; @@ -1139,14 +1391,37 @@ private static string TryBuildClauseForAssignment(AssignmentElement assignment, var matchingProperty = targetProperties.FirstOrDefault(property => string.Equals(property.Name, assignment.Property, StringComparison.OrdinalIgnoreCase)); - var propertyAccessor = matchingProperty != null - ? matchingProperty.QueryPropertyNameBasedOnUmlProperties() - : assignment.Property.CapitalizeFirstLetter(); + if (matchingProperty == null) + { + // The assignment targets a property that does not exist on the outer + // alternative's class. This can happen when the depth-aware walk descends + // into a NonTerminal whose target metaclass is unrelated to the outer's + // class (e.g. walking AnnotatingElement's switch dispatches into Comment + // / Documentation rules that assign `body`, `locale`, `language` which + // are NOT on the outer IAnnotatingElement). Emitting `{0}.{Prop}` would + // produce a compile error since the case variable lacks that member. + // Skip the clause; the outer guard remains correct without it. + return null; + } + + // Drop `+=` clauses whose target property is not actually a collection on the + // outer class. The grammar's `+=` annotation tells the parser to append to a + // collection in the called rule's target metaclass — but when the depth-aware + // walk crosses a NonTerminal boundary, the OUTER class may expose the same + // property name as a scalar (e.g. `ISubsetting.Specific` is a single IFeature, + // not an IFeature collection). Emitting `{0}.Specific.OfType<…>().Any()` would + // fail to compile against the scalar property. + if (assignment.Operator == "+=" && !matchingProperty.QueryIsEnumerable()) + { + return null; + } + + var propertyAccessor = matchingProperty.QueryPropertyNameBasedOnUmlProperties(); switch (assignment.Operator) { case "=": - return BuildScalarAssignmentClause(assignment, propertyAccessor, cache, allRules); + return BuildScalarAssignmentClause(assignment, matchingProperty, propertyAccessor, cache, allRules); case "+=": return BuildCollectionAssignmentClause(assignment, propertyAccessor, cache, allRules, ref firstCursorEmitted, cursorMayHaveAdvanced); default: @@ -1154,33 +1429,80 @@ private static string TryBuildClauseForAssignment(AssignmentElement assignment, } } + /// + /// Determines whether can hold null in C#. True for + /// reference-typed properties (POCO interfaces, ) and nullable + /// value-typed properties (e.g. int?, VisibilityKind?); false for + /// non-nullable value types (mandatory enums or primitives with multiplicity [1]). + /// + /// Used by to suppress tautological + /// != null guards on properties that the runtime POCO cannot leave unset. + /// + /// + /// The resolved against the outer alternative class. + /// true if a runtime instance of the property could be null. + private static bool IsPropertyNullableInCSharp(IProperty property) + { + return property.QueryIsReferenceType() + || property.QueryIsNullableAndNotString() + || property.QueryIsString(); + } + /// /// Translates a parsed scalar = assignment into its corresponding /// when-clause predicate. Terminal-literal RHS becomes an equality check; /// [QualifiedName] RHS becomes a non-null check; NonTerminal RHS narrows to /// the referenced rule's target metaclass when known. + /// + /// When the matching property is a non-nullable value type (mandatory enum / + /// primitive — multiplicity [1] in UML), != null and is I… + /// predicates would be a tautology (always-true) or a compile error (value type + /// vs reference type), so they are silently dropped. Only the terminal-equality + /// branch ({0}.{Prop} == "literal") survives for non-nullable scalars. + /// /// /// The with = + /// The on the outer alternative class that this assignment binds — consulted for C# nullability. /// The C# property name resolved via /// The for resolving NonTerminal RHS targets /// All available rules for NonTerminal resolution /// A template clause, or null when no useful clause can be synthesised. - private static string BuildScalarAssignmentClause(AssignmentElement assignment, string propertyAccessor, IXmiElementCache cache, IReadOnlyList allRules) + private static string BuildScalarAssignmentClause(AssignmentElement assignment, IProperty matchingProperty, string propertyAccessor, IXmiElementCache cache, IReadOnlyList allRules) { switch (assignment.Value) { case TerminalElement terminal when !string.IsNullOrEmpty(terminal.Value): + // Terminal-literal equality is meaningful for any property type. return $"{{0}}.{propertyAccessor} == \"{terminal.Value}\""; case ValueLiteralElement valueLiteral when valueLiteral.QueryIsQualifiedName(): - return $"{{0}}.{propertyAccessor} != null"; + // [QualifiedName] RHS → non-null check; only meaningful when the C# + // property can be null. Non-nullable value types (multiplicity [1] + // enums / primitives) would yield a tautology — drop the clause. + return IsPropertyNullableInCSharp(matchingProperty) + ? $"{{0}}.{propertyAccessor} != null" + : null; case NonTerminalElement nonTerminal: { var rhsTargetClass = RuleQueryUtilities.ResolveRuleTargetClass(nonTerminal, cache, allRules); - return rhsTargetClass != null - ? $"{{0}}.{propertyAccessor} is {rhsTargetClass.QueryFullyQualifiedTypeName()}" - : $"{{0}}.{propertyAccessor} != null"; + + if (rhsTargetClass != null) + { + // `is I{Rhs}` requires a reference-typed property. For non-nullable + // value-typed properties (mandatory enums / primitives) the cast + // would not compile, so drop the clause. + return matchingProperty.QueryIsReferenceType() + ? $"{{0}}.{propertyAccessor} is {rhsTargetClass.QueryFullyQualifiedTypeName()}" + : null; + } + + // Fallback when the NonTerminal does not resolve to an IClass (e.g. + // its target is an enum literal or unresolved name) — emit `!= null` + // only when the property can actually hold null. + return IsPropertyNullableInCSharp(matchingProperty) + ? $"{{0}}.{propertyAccessor} != null" + : null; } default: @@ -1189,23 +1511,31 @@ private static string BuildScalarAssignmentClause(AssignmentElement assignment, } /// - /// Translates a parsed collection += assignment into its corresponding - /// when-clause predicate. For the first ownedRelationship += in the - /// rule body the predicate inspects the dispatch cursor's current element; for any - /// other collection it inspects the collection contents directly. Subsequent - /// ownedRelationship += assignments produce no clause because the cursor - /// will have advanced past them by the time their position is reached at runtime. + /// Translates a parsed collection += assignment into a cursor-based + /// when-clause predicate. The clause inspects the first element of the + /// target collection via the project's standard cursor pattern + /// (writerContext.CursorCache.GetOrCreateCursor(…).Current is …) — this + /// keeps the dispatch-time guards consistent with how the rest of the textual + /// notation builders consume containment collections. + /// + /// For ownedRelationship += the predicate is additionally gated by the + /// outer walk's tracker: once any + /// prior ownedRelationship += or a NonTerminal reference may have + /// advanced the dispatch cursor past position 0, no further cursor predicate + /// is emitted (it would check a stale position). For other collections that + /// concern does not apply — each collection has its own independent cursor. + /// /// /// The with += /// The C# collection-property name resolved via /// The for resolving NonTerminal RHS targets /// All available rules for NonTerminal resolution - /// Tracks whether a cursor predicate has been emitted yet for this rule. + /// Tracks whether the first ownedRelationship cursor predicate has been emitted yet for this walk. /// - /// When true, the dispatch cursor may have advanced past position 0 at runtime due to a - /// prior ownedRelationship += or a preceding NonTerminal reference whose - /// target rule may consume the cursor. Suppresses cursor predicate emission so we don't - /// generate stale cursor.Current is … checks against the wrong position. + /// When true, the dispatch (ownedRelationship) cursor may have advanced + /// past position 0 at runtime due to a prior ownedRelationship += or a + /// preceding NonTerminal reference whose target rule may consume the + /// cursor. Suppresses ownedRelationship cursor predicate emission. /// /// A template clause, or null when no useful clause can be synthesised. private static string BuildCollectionAssignmentClause(AssignmentElement assignment, string propertyAccessor, IXmiElementCache cache, IReadOnlyList allRules, ref bool firstCursorEmitted, bool cursorMayHaveAdvanced) @@ -1232,10 +1562,9 @@ private static string BuildCollectionAssignmentClause(AssignmentElement assignme } firstCursorEmitted = true; - return $"writerContext.CursorCache.GetOrCreateCursor({{0}}.Id, \"{assignment.Property}\", {{0}}.{propertyAccessor}).Current is {rhsTargetTypeName}"; } - return $"{{0}}.{propertyAccessor}.OfType<{rhsTargetTypeName}>().Any()"; + return $"writerContext.CursorCache.GetOrCreateCursor({{0}}.Id, \"{assignment.Property}\", {{0}}.{propertyAccessor}).Current is {rhsTargetTypeName}"; } } } diff --git a/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs b/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs index ea8bec36..5acd9325 100644 --- a/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs +++ b/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs @@ -29,6 +29,7 @@ namespace SysML2.NET.CodeGenerator.HandleBarHelpers using SysML2.NET.CodeGenerator.Grammar.Model; using uml4net.CommonStructure; + using uml4net.Extensions; using uml4net.StructuredClassifiers; /// @@ -92,11 +93,69 @@ public static void RegisterRulesHelper(this IHandlebars handlebars) }; ruleGenerationContext.AllRules.AddRange(allRules); + + var isOperatorExpressionRule = IsOperatorExpressionRule(textualRule, umlClass); + var isOwnedExpressionRule = string.Equals(textualRule.RuleName, "OwnedExpression", StringComparison.Ordinal); + + if (isOwnedExpressionRule) + { + writer.WriteSafeString("var operatorParensNeeded = writerContext.OperatorContextStack.Count > 0 && SysML2.NET.Serializer.TextualNotation.Writers.OperatorPrecedence.NeedsParenthesesAsOperand(writerContext.OperatorContextStack.Peek(), poco);" + Environment.NewLine); + writer.WriteSafeString("if (operatorParensNeeded) { stringBuilder.Append('('); }" + Environment.NewLine); + } + + if (isOperatorExpressionRule) + { + writer.WriteSafeString("writerContext.OperatorContextStack.Push(poco);" + Environment.NewLine); + writer.WriteSafeString("try" + Environment.NewLine + "{" + Environment.NewLine); + } + processor.ProcessAlternatives(writer, umlClass, textualRule.Alternatives, ruleGenerationContext); + + if (isOperatorExpressionRule) + { + writer.WriteSafeString("}" + Environment.NewLine + "finally" + Environment.NewLine + "{" + Environment.NewLine + "writerContext.OperatorContextStack.Pop();" + Environment.NewLine + "}" + Environment.NewLine); + } + + if (isOwnedExpressionRule) + { + writer.WriteSafeString("if (operatorParensNeeded) { stringBuilder.Append(')'); }" + Environment.NewLine); + } } }); } + /// + /// Determines whether targets an IOperatorExpression + /// (or any of its subclasses) as the rule's effective metaclass. Used by + /// WriteRule to wrap the generated builder body with a precedence-stack + /// push/pop so operand-rendering can decide on parens. + /// + /// The textual notation rule being generated. + /// The rule's target . + /// true when the target is OperatorExpression or a subclass. + private static bool IsOperatorExpressionRule(TextualNotationRule rule, IClass umlClass) + { + if (umlClass == null) + { + return false; + } + + if (string.Equals(umlClass.Name, "OperatorExpression", StringComparison.Ordinal)) + { + return true; + } + + foreach (var general in umlClass.QueryAllGeneralClassifiers()) + { + if (string.Equals(general.Name, "OperatorExpression", StringComparison.Ordinal)) + { + return true; + } + } + + return false; + } + /// /// Resolves the effective target class for a no-target rule by analyzing its assignments. /// diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CollectExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CollectExpressionTextualNotationBuilder.cs index 45fc8182..b2856545 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CollectExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/CollectExpressionTextualNotationBuilder.cs @@ -43,30 +43,38 @@ public static partial class CollectExpressionTextualNotationBuilder /// The that contains the entire textual notation public static void BuildCollectExpression(SysML2.NET.Core.POCO.Kernel.Expressions.ICollectExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } - stringBuilder.Append("."); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } + stringBuilder.Append("."); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildBodyArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildBodyArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } } + finally + { + writerContext.OperatorContextStack.Pop(); + } } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConjugatedPortTypingTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConjugatedPortTypingTextualNotationBuilder.cs index 0b40b440..e4daed84 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConjugatedPortTypingTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ConjugatedPortTypingTextualNotationBuilder.cs @@ -44,7 +44,7 @@ public static partial class ConjugatedPortTypingTextualNotationBuilder public static void BuildConjugatedPortTyping(SysML2.NET.Core.POCO.Systems.Ports.IConjugatedPortTyping poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { stringBuilder.Append("~"); - BuildOriginalPortDefinition(poco, writerContext, stringBuilder); + BuildConjugatedPortTypingHandCoded(poco, writerContext, stringBuilder); } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs index 1ae32838..805903a4 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs @@ -43,6 +43,8 @@ public static partial class ExpressionTextualNotationBuilder /// The that contains the entire textual notation public static void BuildOwnedExpression(SysML2.NET.Core.POCO.Kernel.Functions.IExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { + var operatorParensNeeded = writerContext.OperatorContextStack.Count > 0 && SysML2.NET.Serializer.TextualNotation.Writers.OperatorPrecedence.NeedsParenthesesAsOperand(writerContext.OperatorContextStack.Peek(), poco); + if (operatorParensNeeded) { stringBuilder.Append('('); } switch (poco) { case SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression pocoOperatorExpressionConditionalExpression when pocoOperatorExpressionConditionalExpression.IsValidForConditionalExpression(writerContext): @@ -63,13 +65,14 @@ public static void BuildOwnedExpression(SysML2.NET.Core.POCO.Kernel.Functions.IE case SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression pocoOperatorExpressionMetaclassificationExpression when pocoOperatorExpressionMetaclassificationExpression.IsValidForMetaclassificationExpression(writerContext): OperatorExpressionTextualNotationBuilder.BuildMetaclassificationExpression(pocoOperatorExpressionMetaclassificationExpression, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression pocoOperatorExpressionExtentExpression when pocoOperatorExpressionExtentExpression.Operator == "all" && writerContext.CursorCache.GetOrCreateCursor(pocoOperatorExpressionExtentExpression.Id, "ownedRelationship", pocoOperatorExpressionExtentExpression.OwnedRelationship).Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership: + case SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression pocoOperatorExpressionExtentExpression when (pocoOperatorExpressionExtentExpression.Operator == "all" && writerContext.CursorCache.GetOrCreateCursor(pocoOperatorExpressionExtentExpression.Id, "ownedRelationship", pocoOperatorExpressionExtentExpression.OwnedRelationship).Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership): OperatorExpressionTextualNotationBuilder.BuildExtentExpression(pocoOperatorExpressionExtentExpression, writerContext, stringBuilder); break; default: BuildPrimaryExpression(poco, writerContext, stringBuilder); break; } + if (operatorParensNeeded) { stringBuilder.Append(')'); } } @@ -84,8 +87,8 @@ public static void BuildPrimaryExpression(SysML2.NET.Core.POCO.Kernel.Functions. { switch (poco) { - case SysML2.NET.Core.POCO.Kernel.Expressions.IFeatureChainExpression pocoFeatureChainExpression: - FeatureChainExpressionTextualNotationBuilder.BuildFeatureChainExpression(pocoFeatureChainExpression, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Expressions.IFeatureChainExpression pocoFeatureChainExpressionFeatureChainExpression when writerContext.CursorCache.GetOrCreateCursor(pocoFeatureChainExpressionFeatureChainExpression.Id, "ownedRelationship", pocoFeatureChainExpressionFeatureChainExpression.OwnedRelationship).Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership: + FeatureChainExpressionTextualNotationBuilder.BuildFeatureChainExpression(pocoFeatureChainExpressionFeatureChainExpression, writerContext, stringBuilder); break; default: BuildNonFeatureChainPrimaryExpression(poco, writerContext, stringBuilder); @@ -105,20 +108,20 @@ public static void BuildNonFeatureChainPrimaryExpression(SysML2.NET.Core.POCO.Ke { switch (poco) { - case SysML2.NET.Core.POCO.Kernel.Expressions.IIndexExpression pocoIndexExpression: - IndexExpressionTextualNotationBuilder.BuildIndexExpression(pocoIndexExpression, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Expressions.IIndexExpression pocoIndexExpressionIndexExpression when writerContext.CursorCache.GetOrCreateCursor(pocoIndexExpressionIndexExpression.Id, "ownedRelationship", pocoIndexExpressionIndexExpression.OwnedRelationship).Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership: + IndexExpressionTextualNotationBuilder.BuildIndexExpression(pocoIndexExpressionIndexExpression, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Expressions.ISelectExpression pocoSelectExpression: - SelectExpressionTextualNotationBuilder.BuildSelectExpression(pocoSelectExpression, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Expressions.ISelectExpression pocoSelectExpressionSelectExpression when writerContext.CursorCache.GetOrCreateCursor(pocoSelectExpressionSelectExpression.Id, "ownedRelationship", pocoSelectExpressionSelectExpression.OwnedRelationship).Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership: + SelectExpressionTextualNotationBuilder.BuildSelectExpression(pocoSelectExpressionSelectExpression, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Expressions.ICollectExpression pocoCollectExpression: - CollectExpressionTextualNotationBuilder.BuildCollectExpression(pocoCollectExpression, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Expressions.ICollectExpression pocoCollectExpressionCollectExpression when writerContext.CursorCache.GetOrCreateCursor(pocoCollectExpressionCollectExpression.Id, "ownedRelationship", pocoCollectExpressionCollectExpression.OwnedRelationship).Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership: + CollectExpressionTextualNotationBuilder.BuildCollectExpression(pocoCollectExpressionCollectExpression, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression pocoOperatorExpression: - OperatorExpressionTextualNotationBuilder.BuildBracketExpression(pocoOperatorExpression, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression pocoOperatorExpressionBracketExpression when (writerContext.CursorCache.GetOrCreateCursor(pocoOperatorExpressionBracketExpression.Id, "ownedRelationship", pocoOperatorExpressionBracketExpression.OwnedRelationship).Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership && pocoOperatorExpressionBracketExpression.Operator == "["): + OperatorExpressionTextualNotationBuilder.BuildBracketExpression(pocoOperatorExpressionBracketExpression, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Expressions.IInvocationExpression pocoInvocationExpression: - InvocationExpressionTextualNotationBuilder.BuildFunctionOperationExpression(pocoInvocationExpression, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Expressions.IInvocationExpression pocoInvocationExpressionFunctionOperationExpression when writerContext.CursorCache.GetOrCreateCursor(pocoInvocationExpressionFunctionOperationExpression.Id, "ownedRelationship", pocoInvocationExpressionFunctionOperationExpression.OwnedRelationship).Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership: + InvocationExpressionTextualNotationBuilder.BuildFunctionOperationExpression(pocoInvocationExpressionFunctionOperationExpression, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Kernel.Functions.IExpression pocoExpressionSequenceExpression when pocoExpressionSequenceExpression.IsValidForSequenceExpression(writerContext): BuildSequenceExpression(pocoExpressionSequenceExpression, writerContext, stringBuilder); diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureChainExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureChainExpressionTextualNotationBuilder.cs index 7226a74a..c975ba6b 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureChainExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureChainExpressionTextualNotationBuilder.cs @@ -43,30 +43,38 @@ public static partial class FeatureChainExpressionTextualNotationBuilder /// The that contains the entire textual notation public static void BuildFeatureChainExpression(SysML2.NET.Core.POCO.Kernel.Expressions.IFeatureChainExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildNonFeatureChainPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } - stringBuilder.Append("."); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildNonFeatureChainPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } + stringBuilder.Append("."); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) + if (ownedRelationshipCursor.Current != null) { - MembershipTextualNotationBuilder.BuildFeatureChainMember(elementAsMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Root.Namespaces.IMembership elementAsMembership) + { + MembershipTextualNotationBuilder.BuildFeatureChainMember(elementAsMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } } + finally + { + writerContext.OperatorContextStack.Pop(); + } } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs index 1d39bbe6..4cacd4ad 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureMembershipTextualNotationBuilder.cs @@ -289,7 +289,7 @@ public static void BuildInitialNodeMember(SysML2.NET.Core.POCO.Core.Types.IFeatu { MembershipTextualNotationBuilder.BuildMemberPrefix(poco, writerContext, stringBuilder); stringBuilder.Append("first "); - BuildMemberFeature(poco, writerContext, stringBuilder); + BuildInitialNodeMemberHandCoded(poco, writerContext, stringBuilder); RelationshipTextualNotationBuilder.BuildRelationshipBody(poco, writerContext, stringBuilder); } @@ -538,7 +538,7 @@ public static void BuildOwnedExpressionReferenceMember(SysML2.NET.Core.POCO.Core /// The that contains the entire textual notation public static void BuildOwnedExpressionMember(SysML2.NET.Core.POCO.Core.Types.IFeatureMembership poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - BuildOwnedFeatureMember(poco, writerContext, stringBuilder); + BuildOwnedExpressionMemberHandCoded(poco, writerContext, stringBuilder); } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs index 655dfcdf..6faeca91 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/FeatureTextualNotationBuilder.cs @@ -543,29 +543,29 @@ public static void BuildFeatureElement(SysML2.NET.Core.POCO.Core.Features.IFeatu case SysML2.NET.Core.POCO.Kernel.Interactions.ISuccessionFlow pocoSuccessionFlow: SuccessionFlowTextualNotationBuilder.BuildSuccessionFlow(pocoSuccessionFlow, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Functions.IInvariant pocoInvariant: - InvariantTextualNotationBuilder.BuildInvariant(pocoInvariant, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Functions.IInvariant pocoInvariantInvariant when (pocoInvariantInvariant.DeclaredShortName != null || pocoInvariantInvariant.DeclaredName != null): + InvariantTextualNotationBuilder.BuildInvariant(pocoInvariantInvariant, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Kernel.Interactions.IFlow pocoFlow: FlowTextualNotationBuilder.BuildFlow(pocoFlow, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Functions.IBooleanExpression pocoBooleanExpression: - BooleanExpressionTextualNotationBuilder.BuildBooleanExpression(pocoBooleanExpression, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Functions.IBooleanExpression pocoBooleanExpressionBooleanExpression when (pocoBooleanExpressionBooleanExpression.DeclaredShortName != null || pocoBooleanExpressionBooleanExpression.DeclaredName != null): + BooleanExpressionTextualNotationBuilder.BuildBooleanExpression(pocoBooleanExpressionBooleanExpression, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Connectors.IBindingConnector pocoBindingConnector: - BindingConnectorTextualNotationBuilder.BuildBindingConnector(pocoBindingConnector, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Connectors.IBindingConnector pocoBindingConnectorBindingConnector when (pocoBindingConnectorBindingConnector.DeclaredShortName != null || pocoBindingConnectorBindingConnector.DeclaredName != null): + BindingConnectorTextualNotationBuilder.BuildBindingConnector(pocoBindingConnectorBindingConnector, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Connectors.ISuccession pocoSuccession: - SuccessionTextualNotationBuilder.BuildSuccession(pocoSuccession, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Connectors.ISuccession pocoSuccessionSuccession when (pocoSuccessionSuccession.DeclaredShortName != null || pocoSuccessionSuccession.DeclaredName != null): + SuccessionTextualNotationBuilder.BuildSuccession(pocoSuccessionSuccession, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Functions.IExpression pocoExpression: - ExpressionTextualNotationBuilder.BuildExpression(pocoExpression, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Functions.IExpression pocoExpressionExpression when (pocoExpressionExpression.DeclaredShortName != null || pocoExpressionExpression.DeclaredName != null): + ExpressionTextualNotationBuilder.BuildExpression(pocoExpressionExpression, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Connectors.IConnector pocoConnector: - ConnectorTextualNotationBuilder.BuildConnector(pocoConnector, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Connectors.IConnector pocoConnectorConnector when (pocoConnectorConnector.DeclaredShortName != null || pocoConnectorConnector.DeclaredName != null): + ConnectorTextualNotationBuilder.BuildConnector(pocoConnectorConnector, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Kernel.Behaviors.IStep pocoStep: - StepTextualNotationBuilder.BuildStep(pocoStep, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Behaviors.IStep pocoStepStep when (pocoStepStep.DeclaredShortName != null || pocoStepStep.DeclaredName != null): + StepTextualNotationBuilder.BuildStep(pocoStepStep, writerContext, stringBuilder); break; default: BuildFeature(poco, writerContext, stringBuilder); @@ -694,7 +694,7 @@ public static void BuildFeatureRelationshipPart(SysML2.NET.Core.POCO.Core.Featur case SysML2.NET.Core.POCO.Core.Features.IFeature pocoFeatureInvertingPart when pocoFeatureInvertingPart.IsValidForInvertingPart(writerContext): BuildInvertingPart(pocoFeatureInvertingPart, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Core.Features.IFeature pocoFeatureTypeFeaturingPart when writerContext.CursorCache.GetOrCreateCursor(pocoFeatureTypeFeaturingPart.Id, "ownedRelationship", pocoFeatureTypeFeaturingPart.OwnedRelationship).Current is SysML2.NET.Core.POCO.Core.Features.ITypeFeaturing && pocoFeatureTypeFeaturingPart.ownedTypeFeaturing.OfType().Any(): + case SysML2.NET.Core.POCO.Core.Features.IFeature pocoFeatureTypeFeaturingPart when writerContext.CursorCache.GetOrCreateCursor(pocoFeatureTypeFeaturingPart.Id, "ownedRelationship", pocoFeatureTypeFeaturingPart.OwnedRelationship).Current is SysML2.NET.Core.POCO.Core.Features.ITypeFeaturing: BuildTypeFeaturingPart(pocoFeatureTypeFeaturingPart, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Core.Types.IType pocoType: diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IndexExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IndexExpressionTextualNotationBuilder.cs index 493bc3e4..a13a6c35 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IndexExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/IndexExpressionTextualNotationBuilder.cs @@ -43,32 +43,40 @@ public static partial class IndexExpressionTextualNotationBuilder /// The that contains the entire textual notation public static void BuildIndexExpression(SysML2.NET.Core.POCO.Kernel.Expressions.IIndexExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } - stringBuilder.Append("#"); - stringBuilder.Append("("); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } + stringBuilder.Append("#"); + stringBuilder.Append("("); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) + if (ownedRelationshipCursor.Current != null) { - FeatureMembershipTextualNotationBuilder.BuildSequenceExpressionListMember(elementAsFeatureMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) + { + FeatureMembershipTextualNotationBuilder.BuildSequenceExpressionListMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } + stringBuilder.Append(") "); + } + finally + { + writerContext.OperatorContextStack.Pop(); } - stringBuilder.Append(") "); } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs index 76368111..06d506d8 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MembershipTextualNotationBuilder.cs @@ -210,11 +210,11 @@ public static void BuildMetadataBodyElement(SysML2.NET.Core.POCO.Root.Namespaces { switch (poco) { - case SysML2.NET.Core.POCO.Core.Types.IFeatureMembership pocoFeatureMembership: - FeatureMembershipTextualNotationBuilder.BuildMetadataBodyFeatureMember(pocoFeatureMembership, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Core.Types.IFeatureMembership pocoFeatureMembershipMetadataBodyFeatureMember when pocoFeatureMembershipMetadataBodyFeatureMember.ownedMemberFeature is SysML2.NET.Core.POCO.Core.Features.IFeature: + FeatureMembershipTextualNotationBuilder.BuildMetadataBodyFeatureMember(pocoFeatureMembershipMetadataBodyFeatureMember, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership pocoOwningMembership: - OwningMembershipTextualNotationBuilder.BuildNonFeatureMember(pocoOwningMembership, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership pocoOwningMembershipNonFeatureMember when writerContext.CursorCache.GetOrCreateCursor(pocoOwningMembershipNonFeatureMember.Id, "ownedRelatedElement", pocoOwningMembershipNonFeatureMember.OwnedRelatedElement).Current is SysML2.NET.Core.POCO.Root.Elements.IElement: + OwningMembershipTextualNotationBuilder.BuildNonFeatureMember(pocoOwningMembershipNonFeatureMember, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Root.Namespaces.IImport pocoImport: ImportTextualNotationBuilder.BuildImport(pocoImport, writerContext, stringBuilder); diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityTextualNotationBuilder.cs index fab6b162..5b243ade 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/MultiplicityTextualNotationBuilder.cs @@ -73,8 +73,8 @@ public static void BuildMultiplicity(SysML2.NET.Core.POCO.Core.Types.IMultiplici { switch (poco) { - case SysML2.NET.Core.POCO.Kernel.Multiplicities.IMultiplicityRange pocoMultiplicityRange: - MultiplicityRangeTextualNotationBuilder.BuildMultiplicityRange(pocoMultiplicityRange, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Kernel.Multiplicities.IMultiplicityRange pocoMultiplicityRangeMultiplicityRange when writerContext.CursorCache.GetOrCreateCursor(pocoMultiplicityRangeMultiplicityRange.Id, "ownedRelationship", pocoMultiplicityRangeMultiplicityRange.OwnedRelationship).Current is SysML2.NET.Core.POCO.Root.Namespaces.IOwningMembership: + MultiplicityRangeTextualNotationBuilder.BuildMultiplicityRange(pocoMultiplicityRangeMultiplicityRange, writerContext, stringBuilder); break; default: BuildMultiplicitySubset(poco, writerContext, stringBuilder); diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OperatorExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OperatorExpressionTextualNotationBuilder.cs index c61fdefa..7a0f731e 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OperatorExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OperatorExpressionTextualNotationBuilder.cs @@ -43,54 +43,63 @@ public static partial class OperatorExpressionTextualNotationBuilder /// The that contains the entire textual notation public static void BuildConditionalExpression(SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - stringBuilder.Append(poco.Operator); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); + stringBuilder.Append(poco.Operator); + stringBuilder.Append(' '); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } - stringBuilder.Append("? "); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } + stringBuilder.Append("? "); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildArgumentExpressionMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } - stringBuilder.Append("else "); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildArgumentExpressionMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } + stringBuilder.Append("else "); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildArgumentExpressionMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildArgumentExpressionMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + { + ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } } + finally + { + writerContext.OperatorContextStack.Pop(); + } } @@ -103,41 +112,50 @@ public static void BuildConditionalExpression(SysML2.NET.Core.POCO.Kernel.Expres /// The that contains the entire textual notation public static void BuildConditionalBinaryOperatorExpression(SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } - stringBuilder.Append(poco.Operator); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } + stringBuilder.Append(poco.Operator); + stringBuilder.Append(' '); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildArgumentExpressionMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildArgumentExpressionMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + { + ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } } + finally + { + writerContext.OperatorContextStack.Pop(); + } } @@ -150,41 +168,50 @@ public static void BuildConditionalBinaryOperatorExpression(SysML2.NET.Core.POCO /// The that contains the entire textual notation public static void BuildBinaryOperatorExpression(SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } - stringBuilder.Append(poco.Operator); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } + stringBuilder.Append(poco.Operator); + stringBuilder.Append(' '); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + { + ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } } + finally + { + writerContext.OperatorContextStack.Pop(); + } } @@ -197,30 +224,39 @@ public static void BuildBinaryOperatorExpression(SysML2.NET.Core.POCO.Kernel.Exp /// The that contains the entire textual notation public static void BuildUnaryOperatorExpression(SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - stringBuilder.Append(poco.Operator); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); + stringBuilder.Append(poco.Operator); + stringBuilder.Append(' '); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + { + ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } } + finally + { + writerContext.OperatorContextStack.Pop(); + } } @@ -233,37 +269,45 @@ public static void BuildUnaryOperatorExpression(SysML2.NET.Core.POCO.Kernel.Expr /// The that contains the entire textual notation public static void BuildClassificationExpression(SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); if (ownedRelationshipCursor.Current != null) { - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } + stringBuilder.Append(' '); } - stringBuilder.Append(' '); - } - - BuildClassificationExpressionHandCoded(poco, writerContext, stringBuilder); - stringBuilder.Append(' '); - if (ownedRelationshipCursor.Current != null) - { + BuildClassificationExpressionHandCoded(poco, writerContext, stringBuilder); + stringBuilder.Append(' '); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + { + ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } } + finally + { + writerContext.OperatorContextStack.Pop(); + } } @@ -276,31 +320,39 @@ public static void BuildClassificationExpression(SysML2.NET.Core.POCO.Kernel.Exp /// The that contains the entire textual notation public static void BuildMetaclassificationExpression(SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildMetadataArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } - BuildMetaclassificationExpressionHandCoded(poco, writerContext, stringBuilder); - stringBuilder.Append(' '); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildMetadataArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } + BuildMetaclassificationExpressionHandCoded(poco, writerContext, stringBuilder); + stringBuilder.Append(' '); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Functions.IReturnParameterMembership elementAsReturnParameterMembership) + { + ReturnParameterMembershipTextualNotationBuilder.BuildEmptyResultMember(elementAsReturnParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } } + finally + { + writerContext.OperatorContextStack.Pop(); + } } @@ -313,19 +365,28 @@ public static void BuildMetaclassificationExpression(SysML2.NET.Core.POCO.Kernel /// The that contains the entire textual notation public static void BuildExtentExpression(SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - stringBuilder.Append(poco.Operator); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); + stringBuilder.Append(poco.Operator); + stringBuilder.Append(' '); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildTypeReferenceMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildTypeReferenceMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } } + finally + { + writerContext.OperatorContextStack.Pop(); + } } @@ -338,31 +399,40 @@ public static void BuildExtentExpression(SysML2.NET.Core.POCO.Kernel.Expressions /// The that contains the entire textual notation public static void BuildBracketExpression(SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } - stringBuilder.Append(poco.Operator); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } + stringBuilder.Append(poco.Operator); + stringBuilder.Append(' '); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) + if (ownedRelationshipCursor.Current != null) { - FeatureMembershipTextualNotationBuilder.BuildSequenceExpressionListMember(elementAsFeatureMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) + { + FeatureMembershipTextualNotationBuilder.BuildSequenceExpressionListMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } + stringBuilder.Append("] "); + } + finally + { + writerContext.OperatorContextStack.Pop(); } - stringBuilder.Append("] "); } @@ -375,30 +445,39 @@ public static void BuildBracketExpression(SysML2.NET.Core.POCO.Kernel.Expression /// The that contains the entire textual notation public static void BuildSequenceOperatorExpression(SysML2.NET.Core.POCO.Kernel.Expressions.IOperatorExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) + if (ownedRelationshipCursor.Current != null) { - FeatureMembershipTextualNotationBuilder.BuildOwnedExpressionMember(elementAsFeatureMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } - stringBuilder.Append(poco.Operator); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) + { + FeatureMembershipTextualNotationBuilder.BuildOwnedExpressionMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } + stringBuilder.Append(poco.Operator); + stringBuilder.Append(' '); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) + if (ownedRelationshipCursor.Current != null) { - FeatureMembershipTextualNotationBuilder.BuildSequenceExpressionListMember(elementAsFeatureMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Core.Types.IFeatureMembership elementAsFeatureMembership) + { + FeatureMembershipTextualNotationBuilder.BuildSequenceExpressionListMember(elementAsFeatureMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } } + finally + { + writerContext.OperatorContextStack.Pop(); + } } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OwningMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OwningMembershipTextualNotationBuilder.cs index b3de9f74..4aa8aaa4 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OwningMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/OwningMembershipTextualNotationBuilder.cs @@ -410,8 +410,8 @@ public static void BuildFeatureMember(SysML2.NET.Core.POCO.Root.Namespaces.IOwni { switch (poco) { - case SysML2.NET.Core.POCO.Core.Types.IFeatureMembership pocoFeatureMembership: - FeatureMembershipTextualNotationBuilder.BuildOwnedFeatureMember(pocoFeatureMembership, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Core.Types.IFeatureMembership pocoFeatureMembershipOwnedFeatureMember when writerContext.CursorCache.GetOrCreateCursor(pocoFeatureMembershipOwnedFeatureMember.Id, "ownedRelatedElement", pocoFeatureMembershipOwnedFeatureMember.OwnedRelatedElement).Current is SysML2.NET.Core.POCO.Core.Features.IFeature: + FeatureMembershipTextualNotationBuilder.BuildOwnedFeatureMember(pocoFeatureMembershipOwnedFeatureMember, writerContext, stringBuilder); break; default: BuildTypeFeatureMember(poco, writerContext, stringBuilder); diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SelectExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SelectExpressionTextualNotationBuilder.cs index a66e9b8d..536d2a98 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SelectExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/SelectExpressionTextualNotationBuilder.cs @@ -43,30 +43,38 @@ public static partial class SelectExpressionTextualNotationBuilder /// The that contains the entire textual notation public static void BuildSelectExpression(SysML2.NET.Core.POCO.Kernel.Expressions.ISelectExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - - if (ownedRelationshipCursor.Current != null) + writerContext.OperatorContextStack.Push(poco); + try { + var ownedRelationshipCursor = writerContext.CursorCache.GetOrCreateCursor(poco.Id, "ownedRelationship", poco.OwnedRelationship); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); - } - } - stringBuilder.Append(".? "); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildPrimaryArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); - if (ownedRelationshipCursor.Current != null) - { + } + } + stringBuilder.Append(".? "); - if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + if (ownedRelationshipCursor.Current != null) { - ParameterMembershipTextualNotationBuilder.BuildBodyArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); - ownedRelationshipCursor.Move(); + if (ownedRelationshipCursor.Current is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership elementAsParameterMembership) + { + ParameterMembershipTextualNotationBuilder.BuildBodyArgumentMember(elementAsParameterMembership, writerContext, stringBuilder); + ownedRelationshipCursor.Move(); + + } } } + finally + { + writerContext.OperatorContextStack.Pop(); + } } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/ConjugatedPortTypingTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/ConjugatedPortTypingTextualNotationBuilder.cs index 49626d0d..8499196c 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/ConjugatedPortTypingTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/ConjugatedPortTypingTextualNotationBuilder.cs @@ -30,13 +30,26 @@ namespace SysML2.NET.Serializer.TextualNotation.Writers public static partial class ConjugatedPortTypingTextualNotationBuilder { /// - /// Build the originalPortDefinition=~[QualifiedName] rule part + /// Builds the Textual Notation string for the rule ConjugatedPortTyping. + /// ConjugatedPortTyping:ConjugatedPortTyping='~'originalPortDefinition=~[QualifiedName] + /// The grammar's originalPortDefinition property does not resolve + /// against — the metamodel exposes + /// portDefinition (the derived port-definition reference) instead. + /// The leading '~' token is already emitted by the autogen wrapper; + /// this hand-coded sibling carries the ~[QualifiedName] emission as + /// a stub (matches the previous empty-stub behavior of + /// BuildOriginalPortDefinition). /// /// The from which the rule should be build /// The used to get access to CursorCollection for the current /// The that contains the entire textual notation - private static void BuildOriginalPortDefinition(IConjugatedPortTyping poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) + private static void BuildConjugatedPortTypingHandCoded(IConjugatedPortTyping poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { + // Preserves the previous empty-stub behavior of BuildOriginalPortDefinition + // for this call site. Full ~[QualifiedName] emission via the + // conjugated-resolution rule documented in SysML-textual-bnf.kebnf + // lines 651-658 still requires a dedicated implementation; left as a + // follow-up. } } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/FeatureMembershipTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/FeatureMembershipTextualNotationBuilder.cs index a36cb3ba..2e31a41c 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/FeatureMembershipTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/FeatureMembershipTextualNotationBuilder.cs @@ -40,6 +40,47 @@ private static void BuildMemberFeature(IFeatureMembership poco, TextualNotationW { } + /// + /// Builds the Textual Notation string for the rule InitialNodeMember. + /// InitialNodeMember:FeatureMembership=MemberPrefix'first'memberFeature=[QualifiedName]RelationshipBody + /// The grammar's memberFeature property does not resolve against + /// — the metamodel only exposes + /// ownedMemberFeature on IFeatureMembership and MemberElement + /// on its parent IMembership. This hand-coded sibling carries the + /// remaining [QualifiedName] emission as a stub; the surrounding + /// MemberPrefix, 'first', and RelationshipBody tokens are + /// already emitted by the autogen wrapper. + /// + /// The from which the rule should be build + /// The providing the serialization context for the current + /// The that contains the entire textual notation + private static void BuildInitialNodeMemberHandCoded(IFeatureMembership poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) + { + // Preserves the previous empty-stub behavior of BuildMemberFeature for this + // call site. The full QualifiedName-emission still requires a dedicated + // implementation; left as a follow-up. + } + + /// + /// Builds the Textual Notation string for the rule OwnedExpressionMember. + /// OwnedExpressionMember:FeatureMembership=ownedFeatureMember=OwnedExpression + /// The grammar property name ownedFeatureMember does not exist on + /// — the OMG kebnf carries a one-off typo and + /// the real metamodel property is ownedMemberFeature. This hand-coded + /// sibling resolves the typo at emission time, dispatching the membership's + /// OwnedMemberFeature through BuildOwnedExpression. + /// + /// The from which the rule should be build + /// The providing the serialization context for the current + /// The that contains the entire textual notation + private static void BuildOwnedExpressionMemberHandCoded(IFeatureMembership poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) + { + if (poco.ownedMemberFeature is SysML2.NET.Core.POCO.Kernel.Functions.IExpression elementAsExpression) + { + ExpressionTextualNotationBuilder.BuildOwnedExpression(elementAsExpression, writerContext, stringBuilder); + } + } + /// /// Builds the Textual Notation string for the rule EntryTransitionMember /// EntryTransitionMember:FeatureMembership=MemberPrefix(ownedRelatedElement+=GuardedTargetSuccession|'then'ownedRelatedElement+=TargetSuccession)';' diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/OperatorPrecedence.cs b/SysML2.NET.Serializer.TextualNotation/Writers/OperatorPrecedence.cs new file mode 100644 index 00000000..1fdd54d4 --- /dev/null +++ b/SysML2.NET.Serializer.TextualNotation/Writers/OperatorPrecedence.cs @@ -0,0 +1,279 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// 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 SysML2.NET.Core.POCO.Kernel.Expressions; + using SysML2.NET.Core.POCO.Kernel.Functions; + + /// + /// Precedence-aware parenthesization helpers for operator-expression operands. + /// + /// The KEBNF grammar uses SequenceExpression : Expression = '(' SequenceExpressionList ')' + /// as its parenthesization rule, but the SysML metamodel has no SequenceExpression + /// class — parens are a grammar-only artifact that collapses to the inner + /// at parse time. When writing back, the textual notation + /// writers must therefore decide AT EMISSION TIME whether to wrap a nested operator + /// expression in (…). This class provides the precedence table that drives the + /// decision: each operator-expression family / operator gets a precedence level, and + /// returns true when the inner expression + /// would be ambiguous without parens. + /// + /// + internal static class OperatorPrecedence + { + /// + /// Levels are inferred from the OwnedExpression rule alternative ordering + /// in Resources/KerML-textual-bnf.kebnf and tuned to reproduce the + /// canonical parenthesization in Resources/Quantities.sysml. Lower = binds + /// less tightly. + /// + private const int LevelConditional = 1; + private const int LevelConditionalBinary = 2; + private const int LevelBitwise = 3; + private const int LevelEquality = 4; + private const int LevelRelational = 5; + private const int LevelClassification = 6; + private const int LevelAdditive = 7; + private const int LevelMultiplicative = 8; + private const int LevelPower = 9; + private const int LevelUnary = 10; + private const int LevelExtent = 11; + private const int LevelPrimary = int.MaxValue; + + /// + /// Coarse-grained operator families used by the cross-family wrap rule. + /// + private enum PrecedenceBucket + { + Conditional, + Binary, + Classification, + Unary, + Extent, + Primary, + } + + /// + /// Returns the precedence level of . Lower = binds less + /// tightly. Primary forms (literals, feature references, invocations, etc.) return + /// — they are self-contained and never need wrapping. + /// + /// The expression to classify, or null. + /// The precedence level. + internal static int GetExpressionPrecedence(IExpression expression) + { + // Order matters in the metamodel inheritance chain: + // IExpression ← IInstantiationExpression ← IInvocationExpression ← IOperatorExpression ← {IFeatureChainExpression, IIndexExpression, ICollectExpression, ISelectExpression}. + // Several "primary forms" (member-access `.`, index `[..]`, collect `.`, + // select `.?`) are technically IOperatorExpression-typed in the metamodel + // but render as self-contained tokens — they must be classified as primary + // BEFORE the generic IOperatorExpression check. + if (expression is IFeatureChainExpression + || expression is IIndexExpression + || expression is ICollectExpression + || expression is ISelectExpression) + { + return LevelPrimary; + } + + if (expression is IOperatorExpression op) + { + // BracketExpression (`[`) and SequenceOperatorExpression (`,`) are + // OperatorExpression-typed metamodel-wise but render as primary forms + // (`a[…]`, `(a, b)`). They are distinguished by their `operator` + // discriminator; no separate interface exists. + if (op.Operator is "[" or ",") + { + return LevelPrimary; + } + + return GetOperatorExpressionPrecedence(op); + } + + // Non-operator-expression primary forms (literals, references, invocations, + // etc.) are always self-contained tokens. + if (expression is IInvocationExpression + || expression is IFeatureReferenceExpression + || expression is IMetadataAccessExpression + || expression is INullExpression + || expression is ILiteralExpression + || expression is IConstructorExpression) + { + return LevelPrimary; + } + + return LevelPrimary; + } + + /// + /// Returns the precedence level of an based on + /// its Operator discriminator. + /// + /// The operator expression. + /// The precedence level. + private static int GetOperatorExpressionPrecedence(IOperatorExpression op) + { + var @operator = op.Operator; + + if (@operator == "if") + { + return LevelConditional; + } + + if (@operator is "or" or "and" or "implies" or "??") + { + return LevelConditionalBinary; + } + + if (@operator is "|" or "&" or "xor") + { + return LevelBitwise; + } + + if (@operator is "==" or "!=" or "===" or "!==") + { + return LevelEquality; + } + + if (@operator is "<" or ">" or "<=" or ">=" or "..") + { + return LevelRelational; + } + + if (@operator is "as" or "istype" or "hastype" or "@" or "@@" or "meta") + { + return LevelClassification; + } + + if (@operator is "*" or "/" or "%") + { + return LevelMultiplicative; + } + + if (@operator is "^" or "**") + { + return LevelPower; + } + + if (@operator is "+" or "-") + { + // + and - are both binary (additive) and unary (sign). Distinguish by the + // count of argument-member relationships on the operator expression: two + // means additive (LHS + RHS); fewer means unary (sign). + return HasTwoArguments(op) ? LevelAdditive : LevelUnary; + } + + if (@operator is "~" or "not") + { + return LevelUnary; + } + + if (@operator == "all") + { + return LevelExtent; + } + + // Unknown operator: treat as unary-level (conservative — wraps when nested). + return LevelUnary; + } + + /// + /// Determines whether needs to be wrapped in + /// (…) when it appears as an operand of . The rule: + /// cross-family nesting always wraps (binary inside conditional, etc.); same-family + /// nesting wraps only when the inner has same-or-lower precedence than the outer. + /// + /// The enclosing operator expression. + /// The candidate operand expression. + /// true when parens are required for unambiguous rendering. + internal static bool NeedsParenthesesAsOperand(IExpression outer, IExpression operand) + { + if (operand == null || outer == null) + { + return false; + } + + var innerPrecedence = GetExpressionPrecedence(operand); + + if (innerPrecedence == LevelPrimary) + { + return false; + } + + var outerPrecedence = GetExpressionPrecedence(outer); + + var innerBucket = GetBucket(innerPrecedence); + var outerBucket = GetBucket(outerPrecedence); + + if (innerBucket != outerBucket) + { + return true; + } + + return innerPrecedence <= outerPrecedence; + } + + /// + /// Counts the IOperatorExpression's argument-members to distinguish binary additive + /// (a + b) from unary sign (+ a). Two argument-members indicate the + /// binary form. + /// + /// The operator expression. + /// true when at least two argument-members are present. + private static bool HasTwoArguments(IOperatorExpression op) + { + var count = 0; + + foreach (var relationship in op.OwnedRelationship) + { + if (relationship is SysML2.NET.Core.POCO.Kernel.Behaviors.IParameterMembership) + { + count++; + + if (count >= 2) + { + return true; + } + } + } + + return false; + } + + /// + /// Maps a precedence level to its coarse-grained operator family bucket. + /// + /// The precedence level. + /// The bucket. + private static PrecedenceBucket GetBucket(int precedence) + { + return precedence switch + { + LevelConditional or LevelConditionalBinary => PrecedenceBucket.Conditional, + LevelBitwise or LevelEquality or LevelRelational or LevelAdditive or LevelMultiplicative or LevelPower => PrecedenceBucket.Binary, + LevelClassification => PrecedenceBucket.Classification, + LevelUnary => PrecedenceBucket.Unary, + LevelExtent => PrecedenceBucket.Extent, + _ => PrecedenceBucket.Primary, + }; + } + } +} diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationValidationExtensions.cs b/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationValidationExtensions.cs index bd356789..9925f822 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationValidationExtensions.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationValidationExtensions.cs @@ -30,6 +30,7 @@ namespace SysML2.NET.Serializer.TextualNotation.Writers using SysML2.NET.Core.POCO.Kernel.Connectors; using SysML2.NET.Core.POCO.Kernel.Expressions; using SysML2.NET.Core.POCO.Kernel.Functions; + using SysML2.NET.Core.POCO.Kernel.Interactions; using SysML2.NET.Core.POCO.Root.Elements; using SysML2.NET.Core.POCO.Root.Namespaces; using SysML2.NET.Core.POCO.Systems.Actions; @@ -229,16 +230,8 @@ private static IElement QueryCurrentOwnedRelationship(IElement element, TextualN internal static bool IsValidForBehaviorUsageMember(this IFeatureMembership featureMembership, TextualNotationWriterContext writerContext) { return featureMembership?.OwnedRelatedElement.Any(element => - (element is IActionUsage or IStateUsage or IConstraintUsage - or IRequirementUsage or ICaseUsage) - && element is not IControlNode - && element is not ISendActionUsage - && element is not IAcceptActionUsage - && element is not IAssignmentActionUsage - && element is not ITerminateActionUsage - && element is not IIfActionUsage - && element is not ILoopActionUsage - && element is not ITransitionUsage) == true; + (element is (IActionUsage or IStateUsage or IConstraintUsage + or IRequirementUsage or ICaseUsage) and not IControlNode and not ISendActionUsage and not IAcceptActionUsage and not IAssignmentActionUsage and not ITerminateActionUsage and not IIfActionUsage and not ILoopActionUsage and not ITransitionUsage)) == true; } /// @@ -310,11 +303,9 @@ internal static bool IsValidForBinaryInterfacePart(this IInterfaceUsage interfac /// True if the usage is a structural-usage metaclass (and not a behavior-usage subtype routed by a sibling rule) internal static bool IsValidForStructureUsageElement(this IUsage usage, TextualNotationWriterContext writerContext) { - return (usage is IOccurrenceUsage or IItemUsage or IPartUsage or IViewUsage - or IRenderingUsage or IPortUsage or IConnectionUsage or IInterfaceUsage - or IAllocationUsage or IFlowUsage) - && usage is not IConstraintUsage - && (usage is not IActionUsage || usage is IFlowUsage); + return (usage is (IOccurrenceUsage or IItemUsage or IPartUsage or IViewUsage + or IRenderingUsage or IPortUsage or IConnectionUsage or IInterfaceUsage + or IAllocationUsage or IFlowUsage) and not IConstraintUsage and (not IActionUsage or IFlowUsage)); } /// @@ -334,12 +325,7 @@ or IRenderingUsage or IPortUsage or IConnectionUsage or IInterfaceUsage /// True if the usage is a plain occurrence (no individual, no portion kind, and not routed by a more specific sibling rule) internal static bool IsValidForOccurrenceUsage(this IOccurrenceUsage occurrenceUsage, TextualNotationWriterContext writerContext) { - return occurrenceUsage is { IsIndividual: false, PortionKind: null } - && occurrenceUsage is not IItemUsage - && occurrenceUsage is not IPortUsage - && occurrenceUsage is not IActionUsage - && occurrenceUsage is not IConstraintUsage - && occurrenceUsage is not IEventOccurrenceUsage; + return occurrenceUsage is { IsIndividual: false, PortionKind: null } and not IItemUsage and not IPortUsage and not IActionUsage and not IConstraintUsage and not IEventOccurrenceUsage; } /// diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs b/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs index 1dc046fa..5009f86e 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs @@ -21,7 +21,9 @@ namespace SysML2.NET.Serializer.TextualNotation.Writers { using System; + using System.Collections.Generic; + using SysML2.NET.Core.POCO.Kernel.Functions; using SysML2.NET.Core.POCO.Root.Namespaces; /// @@ -49,8 +51,19 @@ public TextualNotationWriterContext(INamespace contextNamespace) this.CursorCache = new CursorCache(); this.ContextNamespace = contextNamespace ?? throw new ArgumentNullException(nameof(contextNamespace)); this.NameResolutionCache = new NameResolutionCache(contextNamespace); + this.OperatorContextStack = new Stack(); } + /// + /// Gets the stack of currently-active enclosing operator expressions. The textual + /// notation builder for each IOperatorExpression-typed rule pushes its + /// poco on entry and pops it on exit (try/finally), so + /// operand-emission paths can peek the top to obtain the enclosing operator and + /// consult to decide + /// whether the operand needs to be wrapped in (…). + /// + public Stack OperatorContextStack { get; } + /// /// Gets the used for cursor-based element traversal. /// From 8e307e0ff5c0b4b21e8215c38d340c5e6aab71c8 Mon Sep 17 00:00:00 2001 From: atheate Date: Thu, 21 May 2026 10:15:53 +0200 Subject: [PATCH 3/5] Fix textual notation --- .../HandleBarHelpers/RuleQueryUtilities.cs | 63 ++++++++++++++++--- .../ElementTextualNotationBuilder.cs | 6 +- .../ReferenceUsageTextualNotationBuilder.cs | 6 +- .../UsageTextualNotationBuilder.cs | 30 ++++----- .../Writers/OperatorPrecedence.cs | 9 +++ .../TextualNotationValidationExtensions.cs | 53 ++++++++++++++++ 6 files changed, 139 insertions(+), 28 deletions(-) diff --git a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleQueryUtilities.cs b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleQueryUtilities.cs index 06389400..59ef7d79 100644 --- a/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleQueryUtilities.cs +++ b/SysML2.NET.CodeGenerator/HandleBarHelpers/RuleQueryUtilities.cs @@ -112,7 +112,19 @@ internal static INamedElement FindNamedElement(IXmiElementCache cache, string ty } /// - /// Extracts all boolean property names assigned via the conditional operator from a grammar rule. + /// Extracts all boolean property names assigned via the conditional operator + /// (?=) from a grammar rule, restricted to assignments that are + /// guaranteed to fire whenever the rule matches. A ?= at the + /// top level of the rule body is guaranteed; one inside an optional + /// (?), repeating (*/+), or alternation + /// ((A | B)) group — or reached through a NonTerminal whose + /// referenced rule itself has multiple top-level alternatives — is + /// conditional and is excluded, because IsX would be + /// true only for the subset of inputs that took that path. The + /// conditional-position filter prevents the duplicate-class + /// discriminator pass (RuleProcessor.PatternHandlers.cs) from + /// emitting unreliable when poco.IsX guards that silently drop + /// runtime instances where the keyword was not matched. /// /// The to inspect /// All available rules for recursive lookup @@ -120,42 +132,79 @@ internal static INamedElement FindNamedElement(IXmiElementCache cache, string ty internal static List QueryBooleanAssignmentProperties(TextualNotationRule rule, IReadOnlyList allRules) { var result = new List(); - CollectBooleanAssignmentProperties(rule.Alternatives.SelectMany(x => x.Elements).ToList(), allRules, result, new HashSet()); + + // A rule with multiple top-level alternatives is itself an alternation + // choice — `?=` reached through any single alternative is conditional. + var topLevelIsConditional = rule.Alternatives.Count > 1; + + foreach (var alternative in rule.Alternatives) + { + CollectBooleanAssignmentProperties(alternative.Elements, allRules, result, new HashSet(), topLevelIsConditional); + } + return result; } /// - /// Recursively collects boolean ?= assignment property names from a list of + /// Recursively collects boolean ?= assignment property names from a + /// list of . Only assignments at + /// unconditional positions ( + /// == false) are collected — see + /// for why. /// /// The elements to inspect /// All available rules for resolving NonTerminal references /// The accumulated list of boolean property names /// Set of already-visited rule names to prevent infinite recursion - internal static void CollectBooleanAssignmentProperties(IReadOnlyList elements, IReadOnlyList allRules, List result, HashSet visited) + /// + /// true when the current walk position is inside an optional / + /// repeating / alternation group (directly or transitively) so any + /// ?= reached from here cannot serve as a guaranteed discriminator. + /// + internal static void CollectBooleanAssignmentProperties(IReadOnlyList elements, IReadOnlyList allRules, List result, HashSet visited, bool isConditional) { foreach (var element in elements) { switch (element) { - case AssignmentElement { Operator: "?=" } assignment: + case AssignmentElement { Operator: "?=" } assignment when !isConditional: result.Add(assignment.Property); break; + case GroupElement groupElement: + { + var groupIsConditional = isConditional + || groupElement.IsOptional + || groupElement.IsCollection + || groupElement.Alternatives.Count > 1; + foreach (var groupAlternative in groupElement.Alternatives) { - CollectBooleanAssignmentProperties(groupAlternative.Elements, allRules, result, visited); + CollectBooleanAssignmentProperties(groupAlternative.Elements, allRules, result, visited, groupIsConditional); } break; + } + case NonTerminalElement nonTerminal: + { var referencedRule = allRules.SingleOrDefault(x => x.RuleName == nonTerminal.Name); if (referencedRule != null && visited.Add(referencedRule.RuleName)) { - CollectBooleanAssignmentProperties(referencedRule.Alternatives.SelectMany(x => x.Elements).ToList(), allRules, result, visited); + var nonTerminalIsConditional = isConditional + || nonTerminal.IsOptional + || nonTerminal.IsCollection + || referencedRule.Alternatives.Count > 1; + + foreach (var alternative in referencedRule.Alternatives) + { + CollectBooleanAssignmentProperties(alternative.Elements, allRules, result, visited, nonTerminalIsConditional); + } } break; + } } } } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs index 6144e55d..4700088b 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ElementTextualNotationBuilder.cs @@ -138,11 +138,11 @@ public static void BuildDefinitionElement(SysML2.NET.Core.POCO.Root.Elements.IEl case SysML2.NET.Core.POCO.Systems.Attributes.IAttributeDefinition pocoAttributeDefinition: AttributeDefinitionTextualNotationBuilder.BuildAttributeDefinition(pocoAttributeDefinition, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceDefinition pocoOccurrenceDefinitionOccurrenceDefinition when pocoOccurrenceDefinitionOccurrenceDefinition.IsValidForOccurrenceDefinition(writerContext): - OccurrenceDefinitionTextualNotationBuilder.BuildOccurrenceDefinition(pocoOccurrenceDefinitionOccurrenceDefinition, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceDefinition pocoOccurrenceDefinitionIndividualDefinition when pocoOccurrenceDefinitionIndividualDefinition.IsIndividual: + OccurrenceDefinitionTextualNotationBuilder.BuildIndividualDefinition(pocoOccurrenceDefinitionIndividualDefinition, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceDefinition pocoOccurrenceDefinition: - OccurrenceDefinitionTextualNotationBuilder.BuildIndividualDefinition(pocoOccurrenceDefinition, writerContext, stringBuilder); + OccurrenceDefinitionTextualNotationBuilder.BuildOccurrenceDefinition(pocoOccurrenceDefinition, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IDefinition pocoDefinition: DefinitionTextualNotationBuilder.BuildExtendedDefinition(pocoDefinition, writerContext, stringBuilder); diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs index e19ec23a..258d547f 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ReferenceUsageTextualNotationBuilder.cs @@ -389,11 +389,11 @@ public static void BuildReferenceUsage(SysML2.NET.Core.POCO.Systems.DefinitionAn { switch (poco) { - case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage pocoUsageRefPrefix when pocoUsageRefPrefix.IsDerived: - UsageTextualNotationBuilder.BuildRefPrefix(pocoUsageRefPrefix, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage pocoUsageEndUsagePrefix when pocoUsageEndUsagePrefix.IsEnd: + UsageTextualNotationBuilder.BuildEndUsagePrefix(pocoUsageEndUsagePrefix, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage pocoUsage: - UsageTextualNotationBuilder.BuildEndUsagePrefix(pocoUsage, writerContext, stringBuilder); + UsageTextualNotationBuilder.BuildRefPrefix(pocoUsage, writerContext, stringBuilder); break; } diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UsageTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UsageTextualNotationBuilder.cs index 4ad0db69..0f5ba1a2 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UsageTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/UsageTextualNotationBuilder.cs @@ -45,7 +45,7 @@ public static void BuildUsageElement(SysML2.NET.Core.POCO.Systems.DefinitionAndU { switch (poco) { - case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage pocoUsageNonOccurrenceUsageElement when pocoUsageNonOccurrenceUsageElement.IsEnd: + case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage pocoUsageNonOccurrenceUsageElement when pocoUsageNonOccurrenceUsageElement.IsValidForNonOccurrenceUsageElement(writerContext): BuildNonOccurrenceUsageElement(pocoUsageNonOccurrenceUsageElement, writerContext, stringBuilder); break; default: @@ -184,11 +184,11 @@ public static void BuildUnextendedUsagePrefix(SysML2.NET.Core.POCO.Systems.Defin { switch (poco) { - case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage pocoUsageBasicUsagePrefix when pocoUsageBasicUsagePrefix.IsDerived: - BuildBasicUsagePrefix(pocoUsageBasicUsagePrefix, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IUsage pocoUsageEndUsagePrefix when pocoUsageEndUsagePrefix.IsEnd: + BuildEndUsagePrefix(pocoUsageEndUsagePrefix, writerContext, stringBuilder); break; default: - BuildEndUsagePrefix(poco, writerContext, stringBuilder); + BuildBasicUsagePrefix(poco, writerContext, stringBuilder); break; } @@ -284,11 +284,11 @@ public static void BuildNonOccurrenceUsageElement(SysML2.NET.Core.POCO.Systems.D case SysML2.NET.Core.POCO.Systems.Enumerations.IEnumerationUsage pocoEnumerationUsage: EnumerationUsageTextualNotationBuilder.BuildEnumerationUsage(pocoEnumerationUsage, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage pocoReferenceUsageReferenceUsage when pocoReferenceUsageReferenceUsage.IsEnd: - ReferenceUsageTextualNotationBuilder.BuildReferenceUsage(pocoReferenceUsageReferenceUsage, writerContext, stringBuilder); + case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage pocoReferenceUsageDefaultReferenceUsage when pocoReferenceUsageDefaultReferenceUsage.IsValidForDefaultReferenceUsage(writerContext): + ReferenceUsageTextualNotationBuilder.BuildDefaultReferenceUsage(pocoReferenceUsageDefaultReferenceUsage, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage pocoReferenceUsage: - ReferenceUsageTextualNotationBuilder.BuildDefaultReferenceUsage(pocoReferenceUsage, writerContext, stringBuilder); + ReferenceUsageTextualNotationBuilder.BuildReferenceUsage(pocoReferenceUsage, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Systems.Attributes.IAttributeUsage pocoAttributeUsage: AttributeUsageTextualNotationBuilder.BuildAttributeUsage(pocoAttributeUsage, writerContext, stringBuilder); @@ -368,12 +368,12 @@ public static void BuildStructureUsageElement(SysML2.NET.Core.POCO.Systems.Defin case SysML2.NET.Core.POCO.Systems.Ports.IPortUsage pocoPortUsage: PortUsageTextualNotationBuilder.BuildPortUsage(pocoPortUsage, writerContext, stringBuilder); break; + case SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceUsage pocoOccurrenceUsageIndividualUsage when pocoOccurrenceUsageIndividualUsage.IsIndividual: + OccurrenceUsageTextualNotationBuilder.BuildIndividualUsage(pocoOccurrenceUsageIndividualUsage, writerContext, stringBuilder); + break; case SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceUsage pocoOccurrenceUsageOccurrenceUsage when pocoOccurrenceUsageOccurrenceUsage.IsValidForOccurrenceUsage(writerContext): OccurrenceUsageTextualNotationBuilder.BuildOccurrenceUsage(pocoOccurrenceUsageOccurrenceUsage, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceUsage pocoOccurrenceUsageIndividualUsage when pocoOccurrenceUsageIndividualUsage.IsValidForIndividualUsage(writerContext): - OccurrenceUsageTextualNotationBuilder.BuildIndividualUsage(pocoOccurrenceUsageIndividualUsage, writerContext, stringBuilder); - break; case SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceUsage pocoOccurrenceUsage: OccurrenceUsageTextualNotationBuilder.BuildPortionUsage(pocoOccurrenceUsage, writerContext, stringBuilder); break; @@ -497,16 +497,16 @@ public static void BuildVariantUsageElement(SysML2.NET.Core.POCO.Systems.Definit case SysML2.NET.Core.POCO.Systems.Ports.IPortUsage pocoPortUsage: PortUsageTextualNotationBuilder.BuildPortUsage(pocoPortUsage, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage pocoReferenceUsageReferenceUsage when pocoReferenceUsageReferenceUsage.IsEnd: - ReferenceUsageTextualNotationBuilder.BuildReferenceUsage(pocoReferenceUsageReferenceUsage, writerContext, stringBuilder); - break; - case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage pocoReferenceUsageVariantReference when writerContext.CursorCache.GetOrCreateCursor(pocoReferenceUsageVariantReference.Id, "ownedRelationship", pocoReferenceUsageVariantReference.OwnedRelationship).Current is SysML2.NET.Core.POCO.Core.Features.IReferenceSubsetting: + case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage pocoReferenceUsageVariantReference when pocoReferenceUsageVariantReference.IsValidForVariantReference(writerContext): ReferenceUsageTextualNotationBuilder.BuildVariantReference(pocoReferenceUsageVariantReference, writerContext, stringBuilder); break; + case SysML2.NET.Core.POCO.Systems.DefinitionAndUsage.IReferenceUsage pocoReferenceUsage: + ReferenceUsageTextualNotationBuilder.BuildReferenceUsage(pocoReferenceUsage, writerContext, stringBuilder); + break; case SysML2.NET.Core.POCO.Systems.Attributes.IAttributeUsage pocoAttributeUsage: AttributeUsageTextualNotationBuilder.BuildAttributeUsage(pocoAttributeUsage, writerContext, stringBuilder); break; - case SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceUsage pocoOccurrenceUsageIndividualUsage when pocoOccurrenceUsageIndividualUsage.IsValidForIndividualUsage(writerContext): + case SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceUsage pocoOccurrenceUsageIndividualUsage when pocoOccurrenceUsageIndividualUsage.IsIndividual: OccurrenceUsageTextualNotationBuilder.BuildIndividualUsage(pocoOccurrenceUsageIndividualUsage, writerContext, stringBuilder); break; case SysML2.NET.Core.POCO.Systems.Occurrences.IOccurrenceUsage pocoOccurrenceUsageOccurrenceUsage when pocoOccurrenceUsageOccurrenceUsage.IsValidForOccurrenceUsage(writerContext): diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/OperatorPrecedence.cs b/SysML2.NET.Serializer.TextualNotation/Writers/OperatorPrecedence.cs index 1fdd54d4..a053427f 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/OperatorPrecedence.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/OperatorPrecedence.cs @@ -223,6 +223,15 @@ internal static bool NeedsParenthesesAsOperand(IExpression outer, IExpression op var innerBucket = GetBucket(innerPrecedence); var outerBucket = GetBucket(outerPrecedence); + // Unary prefix operators (`~`, `not`, unary `+`/`-`) bind tighter than any binary + // operator and have no LHS to confuse with — they are unambiguous as operands and + // never need parenthesization, even when crossing operator-family buckets. E.g. + // `not a and b` re-parses unambiguously as `(not a) and b`. + if (innerBucket == PrecedenceBucket.Unary) + { + return false; + } + if (innerBucket != outerBucket) { return true; diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationValidationExtensions.cs b/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationValidationExtensions.cs index 9925f822..56e5f1cc 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationValidationExtensions.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationValidationExtensions.cs @@ -277,6 +277,59 @@ internal static bool IsValidForBinaryInterfacePart(this IInterfaceUsage interfac return interfaceUsage?.OwnedRelationship.OfType().Count() == 2; } + /// + /// Asserts that the is valid for the NonOccurrenceUsageElement rule. + /// NonOccurrenceUsageElement : Usage = DefaultReferenceUsage | ReferenceUsage | + /// AttributeUsage | EnumerationUsage | BindingConnectorAsUsage | SuccessionAsUsage | ExtendedUsage + /// None of these alternatives target or its + /// subclasses. The sibling rule OccurrenceUsageElement handles + /// instances (items, parts, actions, etc.). Thus the + /// runtime discriminator is purely class-based: anything that is NOT an + /// flows to the non-occurrence branch. + /// + /// The + /// The active (unused for this guard) + /// True if the usage is not an + internal static bool IsValidForNonOccurrenceUsageElement(this IUsage usage, TextualNotationWriterContext writerContext) + { + return usage is not IOccurrenceUsage; + } + + /// + /// Asserts that the is valid for the DefaultReferenceUsage rule. + /// DefaultReferenceUsage : ReferenceUsage = RefPrefix Usage — the form + /// WITHOUT the 'ref' keyword. + /// ReferenceUsage = ( EndUsagePrefix | RefPrefix ) 'ref' Usage — the form + /// WITH the 'ref' keyword, which sets to true + /// via BasicUsagePrefix's isReference ?= 'ref'. + /// Distinguishes the two by the property: + /// !IsReference means no 'ref' keyword → default form. + /// + /// The + /// The active (unused for this guard) + /// True if the reference usage has no 'ref' keyword (i.e. default form) + internal static bool IsValidForDefaultReferenceUsage(this IReferenceUsage referenceUsage, TextualNotationWriterContext writerContext) + { + return !referenceUsage.isReference; + } + + /// + /// Asserts that the is valid for the VariantReference rule. + /// VariantReference : ReferenceUsage = ownedRelationship += OwnedReferenceSubsetting + /// FeatureSpecialization* UsageBody — a reference-usage form that carries an owned + /// in its relationships. + /// The sibling alternative ReferenceUsage = ( EndUsagePrefix | RefPrefix ) 'ref' Usage + /// does not produce an at the reference-usage's own + /// relationship level, so the presence of one discriminates the variant form. + /// + /// The + /// The active (unused for this guard) + /// True if the reference usage has an owned + internal static bool IsValidForVariantReference(this IReferenceUsage referenceUsage, TextualNotationWriterContext writerContext) + { + return referenceUsage.OwnedRelationship.OfType().Any(); + } + /// /// Asserts that the is valid for the StructureUsageElement rule. /// StructureUsageElement : Usage = OccurrenceUsage | IndividualUsage | PortionUsage From 12049a227c5a6c37660b714e15fb5d09706dd1e1 Mon Sep 17 00:00:00 2001 From: atheate Date: Thu, 21 May 2026 10:26:01 +0200 Subject: [PATCH 4/5] Provides settings to emit or not parentheses --- .../HandleBarHelpers/RulesHelper.cs | 2 +- .../TextualNotationBuilderTestFixture.cs | 1 + .../ExpressionTextualNotationBuilder.cs | 2 +- .../Writers/TextualNotationWriterContext.cs | 17 +++++++++++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs b/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs index 5acd9325..6f701380 100644 --- a/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs +++ b/SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs @@ -99,7 +99,7 @@ public static void RegisterRulesHelper(this IHandlebars handlebars) if (isOwnedExpressionRule) { - writer.WriteSafeString("var operatorParensNeeded = writerContext.OperatorContextStack.Count > 0 && SysML2.NET.Serializer.TextualNotation.Writers.OperatorPrecedence.NeedsParenthesesAsOperand(writerContext.OperatorContextStack.Peek(), poco);" + Environment.NewLine); + writer.WriteSafeString("var operatorParensNeeded = writerContext.EmitOperatorParentheses && writerContext.OperatorContextStack.Count > 0 && SysML2.NET.Serializer.TextualNotation.Writers.OperatorPrecedence.NeedsParenthesesAsOperand(writerContext.OperatorContextStack.Peek(), poco);" + Environment.NewLine); writer.WriteSafeString("if (operatorParensNeeded) { stringBuilder.Append('('); }" + Environment.NewLine); } diff --git a/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationBuilderTestFixture.cs b/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationBuilderTestFixture.cs index 2374f6cc..fed9cb57 100644 --- a/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationBuilderTestFixture.cs +++ b/SysML2.NET.Serializer.TextualNotation.Tests/Writers/TextualNotationBuilderTestFixture.cs @@ -81,6 +81,7 @@ public void Verify_that_Quantities_namespace_is_deserialized_with_expected_id() public void Verify_that_textual_notation_is_produced_from_Quantities_root_namespace() { using var writerContext = new TextualNotationWriterContext(this.rootNamespace); + writerContext.EmitOperatorParentheses = false; var stringBuilder = new StringBuilder(); try diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs index 805903a4..7d9a3e79 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/AutoGenTextualNotationBuilder/ExpressionTextualNotationBuilder.cs @@ -43,7 +43,7 @@ public static partial class ExpressionTextualNotationBuilder /// The that contains the entire textual notation public static void BuildOwnedExpression(SysML2.NET.Core.POCO.Kernel.Functions.IExpression poco, TextualNotationWriterContext writerContext, StringBuilder stringBuilder) { - var operatorParensNeeded = writerContext.OperatorContextStack.Count > 0 && SysML2.NET.Serializer.TextualNotation.Writers.OperatorPrecedence.NeedsParenthesesAsOperand(writerContext.OperatorContextStack.Peek(), poco); + var operatorParensNeeded = writerContext.EmitOperatorParentheses && writerContext.OperatorContextStack.Count > 0 && SysML2.NET.Serializer.TextualNotation.Writers.OperatorPrecedence.NeedsParenthesesAsOperand(writerContext.OperatorContextStack.Peek(), poco); if (operatorParensNeeded) { stringBuilder.Append('('); } switch (poco) { diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs b/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs index 5009f86e..6cd2803d 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/TextualNotationWriterContext.cs @@ -52,8 +52,25 @@ public TextualNotationWriterContext(INamespace contextNamespace) this.ContextNamespace = contextNamespace ?? throw new ArgumentNullException(nameof(contextNamespace)); this.NameResolutionCache = new NameResolutionCache(contextNamespace); this.OperatorContextStack = new Stack(); + this.EmitOperatorParentheses = true; } + /// + /// Gets or sets a value indicating whether the writer should emit precedence-aware + /// parentheses around operator-expression operands. Defaults to true, which + /// produces the spec-canonical form (KerML §8.2.5.8.1 / SysML §8.4.3.2) where + /// nested operator expressions are wrapped in (…) to guarantee round-trip + /// fidelity against the precedence-climbing parser. + /// + /// Set to false to suppress the writer-side disambiguation parens entirely. + /// The resulting output is more compact and matches the idiomatic shorthand used + /// throughout the SysML tutorials (e.g. a and b or c), but a model whose + /// operand nesting does not align with the parser's default precedence ordering may + /// re-parse to a structurally-different AST in that mode. + /// + /// + public bool EmitOperatorParentheses { get; set; } + /// /// Gets the stack of currently-active enclosing operator expressions. The textual /// notation builder for each IOperatorExpression-typed rule pushes its From 74d8b7afdabcd57f65bab3965d9032480b8db2ae Mon Sep 17 00:00:00 2001 From: atheate Date: Thu, 21 May 2026 11:12:47 +0200 Subject: [PATCH 5/5] SQ fix --- .../Writers/NameResolutionCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SysML2.NET.Serializer.TextualNotation/Writers/NameResolutionCache.cs b/SysML2.NET.Serializer.TextualNotation/Writers/NameResolutionCache.cs index 5a1b4548..988b1682 100644 --- a/SysML2.NET.Serializer.TextualNotation/Writers/NameResolutionCache.cs +++ b/SysML2.NET.Serializer.TextualNotation/Writers/NameResolutionCache.cs @@ -540,7 +540,7 @@ private static void BuildInheritedEntries(IType type, Dictionary supertype != null && !ReferenceEquals(supertype, type))) + foreach (var supertype in supertypes.Where(s => s != null && !ReferenceEquals(s, type))) { if (supertype is INamespace supertypeAsNamespace) {