Skip to content

Commit d68b54b

Browse files
[WIP] Switch case for NonTerminalElement while multiple alternative implemented
1 parent d8638ef commit d68b54b

25 files changed

+562
-59
lines changed

SysML2.NET.CodeGenerator/Extensions/ClassExtensions.cs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,15 @@
2020

2121
namespace SysML2.NET.CodeGenerator.Extensions
2222
{
23-
using System;
24-
using System.Collections.Generic;
2523
using System.Collections.ObjectModel;
2624
using System.Linq;
2725

2826
using uml4net.Classification;
2927
using uml4net.Extensions;
30-
using uml4net.Packages;
3128
using uml4net.StructuredClassifiers;
3229

3330
/// <summary>
34-
/// Extension methods for <see cref="IClass"/> interface
31+
/// Extension methods for <see cref="IClass" /> interface
3532
/// </summary>
3633
public static class ClassExtensions
3734
{
@@ -40,10 +37,10 @@ public static class ClassExtensions
4037
/// or interface implementations EXCLUDING IsDerived
4138
/// </summary>
4239
/// <param name="class">
43-
/// The <see cref="IClass"/> from which to query the properties
40+
/// The <see cref="IClass" /> from which to query the properties
4441
/// </param>
4542
/// <returns>
46-
/// A <see cref="ReadOnlyCollection{T}"/> of <see cref="IProperty"/>
43+
/// A <see cref="ReadOnlyCollection{T}" /> of <see cref="IProperty" />
4744
/// </returns>
4845
public static ReadOnlyCollection<IProperty> QueryAllNonDerivedProperties(this IClass @class)
4946
{
@@ -59,10 +56,10 @@ public static ReadOnlyCollection<IProperty> QueryAllNonDerivedProperties(this IC
5956
/// redefined in the context of the current class
6057
/// </summary>
6158
/// <param name="class">
62-
/// The <see cref="IClass"/> from which to query the properties
59+
/// The <see cref="IClass" /> from which to query the properties
6360
/// </param>
6461
/// <returns>
65-
/// A <see cref="ReadOnlyCollection{T}"/> of <see cref="IProperty"/>
62+
/// A <see cref="ReadOnlyCollection{T}" /> of <see cref="IProperty" />
6663
/// </returns>
6764
public static ReadOnlyCollection<IProperty> QueryAllNonDerivedNonRedefinedProperties(this IClass @class)
6865
{
@@ -78,7 +75,7 @@ public static ReadOnlyCollection<IProperty> QueryAllNonDerivedNonRedefinedProper
7875
/// Counts and returns to amount of non derived properties
7976
/// </summary>
8077
/// <param name="class">
81-
/// The subject <see cref="IClass"/>
78+
/// The subject <see cref="IClass" />
8279
/// </param>
8380
/// <returns>
8481
/// the amount of non derived properties
@@ -92,7 +89,7 @@ public static int CountAllNonDerivedProperties(this IClass @class)
9289
/// Counts and returns to amount of non derived properties
9390
/// </summary>
9491
/// <param name="class">
95-
/// The subject <see cref="IClass"/>
92+
/// The subject <see cref="IClass" />
9693
/// </param>
9794
/// <returns>
9895
/// the amount of non derived properties
@@ -103,20 +100,36 @@ public static int CountAllNonDerivedNonRedefinedProperties(this IClass @class)
103100
}
104101

105102
/// <summary>
106-
/// Query the name of the internal interface to implement for an <see cref="IClass"/>
103+
/// Query the name of the internal interface to implement for an <see cref="IClass" />
107104
/// </summary>
108-
/// <param name="umlClass">The <see cref="IClass"/></param>
105+
/// <param name="umlClass">The <see cref="IClass" /></param>
109106
/// <returns>The name of the internal interface to implement, if any</returns>
110107
public static string QueryInternalInterfaceName(this IClass umlClass)
111108
{
112109
var classifiers = umlClass.QueryAllGeneralClassifiers();
113-
110+
114111
if (classifiers.Any(x => x.Name == "Relationship"))
115112
{
116113
return "IContainedRelationship";
117114
}
118-
115+
119116
return classifiers.Any(x => x.Name == "Element") ? "IContainedElement" : string.Empty;
120117
}
118+
119+
/// <summary>
120+
/// Asserts that an <see cref="IClass" /> is a subclass of another
121+
/// </summary>
122+
/// <param name="umlClass">The <see cref="IClass" /> to check</param>
123+
/// <param name="potentialSuperClass">
124+
/// The <see cref="IClass" /> that is potentially a super class of
125+
/// <paramref name="umlClass" />
126+
/// </param>
127+
/// <returns>
128+
/// True if the <paramref name="potentialSuperClass" /> is a super class of the <paramref name="umlClass" />
129+
/// </returns>
130+
public static bool QueryIsSubclassOf(this IClass umlClass, IClass potentialSuperClass)
131+
{
132+
return umlClass.QueryAllGeneralClassifiers().Contains(potentialSuperClass);
133+
}
121134
}
122135
}

SysML2.NET.CodeGenerator/HandleBarHelpers/RulesHelper.cs

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace SysML2.NET.CodeGenerator.HandleBarHelpers
2929
using SysML2.NET.CodeGenerator.Extensions;
3030
using SysML2.NET.CodeGenerator.Grammar.Model;
3131

32+
using uml4net;
3233
using uml4net.Classification;
3334
using uml4net.CommonStructure;
3435
using uml4net.Extensions;
@@ -164,7 +165,14 @@ private static void ProcessAlternatives(EncodedTextWriter writer, IClass umlClas
164165

165166
if(types.Count == 1)
166167
{
167-
ProcessUnitypedAlternativesWithOneElement(writer, umlClass, alternatives, ruleGenerationContext);
168+
if (ruleGenerationContext.CallerRule is not AssignmentElement)
169+
{
170+
ProcessUnitypedAlternativesWithOneElement(writer, umlClass, alternatives, ruleGenerationContext);
171+
}
172+
else
173+
{
174+
writer.WriteSafeString($"throw new System.NotSupportedException(\"Multiple alternatives with only not implemented yet for caller as AssignmentElement\");");
175+
}
168176
}
169177
else
170178
{
@@ -186,13 +194,81 @@ private static void ProcessUnitypedAlternativesWithOneElement(EncodedTextWriter
186194
{
187195
case TerminalElement terminalElement:
188196
writer.WriteSafeString($"stringBuilder.Append(\" {terminalElement.Value} \");");
197+
break;
198+
case NonTerminalElement:
199+
var nonTerminalElements = alternatives.SelectMany(x => x.Elements).OfType<NonTerminalElement>().ToList();
200+
var mappedNonTerminalElements = OrderElementsByInheritance(nonTerminalElements, umlClass.Cache, ruleGenerationContext);
201+
202+
if (mappedNonTerminalElements.Select(x => x.UmlClass).Distinct().Count() != mappedNonTerminalElements.Count)
203+
{
204+
writer.WriteSafeString("throw new System.NotSupportedException(\"Multiple alternatives with same referenced rule type not implemented yet\");");
205+
break;
206+
}
207+
208+
writer.WriteSafeString($"switch(poco){Environment.NewLine}");
209+
writer.WriteSafeString("{");
210+
211+
foreach (var orderedNonTerminalElement in mappedNonTerminalElements)
212+
{
213+
if (orderedNonTerminalElement.UmlClass == ruleGenerationContext.NamedElementToGenerate)
214+
{
215+
writer.WriteSafeString($"default:{Environment.NewLine}");
216+
ProcessNonTerminalElement(writer, orderedNonTerminalElement.UmlClass, orderedNonTerminalElement.RuleElement, "poco",ruleGenerationContext);
217+
}
218+
else
219+
{
220+
writer.WriteSafeString($"case {orderedNonTerminalElement.UmlClass.QueryFullyQualifiedTypeName(targetInterface: orderedNonTerminalElement.UmlClass.IsAbstract)} poco{orderedNonTerminalElement.UmlClass.Name}:{Environment.NewLine}");
221+
ProcessNonTerminalElement(writer, orderedNonTerminalElement.UmlClass, orderedNonTerminalElement.RuleElement, $"poco{orderedNonTerminalElement.UmlClass.Name}",ruleGenerationContext);
222+
}
223+
224+
writer.WriteSafeString($"{Environment.NewLine}break;{Environment.NewLine}");
225+
}
226+
227+
writer.WriteSafeString($"}}{Environment.NewLine}");
228+
189229
break;
190230
default:
191231
writer.WriteSafeString($"throw new System.NotSupportedException(\"Multiple alternatives with only {firstRuleElement.GetType().Name} not implemented yet\");");
192232
break;
193233
}
194234
}
195235

236+
private static List<(NonTerminalElement RuleElement, IClass UmlClass)> OrderElementsByInheritance(List<NonTerminalElement> nonTerminalElements, IXmiElementCache cache, RuleGenerationContext ruleGenerationContext)
237+
{
238+
var mapping = new List<(NonTerminalElement RuleElement, IClass UmlClass)>();
239+
var elementClass = cache.Values.Single(x => x is IClass { Name: "Element" });
240+
241+
foreach (var nonTerminalElement in nonTerminalElements)
242+
{
243+
var referencedRule = ruleGenerationContext.AllRules.Single(x => x.RuleName == nonTerminalElement.Name);
244+
var referencedClassName = referencedRule.TargetElementName ?? referencedRule.RuleName;
245+
var referencedClass =(IClass)(cache.Values.SingleOrDefault(x => x is IClass umlClass && umlClass.Name == referencedClassName)?? elementClass);
246+
mapping.Add((nonTerminalElement, referencedClass));
247+
}
248+
249+
mapping.Sort((a, b) =>
250+
{
251+
if (a.UmlClass == ruleGenerationContext.NamedElementToGenerate)
252+
{
253+
return 1;
254+
}
255+
256+
if (a.UmlClass == b.UmlClass)
257+
{
258+
return 0;
259+
}
260+
261+
if (a.UmlClass.QueryIsSubclassOf(b.UmlClass))
262+
{
263+
return -1;
264+
}
265+
266+
return b.UmlClass.QueryIsSubclassOf(a.UmlClass) ? 1 : 0;
267+
});
268+
269+
return mapping;
270+
}
271+
196272
/// <summary>
197273
/// Declares all required iterator for all <see cref="RuleElement"/> present inside an <see cref="Alternatives"/>
198274
/// </summary>

SysML2.NET/TextualNotation/AutoGenTextualNotationBuilder/ActionUsageTextualNotationBuilder.cs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,34 @@ public static void BuildActionUsageDeclaration(SysML2.NET.Core.POCO.Systems.Acti
5555
/// <param name="stringBuilder">The <see cref="StringBuilder" /> that contains the entire textual notation</param>
5656
public static void BuildActionNode(SysML2.NET.Core.POCO.Systems.Actions.IActionUsage poco, StringBuilder stringBuilder)
5757
{
58-
throw new System.NotSupportedException("Multiple alternatives with only NonTerminalElement not implemented yet");
58+
switch (poco)
59+
{
60+
case SysML2.NET.Core.POCO.Systems.Actions.IControlNode pocoControlNode:
61+
ControlNodeTextualNotationBuilder.BuildControlNode(pocoControlNode, stringBuilder);
62+
break;
63+
case SysML2.NET.Core.POCO.Systems.Actions.SendActionUsage pocoSendActionUsage:
64+
SendActionUsageTextualNotationBuilder.BuildSendNode(pocoSendActionUsage, stringBuilder);
65+
break;
66+
case SysML2.NET.Core.POCO.Systems.Actions.AcceptActionUsage pocoAcceptActionUsage:
67+
AcceptActionUsageTextualNotationBuilder.BuildAcceptNode(pocoAcceptActionUsage, stringBuilder);
68+
break;
69+
case SysML2.NET.Core.POCO.Systems.Actions.AssignmentActionUsage pocoAssignmentActionUsage:
70+
AssignmentActionUsageTextualNotationBuilder.BuildAssignmentNode(pocoAssignmentActionUsage, stringBuilder);
71+
break;
72+
case SysML2.NET.Core.POCO.Systems.Actions.TerminateActionUsage pocoTerminateActionUsage:
73+
TerminateActionUsageTextualNotationBuilder.BuildTerminateNode(pocoTerminateActionUsage, stringBuilder);
74+
break;
75+
case SysML2.NET.Core.POCO.Systems.Actions.IfActionUsage pocoIfActionUsage:
76+
IfActionUsageTextualNotationBuilder.BuildIfNode(pocoIfActionUsage, stringBuilder);
77+
break;
78+
case SysML2.NET.Core.POCO.Systems.Actions.WhileLoopActionUsage pocoWhileLoopActionUsage:
79+
WhileLoopActionUsageTextualNotationBuilder.BuildWhileLoopNode(pocoWhileLoopActionUsage, stringBuilder);
80+
break;
81+
case SysML2.NET.Core.POCO.Systems.Actions.ForLoopActionUsage pocoForLoopActionUsage:
82+
ForLoopActionUsageTextualNotationBuilder.BuildForLoopNode(pocoForLoopActionUsage, stringBuilder);
83+
break;
84+
}
85+
5986
}
6087

6188
/// <summary>
@@ -176,7 +203,25 @@ public static void BuildEmptyActionUsage(SysML2.NET.Core.POCO.Systems.Actions.IA
176203
/// <param name="stringBuilder">The <see cref="StringBuilder" /> that contains the entire textual notation</param>
177204
public static void BuildEffectBehaviorUsage(SysML2.NET.Core.POCO.Systems.Actions.IActionUsage poco, StringBuilder stringBuilder)
178205
{
179-
throw new System.NotSupportedException("Multiple alternatives with only NonTerminalElement not implemented yet");
206+
switch (poco)
207+
{
208+
case SysML2.NET.Core.POCO.Systems.Actions.PerformActionUsage pocoPerformActionUsage:
209+
PerformActionUsageTextualNotationBuilder.BuildTransitionPerformActionUsage(pocoPerformActionUsage, stringBuilder);
210+
break;
211+
case SysML2.NET.Core.POCO.Systems.Actions.AcceptActionUsage pocoAcceptActionUsage:
212+
AcceptActionUsageTextualNotationBuilder.BuildTransitionAcceptActionUsage(pocoAcceptActionUsage, stringBuilder);
213+
break;
214+
case SysML2.NET.Core.POCO.Systems.Actions.SendActionUsage pocoSendActionUsage:
215+
SendActionUsageTextualNotationBuilder.BuildTransitionSendActionUsage(pocoSendActionUsage, stringBuilder);
216+
break;
217+
case SysML2.NET.Core.POCO.Systems.Actions.AssignmentActionUsage pocoAssignmentActionUsage:
218+
AssignmentActionUsageTextualNotationBuilder.BuildTransitionAssignmentActionUsage(pocoAssignmentActionUsage, stringBuilder);
219+
break;
220+
default:
221+
BuildEmptyActionUsage(poco, stringBuilder);
222+
break;
223+
}
224+
180225
}
181226

182227
/// <summary>

SysML2.NET/TextualNotation/AutoGenTextualNotationBuilder/AnnotatingElementTextualNotationBuilder.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,22 @@ public static partial class AnnotatingElementTextualNotationBuilder
4242
/// <param name="stringBuilder">The <see cref="StringBuilder" /> that contains the entire textual notation</param>
4343
public static void BuildAnnotatingElement(SysML2.NET.Core.POCO.Root.Annotations.IAnnotatingElement poco, StringBuilder stringBuilder)
4444
{
45-
throw new System.NotSupportedException("Multiple alternatives with only NonTerminalElement not implemented yet");
45+
switch (poco)
46+
{
47+
case SysML2.NET.Core.POCO.Root.Annotations.Documentation pocoDocumentation:
48+
DocumentationTextualNotationBuilder.BuildDocumentation(pocoDocumentation, stringBuilder);
49+
break;
50+
case SysML2.NET.Core.POCO.Root.Annotations.Comment pocoComment:
51+
CommentTextualNotationBuilder.BuildComment(pocoComment, stringBuilder);
52+
break;
53+
case SysML2.NET.Core.POCO.Root.Annotations.TextualRepresentation pocoTextualRepresentation:
54+
TextualRepresentationTextualNotationBuilder.BuildTextualRepresentation(pocoTextualRepresentation, stringBuilder);
55+
break;
56+
case SysML2.NET.Core.POCO.Kernel.Metadata.MetadataFeature pocoMetadataFeature:
57+
MetadataFeatureTextualNotationBuilder.BuildMetadataFeature(pocoMetadataFeature, stringBuilder);
58+
break;
59+
}
60+
4661
}
4762
}
4863
}

SysML2.NET/TextualNotation/AutoGenTextualNotationBuilder/ClassifierTextualNotationBuilder.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,16 @@ public static void BuildClassifierDeclaration(SysML2.NET.Core.POCO.Core.Classifi
9292
stringBuilder.Append(' ');
9393
}
9494

95-
throw new System.NotSupportedException("Multiple alternatives with only NonTerminalElement not implemented yet");
95+
switch (poco)
96+
{
97+
case SysML2.NET.Core.POCO.Core.Types.Type pocoType:
98+
TypeTextualNotationBuilder.BuildConjugationPart(pocoType, stringBuilder);
99+
break;
100+
default:
101+
BuildSuperclassingPart(poco, stringBuilder);
102+
break;
103+
}
104+
96105
TypeTextualNotationBuilder.BuildTypeRelationshipPart(poco, stringBuilder);
97106

98107
}

SysML2.NET/TextualNotation/AutoGenTextualNotationBuilder/ConnectionUsageTextualNotationBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public static partial class ConnectionUsageTextualNotationBuilder
4242
/// <param name="stringBuilder">The <see cref="StringBuilder" /> that contains the entire textual notation</param>
4343
public static void BuildConnectorPart(SysML2.NET.Core.POCO.Systems.Connections.IConnectionUsage poco, StringBuilder stringBuilder)
4444
{
45-
throw new System.NotSupportedException("Multiple alternatives with only NonTerminalElement not implemented yet");
45+
throw new System.NotSupportedException("Multiple alternatives with same referenced rule type not implemented yet");
4646
}
4747

4848
/// <summary>

SysML2.NET/TextualNotation/AutoGenTextualNotationBuilder/ConnectorTextualNotationBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public static partial class ConnectorTextualNotationBuilder
4242
/// <param name="stringBuilder">The <see cref="StringBuilder" /> that contains the entire textual notation</param>
4343
public static void BuildConnectorDeclaration(SysML2.NET.Core.POCO.Kernel.Connectors.IConnector poco, StringBuilder stringBuilder)
4444
{
45-
throw new System.NotSupportedException("Multiple alternatives with only NonTerminalElement not implemented yet");
45+
throw new System.NotSupportedException("Multiple alternatives with same referenced rule type not implemented yet");
4646
}
4747

4848
/// <summary>

SysML2.NET/TextualNotation/AutoGenTextualNotationBuilder/ControlNodeTextualNotationBuilder.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,22 @@ public static partial class ControlNodeTextualNotationBuilder
4242
/// <param name="stringBuilder">The <see cref="StringBuilder" /> that contains the entire textual notation</param>
4343
public static void BuildControlNode(SysML2.NET.Core.POCO.Systems.Actions.IControlNode poco, StringBuilder stringBuilder)
4444
{
45-
throw new System.NotSupportedException("Multiple alternatives with only NonTerminalElement not implemented yet");
45+
switch (poco)
46+
{
47+
case SysML2.NET.Core.POCO.Systems.Actions.MergeNode pocoMergeNode:
48+
MergeNodeTextualNotationBuilder.BuildMergeNode(pocoMergeNode, stringBuilder);
49+
break;
50+
case SysML2.NET.Core.POCO.Systems.Actions.DecisionNode pocoDecisionNode:
51+
DecisionNodeTextualNotationBuilder.BuildDecisionNode(pocoDecisionNode, stringBuilder);
52+
break;
53+
case SysML2.NET.Core.POCO.Systems.Actions.JoinNode pocoJoinNode:
54+
JoinNodeTextualNotationBuilder.BuildJoinNode(pocoJoinNode, stringBuilder);
55+
break;
56+
case SysML2.NET.Core.POCO.Systems.Actions.ForkNode pocoForkNode:
57+
ForkNodeTextualNotationBuilder.BuildForkNode(pocoForkNode, stringBuilder);
58+
break;
59+
}
60+
4661
}
4762
}
4863
}

0 commit comments

Comments
 (0)