Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Docfx.Build/ApiPage/ApiPageProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace Docfx.Build.ApiPage;

class ApiPageDocumentProcessor(IMarkdownService markdownService) : IDocumentProcessor
{
private static IDeserializer deserializer = new DeserializerBuilder().WithAttemptingUnquotedStringTypeDeserialization().Build();

IEnumerable<IDocumentBuildStep> IDocumentProcessor.BuildSteps => Array.Empty<IDocumentBuildStep>();
void IDocumentProcessor.UpdateHref(FileModel model, IDocumentBuildContext context) { }

Expand All @@ -35,7 +37,6 @@ public ProcessingPriority GetProcessingPriority(FileAndType file)

public FileModel Load(FileAndType file, ImmutableDictionary<string, object> metadata)
{
var deserializer = new DeserializerBuilder().WithAttemptingUnquotedStringTypeDeserialization().Build();
var yml = EnvironmentContext.FileAbstractLayer.ReadAllText(file.File);
var json = JsonSerializer.Serialize(deserializer.Deserialize<object>(yml));
var data = JsonSerializer.Deserialize<ApiPage>(json, ApiPage.JsonSerializerOptions);
Expand Down
12 changes: 6 additions & 6 deletions src/Docfx.Common/YamlUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ namespace Docfx.Common;

public static class YamlUtility
{
private static readonly ThreadLocal<YamlSerializer> serializer = new(() => new YamlSerializer(SerializationOptions.DisableAliases));
private static readonly ThreadLocal<YamlDeserializer> deserializer = new(() => new YamlDeserializer(ignoreUnmatched: true));
private static readonly YamlSerializer serializer = new(SerializationOptions.DisableAliases);
private static readonly YamlDeserializer deserializer = new(ignoreUnmatched: true);

public static void Serialize(TextWriter writer, object graph)
{
Expand All @@ -30,7 +30,7 @@ public static void Serialize(TextWriter writer, object graph, string comments)
writer.WriteLine(comment.TrimEnd('\r'));
}
}
serializer.Value.Serialize(writer, graph);
serializer.Serialize(writer, graph);
}

public static void Serialize(string path, object graph, string comments)
Expand All @@ -41,7 +41,7 @@ public static void Serialize(string path, object graph, string comments)

public static T Deserialize<T>(TextReader reader)
{
return deserializer.Value.Deserialize<T>(reader);
return deserializer.Deserialize<T>(reader);
}

public static T Deserialize<T>(string path)
Expand All @@ -55,8 +55,8 @@ public static T ConvertTo<T>(object obj)
var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
{
serializer.Value.Serialize(writer, obj);
serializer.Serialize(writer, obj);
}
return deserializer.Value.Deserialize<T>(new StringReader(sb.ToString()));
return deserializer.Deserialize<T>(new StringReader(sb.ToString()));
}
}
5 changes: 3 additions & 2 deletions src/Docfx.Dotnet/DotnetApiCatalog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ namespace Docfx.Dotnet;
/// </summary>
public static partial class DotnetApiCatalog
{
private static IDeserializer deserializer = new DeserializerBuilder().WithAttemptingUnquotedStringTypeDeserialization().Build();

/// <summary>
/// Generates metadata reference YAML files using docfx.json config.
/// </summary>
Expand Down Expand Up @@ -96,13 +98,12 @@ void WriteMarkdown(string outputFolder, string id, Build.ApiPage.ApiPage apiPage
break;

case MetadataOutputFormat.ApiPage:
var serializer = new DeserializerBuilder().WithAttemptingUnquotedStringTypeDeserialization().Build();
CreatePages(WriteYaml, assemblies, config, options);

void WriteYaml(string outputFolder, string id, Build.ApiPage.ApiPage apiPage)
{
var json = JsonSerializer.Serialize(apiPage, Docfx.Build.ApiPage.ApiPage.JsonSerializerOptions);
var obj = serializer.Deserialize(json);
var obj = deserializer.Deserialize(json);
YamlUtility.Serialize(Path.Combine(outputFolder, $"{id}.yml"), obj, "YamlMime:ApiPage");
}
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Concurrent;
using System.Reflection;
using System.Reflection.Emit;
using Docfx.YamlSerialization.Helpers;
Expand All @@ -20,9 +21,9 @@ public class EmitGenericCollectionNodeDeserializer : INodeDeserializer
private readonly IObjectFactory _objectFactory;
private readonly INamingConvention _enumNamingConvention;
private readonly ITypeInspector _typeDescriptor;
private readonly Dictionary<Type, Type?> _gpCache =
private readonly ConcurrentDictionary<Type, Type?> _gpCache =
new();
private readonly Dictionary<Type, Action<IParser, Type, Func<IParser, Type, object?>, object?, INamingConvention, ITypeInspector>> _actionCache =
private readonly ConcurrentDictionary<Type, Action<IParser, Type, Func<IParser, Type, object?>, object?, INamingConvention, ITypeInspector>> _actionCache =
new();

public EmitGenericCollectionNodeDeserializer(IObjectFactory objectFactory, INamingConvention enumNamingConvention, ITypeInspector typeDescriptor)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Concurrent;
using System.ComponentModel;
using System.Reflection;
using System.Reflection.Emit;
Expand All @@ -16,8 +17,8 @@ public class EmitGenericDictionaryNodeDeserializer : INodeDeserializer
private static readonly MethodInfo DeserializeHelperMethod =
typeof(EmitGenericDictionaryNodeDeserializer).GetMethod(nameof(DeserializeHelper))!;
private readonly IObjectFactory _objectFactory;
private readonly Dictionary<Type, Type[]?> _gpCache = [];
private readonly Dictionary<Tuple<Type, Type>, Action<IParser, Type, Func<IParser, Type, object?>, object?>> _actionCache = [];
private readonly ConcurrentDictionary<Type, Type[]?> _gpCache = [];
private readonly ConcurrentDictionary<Tuple<Type, Type>, Action<IParser, Type, Func<IParser, Type, object?>, object?>> _actionCache = [];

public EmitGenericDictionaryNodeDeserializer(IObjectFactory objectFactory)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Concurrent;
using System.Reflection;
using System.Reflection.Emit;

Expand All @@ -10,7 +11,7 @@ namespace Docfx.YamlSerialization.ObjectFactories;

public class DefaultEmitObjectFactory : ObjectFactoryBase
{
private readonly Dictionary<Type, Func<object>> _cache = [];
private readonly ConcurrentDictionary<Type, Func<object>> _cache = [];
private static Type[] EmptyTypes => Type.EmptyTypes;

public override object Create(Type type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
Expand Down Expand Up @@ -32,7 +33,7 @@ public class FullObjectGraphTraversalStrategy : IObjectGraphTraversalStrategy
private readonly IObjectFactory _objectFactory;

// private readonly Dictionary<Tuple<Type, Type>, Action<IPropertyDescriptor?, IObjectDescriptor, IObjectGraphVisitor, Type, Type, IObjectGraphVisitorContext, Stack<FullObjectGraphTraversalStrategy.ObjectPathSegment>, ObjectSerializer>> _behaviorCache = new();
private readonly Dictionary<Tuple<Type, Type, Type>, Action<FullObjectGraphTraversalStrategy, object, IObjectGraphVisitor, INamingConvention, IObjectGraphVisitorContext, Stack<ObjectPathSegment>, ObjectSerializer>> _traverseGenericDictionaryCache = new();
private readonly ConcurrentDictionary<Tuple<Type, Type, Type>, Action<FullObjectGraphTraversalStrategy, object, IObjectGraphVisitor, INamingConvention, IObjectGraphVisitorContext, Stack<ObjectPathSegment>, ObjectSerializer>> _traverseGenericDictionaryCache = new();

protected YamlSerializer Serializer { get; }

Expand Down
3 changes: 2 additions & 1 deletion src/Docfx.YamlSerialization/YamlSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Concurrent;
using Docfx.YamlSerialization.Helpers;
using Docfx.YamlSerialization.ObjectDescriptors;
using Docfx.YamlSerialization.ObjectGraphTraversalStrategies;
Expand Down Expand Up @@ -141,7 +142,7 @@ private IEventEmitter CreateEventEmitter()
{
return new TypeAssigningEventEmitter(
writer,
new Dictionary<Type, TagName>(),
new ConcurrentDictionary<Type, TagName>(),
quoteNecessaryStrings: false,
quoteYaml1_1Strings: false,
defaultScalarStyle: ScalarStyle.Any,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace docfx.Tests;

public partial class YamlSerializationTest
{
private static IDeserializer deserializer = new DeserializerBuilder().WithAttemptingUnquotedStringTypeDeserialization().Build();

[Theory]
[TestData<ApiPage>]
public void YamlSerializationTest_ApiPage(string path)
Expand All @@ -30,9 +32,6 @@ private static ApiPage LoadApiPage(string path)
{
path = PathHelper.ResolveTestDataPath(path);

var deserializer = new DeserializerBuilder().WithAttemptingUnquotedStringTypeDeserialization()
.Build();

// 1. Deserialize ApiPage yaml as Dictionary
// 2. Serialize to json
// 3. Deserialize as ApiPage instance
Expand All @@ -56,8 +55,6 @@ private static void ValidateApiPageRoundTrip(ApiPage model)

private static string ToYaml(ApiPage model)
{
var deserializer = new DeserializerBuilder().WithAttemptingUnquotedStringTypeDeserialization().Build();

var json = JsonSerializer.Serialize(model, Docfx.Build.ApiPage.ApiPage.JsonSerializerOptions);
var obj = deserializer.Deserialize(json);

Expand All @@ -68,7 +65,6 @@ private static string ToYaml(ApiPage model)

private static ApiPage ToApiPage(string yaml)
{
var deserializer = new DeserializerBuilder().WithAttemptingUnquotedStringTypeDeserialization().Build();
var dict = deserializer.Deserialize<Dictionary<object, object>>(new StringReader(yaml));
var json = JsonSerializer.Serialize(dict);
return JsonSerializer.Deserialize<ApiPage>(json, ApiPage.JsonSerializerOptions);
Expand Down