Skip to content
Open
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
37 changes: 27 additions & 10 deletions samples/csharp/docfx.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
{
"metadata": [
{
"src": [
"src/*.csproj"
],
"outputFormat": "mref",
"memberLayout": "separatePages",
"output": "obj/api"
},
{
"src": [
"src/*.csproj"
],
"outputFormat": "apiPage",
"memberLayout": "separatePages",
"output": "obj/apipage"
},
{
"src": [
"src/*.csproj"
],
"dest": "api"
}
"outputFormat": "markdown",
"memberLayout": "separatePages",
"output": "obj/md"
},
],
"build": {
"content": [
{
"files": [
"api/**/*.yml",
"toc.yml"
]
}
{ "files": [ "*.{md,yml}" ]},
{ "files": [ "**/*.yml" ], "src": "obj/api", "dest": "api" },
{ "files": [ "**/*.yml" ], "src": "obj/apipage", "dest": "apipage" },
{ "files": [ "**/*.{md,yml}" ], "src": "obj/md", "dest": "md" },
],
"dest": "_site",
"output": "_site",
"template": ["default", "modern"],
"exportViewModel": true
}
}
}
3 changes: 3 additions & 0 deletions samples/csharp/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
_layout: landing
---
12 changes: 12 additions & 0 deletions samples/csharp/src/CSharp13.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace CSharp13;

// https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#allows-ref-struct
public class AllowRefStruct<T>
where T : allows ref struct
{
// Use T as a ref struct:
public void Method(scoped T p)
{
// The parameter p must follow ref safety rules
}
}
78 changes: 78 additions & 0 deletions samples/csharp/src/CSharp14.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
namespace CSharp14;

// https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14#the-field-keyword
public class FieldBackedPropertySample
{
public int FieldBackedProperty
{
get;
set => field = value;
}
}

public class SampleClass
{
public required string Value { get; init; }
}

public static class SampleClassExtensions
{
// Extension block
extension(SampleClass sample)
{
// Extension property:
public string ExtensionProperty => sample.Value;

// Extension method:
public void ExtensionMethod()
{
}
}

// Extension block for static type
extension(SampleClass)
{
// static extension method:
public static void StaticExtensionMethod()
{
}

// static extension property:
public static int StaticExtensionProperty => default;

// static user defined operator:
public static SampleClass operator +(SampleClass value1, SampleClass value2)
=> new() { Value = value1.Value + value2.Value };
}
}

public class UserDefinedCompoundAssignmentOperatorsSample
{
public int? Value { get; set; }

public override string? ToString() => Value?.ToString();

public void operator ++() { Value += 1; }

public void operator --() { Value -= 1; }

public void operator +=(UserDefinedCompoundAssignmentOperatorsSample c) { Value += c?.Value; }

public void operator -=(UserDefinedCompoundAssignmentOperatorsSample c) { Value -= c?.Value; }

public void operator *=(UserDefinedCompoundAssignmentOperatorsSample c) { Value *= c?.Value; }

public void operator /=(UserDefinedCompoundAssignmentOperatorsSample c) { Value /= c?.Value; }

public void operator %=(UserDefinedCompoundAssignmentOperatorsSample c) { Value %= c?.Value; }

public void operator &=(UserDefinedCompoundAssignmentOperatorsSample c) { Value &= c?.Value; }

public void operator |=(UserDefinedCompoundAssignmentOperatorsSample c) { Value |= c?.Value; }

public void operator ^=(UserDefinedCompoundAssignmentOperatorsSample c) { Value ^= c?.Value; }

public void operator <<=(int shift) { Value <<= shift; }

public void operator >>=(int shift) { Value >>= shift; }
}
8 changes: 8 additions & 0 deletions samples/csharp/toc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
- name: API Documentation
items:
- name: .NET API
href: obj/api/
- name: .NET API (apipage)
href: obj/apipage/
- name: .NET API (markdown)
href: obj/md/
7 changes: 7 additions & 0 deletions src/Docfx.Dotnet/DotnetApiCatalog.Toc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ enum TocNodeType
Method,
Event,
Operator,
Extension,
}

class TocNode
Expand Down Expand Up @@ -135,6 +136,12 @@ IEnumerable<TocNode> CreateNamedTypeToc(INamedTypeSymbol type)
{
var idExists = true;
var id = VisitorHelper.PathFriendlyId(VisitorHelper.GetId(symbol));

// TODO: Handle C# 14 Extension Members. It'll be shown on `static class` and target type of extension.
// Currently Extension symbol is skipped.
if (type.TypeKind == TypeKind.Extension)
yield break;

if (!tocNodes.TryGetValue(id, out var node))
{
idExists = false;
Expand Down
3 changes: 2 additions & 1 deletion src/Docfx.Dotnet/ManagedReference/Models/MemberType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ public enum MemberType
Operator,
Container,
AttachedEvent,
AttachedProperty
AttachedProperty,
Extension,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Docfx.DataContracts.ManagedReference;

#nullable enable

namespace Docfx.Dotnet;

internal class ResolveExtensionMember : IResolverPipeline
{
public void Run(MetadataModel yaml, ResolverContext context)
{
// Remove extension from root members.
yaml.Members.RemoveAll(x => x.Type == MemberType.Extension);

// Remove extension from TocYamlViewModel items.
ProcessItem(yaml.TocYamlViewModel);
}

private static void ProcessItem(MetadataItem metadataItem)
{
if (metadataItem.IsInvalid || metadataItem.Items == null)
return;

metadataItem.Items.RemoveAll(x => x.Type == MemberType.Extension);

foreach (var item in metadataItem.Items)
ProcessItem(item);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal static class YamlMetadataResolver
new NormalizeSyntax(),
new BuildMembers(),
new SetDerivedClass(),
new ResolveExtensionMember(),
new BuildToc()
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,15 @@ s is not INamedTypeSymbol
}
}

AddReference(symbol);
if (symbol.IsExtension)
{
// Currently extension symbol is skipped and reference is not added.
// TODO: Handle C# 14 Extension Member definition.
}
else
{
AddReference(symbol);
}

item.Attributes = GetAttributeInfo(symbol.GetAttributes());

Expand Down
2 changes: 2 additions & 0 deletions src/Docfx.Dotnet/ManagedReference/Visitors/VisitorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ public static MemberType GetMemberTypeFromTypeKind(TypeKind typeKind)
return MemberType.Struct;
case TypeKind.Delegate:
return MemberType.Delegate;
case TypeKind.Extension:
return MemberType.Extension;
default:
return MemberType.Default;
}
Expand Down
14 changes: 12 additions & 2 deletions src/Docfx.Dotnet/YamlViewModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ internal static class YamlViewModelExtensions
{
public static bool IsPageLevel(this MemberType type)
{
return type == MemberType.Namespace || type == MemberType.Class || type == MemberType.Enum || type == MemberType.Delegate || type == MemberType.Interface || type == MemberType.Struct;
return type is MemberType.Namespace
or MemberType.Class
or MemberType.Enum
or MemberType.Delegate
or MemberType.Interface
or MemberType.Struct
or MemberType.Extension;
}

/// <summary>
Expand All @@ -22,7 +28,11 @@ public static bool IsPageLevel(this MemberType type)
/// <returns></returns>
public static bool AllowMultipleItems(this MemberType type)
{
return type == MemberType.Class || type == MemberType.Enum || type == MemberType.Delegate || type == MemberType.Interface || type == MemberType.Struct;
return type is MemberType.Class
or MemberType.Enum
or MemberType.Delegate
or MemberType.Interface
or MemberType.Struct;
}

public static MetadataItem ShrinkToSimpleToc(this MetadataItem item)
Expand Down