Skip to content

Commit 5451517

Browse files
[Implement] Xmi Serializer and update DeSerializer to keep track of source file an Element was sourced from; fixes #56
1 parent 813e221 commit 5451517

File tree

403 files changed

+314318
-7632
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

403 files changed

+314318
-7632
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,4 @@ MigrationBackup/
355355
# WinMerge bak files
356356
*.bak
357357
/switcher.json
358+
/.claude/settings.local.json

CLAUDE.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ Test framework: **NUnit**. Test classes use `[TestFixture]` and `[Test]` attribu
3131

3232
## Architecture
3333

34+
### Code Generation
35+
36+
- favour duplicated code in codegeneration to have staticaly defined methods that provide performance over reflection based code.
37+
- code generation is done by processing the UML model and creating handlebars templates
38+
3439
### Code Generation Pipeline
3540

3641
Most code in this repo is **auto-generated** — files marked `THIS IS AN AUTOMATICALLY GENERATED FILE. ANY MANUAL CHANGES WILL BE OVERWRITTEN!` must not be edited directly.
@@ -104,3 +109,8 @@ Auto-generated DTOs use structured namespaces reflecting the KerML/SysML package
104109
- CI: GitHub Actions (`CodeQuality.yml`) — builds, tests, and runs SonarQube analysis
105110
- License: Apache 2.0 (code), LGPL v3.0 (metamodel files)
106111
- To add a new metaclass: update the UML XMI source files, then run the code generators — do not manually create AutoGen files
112+
113+
## Quality rules
114+
115+
- Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance
116+
- Use 'StringBuilder.Append(char)' instead of 'StringBuilder.Append(string)' when the input is a constant unit string

SysML2.NET.CodeGenerator.Tests/Expected/UML/Core/AutoGenEnumProvider/TransitionFeatureKindProvider.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,48 @@ public static TransitionFeatureKind Parse(ReadOnlySpan<char> value)
7373
throw new ArgumentException($"'{new string(value)}' is not a valid TransitionFeatureKind", nameof(value));
7474
}
7575

76+
/// <summary>
77+
/// Tries to parse the <see cref="ReadOnlySpan{Char}"/> to a <see cref="TransitionFeatureKind"/>
78+
/// </summary>
79+
/// <param name="value">
80+
/// The <see cref="ReadOnlySpan{Char}"/> that is to be parsed
81+
/// </param>
82+
/// <param name="result">
83+
/// When this method returns, contains the <see cref="TransitionFeatureKind"/> value equivalent
84+
/// to the span, if the conversion succeeded, or <c>default</c> if the conversion failed.
85+
/// </param>
86+
/// <returns>
87+
/// <c>true</c> if <paramref name="value"/> was converted successfully; otherwise, <c>false</c>.
88+
/// </returns>
89+
/// <remarks>
90+
/// This method is suited for string parsing
91+
/// There are zero allocations, no boxing, Fast short-circuit evaluation
92+
/// JIT friendly
93+
/// </remarks>
94+
public static bool TryParse(ReadOnlySpan<char> value, out TransitionFeatureKind result)
95+
{
96+
if (value.Length == 7 && value.Equals("trigger".AsSpan(), StringComparison.OrdinalIgnoreCase))
97+
{
98+
result = TransitionFeatureKind.Trigger;
99+
return true;
100+
}
101+
102+
if (value.Length == 5 && value.Equals("guard".AsSpan(), StringComparison.OrdinalIgnoreCase))
103+
{
104+
result = TransitionFeatureKind.Guard;
105+
return true;
106+
}
107+
108+
if (value.Length == 6 && value.Equals("effect".AsSpan(), StringComparison.OrdinalIgnoreCase))
109+
{
110+
result = TransitionFeatureKind.Effect;
111+
return true;
112+
}
113+
114+
result = default;
115+
return false;
116+
}
117+
76118
/// <summary>
77119
/// Parses the <see cref="ReadOnlySpan{Byte}"/> to a <see cref="TransitionFeatureKind"/>
78120
/// </summary>

SysML2.NET.CodeGenerator.Tests/Expected/UML/Core/AutoGenEnumProvider/VisibilityKindProvider.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,48 @@ public static VisibilityKind Parse(ReadOnlySpan<char> value)
7373
throw new ArgumentException($"'{new string(value)}' is not a valid VisibilityKind", nameof(value));
7474
}
7575

76+
/// <summary>
77+
/// Tries to parse the <see cref="ReadOnlySpan{Char}"/> to a <see cref="VisibilityKind"/>
78+
/// </summary>
79+
/// <param name="value">
80+
/// The <see cref="ReadOnlySpan{Char}"/> that is to be parsed
81+
/// </param>
82+
/// <param name="result">
83+
/// When this method returns, contains the <see cref="VisibilityKind"/> value equivalent
84+
/// to the span, if the conversion succeeded, or <c>default</c> if the conversion failed.
85+
/// </param>
86+
/// <returns>
87+
/// <c>true</c> if <paramref name="value"/> was converted successfully; otherwise, <c>false</c>.
88+
/// </returns>
89+
/// <remarks>
90+
/// This method is suited for string parsing
91+
/// There are zero allocations, no boxing, Fast short-circuit evaluation
92+
/// JIT friendly
93+
/// </remarks>
94+
public static bool TryParse(ReadOnlySpan<char> value, out VisibilityKind result)
95+
{
96+
if (value.Length == 7 && value.Equals("private".AsSpan(), StringComparison.OrdinalIgnoreCase))
97+
{
98+
result = VisibilityKind.Private;
99+
return true;
100+
}
101+
102+
if (value.Length == 9 && value.Equals("protected".AsSpan(), StringComparison.OrdinalIgnoreCase))
103+
{
104+
result = VisibilityKind.Protected;
105+
return true;
106+
}
107+
108+
if (value.Length == 6 && value.Equals("public".AsSpan(), StringComparison.OrdinalIgnoreCase))
109+
{
110+
result = VisibilityKind.Public;
111+
return true;
112+
}
113+
114+
result = default;
115+
return false;
116+
}
117+
76118
/// <summary>
77119
/// Parses the <see cref="ReadOnlySpan{Byte}"/> to a <see cref="VisibilityKind"/>
78120
/// </summary>

0 commit comments

Comments
 (0)