Skip to content

Commit d7eaf47

Browse files
Merge pull request #2363 from microsoft/fix/revert-to-IDictionary-and-allow-sorting
feat: Add writer settings to enable collection sorting using a comparer
2 parents 2f9a78b + 25d45ed commit d7eaf47

File tree

117 files changed

+2751
-712
lines changed

Some content is hidden

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

117 files changed

+2751
-712
lines changed

performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.json

Lines changed: 1182 additions & 1 deletion
Large diffs are not rendered by default.

src/Microsoft.OpenApi.Hidi/Extensions/OpenApiExtensibleExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ internal static class OpenApiExtensibleExtensions
1111
/// <param name="extensions">A dictionary of <see cref="IOpenApiExtension"/>.</param>
1212
/// <param name="extensionKey">The key corresponding to the <see cref="IOpenApiExtension"/>.</param>
1313
/// <returns>A <see cref="string"/> value matching the provided extensionKey. Return null when extensionKey is not found. </returns>
14-
internal static string GetExtension(this Dictionary<string, IOpenApiExtension> extensions, string extensionKey)
14+
internal static string GetExtension(this IDictionary<string, IOpenApiExtension> extensions, string extensionKey)
1515
{
1616
if (extensions.TryGetValue(extensionKey, out var value) && value is JsonNodeExtension { Node: JsonValue castValue } && castValue.TryGetValue<string>(out var stringValue))
1717
{

src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public override void Visit(OpenApiOperation operation)
7474
// Order matters. Resolve operationId.
7575
operationId = RemoveHashSuffix(operationId);
7676
if (operationTypeExtension.IsEquals("action") || operationTypeExtension.IsEquals("function"))
77-
operationId = RemoveKeyTypeSegment(operationId, operation.Parameters ?? []);
77+
operationId = RemoveKeyTypeSegment(operationId, operation.Parameters ?? new List<IOpenApiParameter>());
7878
operationId = SingularizeAndDeduplicateOperationId(operationId.SplitByChar('.'));
7979
operationId = ResolveODataCastOperationId(operationId);
8080
operationId = ResolveByRefOperationId(operationId);
@@ -142,7 +142,7 @@ private static string RemoveHashSuffix(string operationId)
142142
return s_hashSuffixRegex.Match(operationId).Value;
143143
}
144144

145-
private static string RemoveKeyTypeSegment(string operationId, List<IOpenApiParameter> parameters)
145+
private static string RemoveKeyTypeSegment(string operationId, IList<IOpenApiParameter> parameters)
146146
{
147147
var segments = operationId.SplitByChar('.');
148148
foreach (var parameter in parameters)
@@ -156,7 +156,7 @@ private static string RemoveKeyTypeSegment(string operationId, List<IOpenApiPara
156156
return string.Join('.', segments);
157157
}
158158

159-
private static void ResolveFunctionParameters(List<IOpenApiParameter> parameters)
159+
private static void ResolveFunctionParameters(IList<IOpenApiParameter> parameters)
160160
{
161161
foreach (var parameter in parameters.OfType<OpenApiParameter>().Where(static p => p.Content?.Count > 0))
162162
{

src/Microsoft.OpenApi.Hidi/StatsVisitor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public override void Visit(IOpenApiSchema schema)
2424

2525
public int HeaderCount { get; set; }
2626

27-
public override void Visit(Dictionary<string, IOpenApiHeader> headers)
27+
public override void Visit(IDictionary<string, IOpenApiHeader> headers)
2828
{
2929
HeaderCount++;
3030
}

src/Microsoft.OpenApi.Workbench/StatsVisitor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public override void Visit(IOpenApiSchema schema)
2424

2525
public int HeaderCount { get; set; }
2626

27-
public override void Visit(Dictionary<string, IOpenApiHeader> headers)
27+
public override void Visit(IDictionary<string, IOpenApiHeader> headers)
2828
{
2929
HeaderCount++;
3030
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace Microsoft.OpenApi
6+
{
7+
/// <summary>
8+
/// Dictionary extension methods
9+
/// </summary>
10+
internal static class CollectionExtensions
11+
{
12+
/// <summary>
13+
/// Returns a new dictionary with entries sorted by key using a custom comparer.
14+
/// </summary>
15+
internal static IDictionary<TKey, TValue> Sort<TKey, TValue>(
16+
this IDictionary<TKey, TValue> source,
17+
IComparer<TKey> comparer)
18+
where TKey : notnull
19+
{
20+
#if NET7_0_OR_GREATER
21+
ArgumentNullException.ThrowIfNull(nameof(source));
22+
ArgumentNullException.ThrowIfNull(nameof(comparer));
23+
#else
24+
if (source == null)
25+
throw new ArgumentNullException(nameof(source));
26+
if (comparer == null)
27+
throw new ArgumentNullException(nameof(comparer));
28+
#endif
29+
return source.OrderBy(kvp => kvp.Key, comparer)
30+
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
31+
}
32+
33+
/// <summary>
34+
/// Sorts any IEnumerable<T> using the specified comparer and returns a List</T>.
35+
/// </summary>
36+
internal static List<T> Sort<T>(this IEnumerable<T> source, IComparer<T> comparer)
37+
{
38+
#if NET7_0_OR_GREATER
39+
ArgumentNullException.ThrowIfNull(source);
40+
ArgumentNullException.ThrowIfNull(comparer);
41+
#else
42+
if (source == null)
43+
throw new ArgumentNullException(nameof(source));
44+
if (comparer == null)
45+
throw new ArgumentNullException(nameof(comparer));
46+
#endif
47+
return source.OrderBy(item => item, comparer).ToList();
48+
}
49+
}
50+
}

src/Microsoft.OpenApi/Extensions/OpenApiExtensibleExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license.
33

44
using System;
5+
using System.Collections.Generic;
56

67
namespace Microsoft.OpenApi
78
{
@@ -28,7 +29,7 @@ public static void AddExtension<T>(this T element, string name, IOpenApiExtensio
2829
throw new OpenApiException(string.Format(SRResource.ExtensionFieldNameMustBeginWithXDash, name));
2930
}
3031

31-
element.Extensions ??= [];
32+
element.Extensions ??= new Dictionary<string, IOpenApiExtension>();
3233
element.Extensions[name] = Utils.CheckArgumentNull(any);
3334
}
3435
}

src/Microsoft.OpenApi/Interfaces/IMetadataContainer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ public interface IMetadataContainer
1414
/// A collection of properties associated with the current OpenAPI element to be used by the application.
1515
/// Metadata are NOT (de)serialized with the schema and can be used for custom properties.
1616
/// </summary>
17-
Dictionary<string, object>? Metadata { get; set; }
17+
IDictionary<string, object>? Metadata { get; set; }
1818
}

src/Microsoft.OpenApi/Interfaces/IOpenApiExtensible.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ public interface IOpenApiExtensible : IOpenApiElement
1313
/// <summary>
1414
/// Specification extensions.
1515
/// </summary>
16-
Dictionary<string, IOpenApiExtension>? Extensions { get; set; }
16+
IDictionary<string, IOpenApiExtension>? Extensions { get; set; }
1717
}
1818
}

src/Microsoft.OpenApi/Interfaces/IOpenApiReadOnlyExtensible.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ public interface IOpenApiReadOnlyExtensible
1010
/// <summary>
1111
/// Specification extensions.
1212
/// </summary>
13-
Dictionary<string, IOpenApiExtension>? Extensions { get; }
13+
IDictionary<string, IOpenApiExtension>? Extensions { get; }
1414

1515
}

0 commit comments

Comments
 (0)