Skip to content

Commit 3c84d28

Browse files
Handle null case for the importedMembershipOperation and provided answer about PR's comments
1 parent a7afbf8 commit 3c84d28

4 files changed

Lines changed: 72 additions & 7 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// -------------------------------------------------------------------------------------------------
2+
// <copyright file="NullableStringEqualityComparer.cs" company="Starion Group S.A.">
3+
//
4+
// Copyright 2022-2026 Starion Group S.A.
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// </copyright>
19+
// ------------------------------------------------------------------------------------------------
20+
21+
namespace SysML2.NET.Comparer
22+
{
23+
using System;
24+
using System.Collections.Generic;
25+
26+
/// <summary>
27+
/// Provides equality comparison for string, handling null case
28+
/// </summary>
29+
public sealed class NullSafeStringComparer : IEqualityComparer<string>
30+
{
31+
/// <summary>Determines whether the specified objects are equal.</summary>
32+
/// <param name="x">The first object of type <paramref name="T" /> to compare.</param>
33+
/// <param name="y">The second object of type <paramref name="T" /> to compare.</param>
34+
/// <returns>
35+
/// <see langword="true" /> if the specified objects are equal; otherwise, <see langword="false" />.</returns>
36+
public bool Equals(string x, string y)
37+
{
38+
if (x == null && y == null)
39+
{
40+
return true;
41+
}
42+
43+
if (x == null || y == null)
44+
{
45+
return false;
46+
}
47+
48+
return string.Equals(x, y, StringComparison.Ordinal);
49+
}
50+
51+
/// <summary>Returns a hash code for the specified object.</summary>
52+
/// <param name="obj">The <see cref="T:System.Object" /> for which a hash code is to be returned.</param>
53+
/// <returns>A hash code for the specified object.</returns>
54+
/// <exception cref="T:System.ArgumentNullException">The type of <paramref name="obj" /> is a reference type and <paramref name="obj" /> is <see langword="null" />.</exception>
55+
public int GetHashCode(string? obj)
56+
{
57+
return obj?.GetHashCode() ?? 0;
58+
}
59+
60+
/// <summary>
61+
/// Gets the instance of the <see cref="NullSafeStringComparer"/>
62+
/// </summary>
63+
public static readonly NullSafeStringComparer Instance = new();
64+
}
65+
}

SysML2.NET/Extend/ElementExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ internal static string ComputeEscapedNameOperation(this IElement elementSubject)
253253
return null;
254254
}
255255

256-
return targetName.QueryIsBasicName() ? targetName : targetName.ToUnrestrictedName();
256+
return targetName.QueryIsValidBasicName() ? targetName : targetName.ToUnrestrictedName();
257257
}
258258

259259
/// <summary>

SysML2.NET/Extend/NamespaceExtensions.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ namespace SysML2.NET.Core.POCO.Root.Namespaces
2525
using System.Collections.Generic;
2626
using System.Linq;
2727

28+
using SysML2.NET.Comparer;
2829
using SysML2.NET.Core.Root.Namespaces;
2930
using SysML2.NET.Core.POCO.Root.Annotations;
3031
using SysML2.NET.Core.POCO.Root.Elements;
@@ -213,18 +214,17 @@ internal static List<IMembership> ComputeImportedMembershipsOperation(this IName
213214

214215
var ownedMembershipNames = namespaceSubject.ownedMembership
215216
.Select(m => m.MemberName)
216-
.Where(name => name != null)
217-
.ToHashSet(StringComparer.Ordinal);
217+
.ToHashSet(NullSafeStringComparer.Instance);
218218

219219
var importedMembershipsNameFrequency = importedMemberships
220-
.GroupBy(x => x.MemberName, StringComparer.Ordinal)
221-
.ToFrozenDictionary(g => g.Key, g => g.Count(), StringComparer.Ordinal);
220+
.GroupBy(x => x.MemberName, NullSafeStringComparer.Instance)
221+
.ToFrozenDictionary(g => g.Key, g => g.Count(), NullSafeStringComparer.Instance);
222222

223223
var nonCollidingImportedMemberships = importedMemberships.Where(x =>
224224
{
225225
var name = x.MemberName;
226226

227-
return !string.IsNullOrWhiteSpace(name) && !ownedMembershipNames.Contains(name) && (!importedMembershipsNameFrequency.TryGetValue(name, out var frequency) || frequency <= 1);
227+
return !ownedMembershipNames.Contains(name) && (!importedMembershipsNameFrequency.TryGetValue(name, out var frequency) || frequency <= 1);
228228
}).ToList();
229229

230230
return nonCollidingImportedMemberships;

SysML2.NET/Extensions/StringExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public static class StringExtensions
3535
/// </summary>
3636
/// <param name="name">The name to verifies</param>
3737
/// <returns><c>true</c> if the name is a basic name, <c>false</c> otherwise</returns>
38-
public static bool QueryIsBasicName(this string name)
38+
public static bool QueryIsValidBasicName(this string name)
3939
{
4040
return Regex.IsMatch(name, "^[a-zA-Z_][a-zA-Z0-9_]*$") && !Keywords.ReservedKeywords.Contains(name);
4141
}

0 commit comments

Comments
 (0)