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
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using HotChocolate.Types.Analyzers.Models;
using Microsoft.CodeAnalysis;
Expand Down Expand Up @@ -87,17 +86,19 @@ public static bool TryGetGraphQLTypeName(

public static IMemberDescription? GetDescription(
this Compilation compilation,
ISymbol methodOrProperty,
ImmutableArray<ResolverParameter> parameters)
ISymbol symbol)
{
switch (methodOrProperty)
switch (symbol)
{
case IPropertySymbol property:
return property.GetDescription(compilation);

case IMethodSymbol method:
return method.GetDescription(compilation);

case IParameterSymbol parameter:
return parameter.GetDescription(compilation);

default:
return null;
}
Expand Down
369 changes: 200 additions & 169 deletions src/HotChocolate/Core/src/Types.Analyzers/Helpers/SymbolExtensions.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public bool TryHandle(GeneratorSyntaxContext context, [NotNullWhen(true)] out Sy
resolvers[i++] = new Resolver(
classSymbol.Name,
member,
compilation.GetDescription(member, parameters: []),
compilation.GetDescription(member),
compilation.GetDeprecationReason(member),
ResolverResultKind.Pure,
[],
Expand Down Expand Up @@ -170,15 +170,15 @@ private static Resolver CreateResolver(
parameter,
parameterKind,
compilation.CreateTypeReference(parameter),
parameter.GetDescriptionFromAttribute(),
compilation.GetDescription(parameter)?.Description,
compilation.GetDeprecationReason(parameter),
key);
}

return new Resolver(
resolverType.Name,
resolverMethod,
compilation.GetDescription(resolverMethod, parameters: resolverParameters),
compilation.GetDescription(resolverMethod),
compilation.GetDeprecationReason(resolverMethod),
resolverMethod.GetResultKind(),
resolverParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ or Accessibility.ProtectedOrInternal
resolvers[i++] = new Resolver(
classSymbol.Name,
member,
compilation.GetDescription(member, []),
compilation.GetDescription(member),
compilation.GetDeprecationReason(member),
ResolverResultKind.Pure,
[],
Expand Down Expand Up @@ -297,7 +297,7 @@ public static Resolver CreateResolver(
parameter,
parameterKind,
compilation.CreateTypeReference(parameter),
parameter.GetDescriptionFromAttribute(),
compilation.GetDescription(parameter)?.Description,
compilation.GetDeprecationReason(parameter),
key);
}
Expand All @@ -307,7 +307,7 @@ public static Resolver CreateResolver(
return new Resolver(
resolverTypeName,
resolverMethod,
compilation.GetDescription(resolverMethod, resolverParameters),
compilation.GetDescription(resolverMethod),
compilation.GetDeprecationReason(resolverMethod),
resolverMethod.GetResultKind(),
resolverParameters,
Expand Down Expand Up @@ -339,7 +339,7 @@ private static Resolver CreateNodeResolver(
parameter,
parameterKind,
compilation.CreateTypeReference(parameter),
parameter.GetDescriptionFromAttribute(),
compilation.GetDescription(parameter)?.Description,
compilation.GetDeprecationReason(parameter),
key);

Expand All @@ -363,7 +363,7 @@ private static Resolver CreateNodeResolver(
parameter,
ResolverParameterKind.Argument,
compilation.CreateTypeReference(parameter),
parameter.GetDescriptionFromAttribute(),
compilation.GetDescription(parameter)?.Description,
compilation.GetDeprecationReason(parameter),
key);
}
Expand All @@ -384,7 +384,7 @@ private static Resolver CreateNodeResolver(
return new Resolver(
resolverType.Name,
resolverMethod,
compilation.GetDescription(resolverMethod, resolverParameters),
compilation.GetDescription(resolverMethod),
compilation.GetDeprecationReason(resolverMethod),
resolverMethod.GetResultKind(),
resolverParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ private static ConnectionClassInfo Create(
new Resolver(
name,
property,
compilation.GetDescription(property, []),
compilation.GetDescription(property),
compilation.GetDeprecationReason(property),
ResolverResultKind.Pure,
[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ private static ConnectionTypeInfo Create(
new Resolver(
connectionName,
property,
compilation.GetDescription(property, []),
compilation.GetDescription(property),
compilation.GetDeprecationReason(property),
ResolverResultKind.Pure,
[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ private static EdgeTypeInfo Create(
new Resolver(
edgeName,
property,
compilation.GetDescription(property, []),
compilation.GetDescription(property),
compilation.GetDeprecationReason(property),
ResolverResultKind.Pure,
[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ public MethodDescription(
public ImmutableArray<string?> ParameterDescriptions { get; }
}

public readonly struct PropertyDescription : IMemberDescription
public readonly record struct PropertyDescription(string? Description) : IMemberDescription
{
public PropertyDescription(string? description)
{
Description = description;
}
public string? Description { get; } = Description;
}

public string? Description { get; }
public readonly record struct ParameterDescription(string? Description) : IMemberDescription
{
public string? Description { get; } = Description;
}

public interface IMemberDescription
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,11 @@ internal static partial class Query
""");

var content = snapshot.Match();
var emitted = s_description.Matches(content).Single().Groups;
Assert.Equal(
AssertFieldDocumentation(
content,
"Query and manages users.\\n\\nPlease note:\\n* Users ...\\n* Users ...\\n * Users ...\\n"
+ " * Users ...\\n\\nYou need one of the following role: Owner,\\n"
+ "Editor, use XYZ to manage permissions.",
emitted[1].Value);
+ "Editor, use XYZ to manage permissions.");
}

[Fact]
Expand Down Expand Up @@ -105,8 +104,9 @@ internal static partial class Query
""");

var content = snapshot.Match();
var emitted = s_description.Matches(content).Single().Groups;
Assert.Equal("null for the default Record.\\nSee this and\\nthis at\\nhttps://foo.com/bar/baz.", emitted[1].Value);
AssertFieldDocumentation(
content,
"null for the default Record.\\nSee this and\\nthis at\\nhttps://foo.com/bar/baz.");
}

[Fact]
Expand Down Expand Up @@ -135,8 +135,7 @@ internal static partial class Query
""");

var content = snapshot.Match();
var emitted = s_description.Matches(content).Single().Groups;
Assert.Equal("This is a parameter reference to id.", emitted[1].Value);
AssertFieldDocumentation(content, "This is a parameter reference to id.");
}

[Fact]
Expand All @@ -163,8 +162,7 @@ internal static partial class Query
""");

var content = snapshot.Match();
var emitted = s_description.Matches(content).Single().Groups;
Assert.Equal("These are some tags.", emitted[1].Value);
AssertFieldDocumentation(content, "These are some tags.");
}

[Fact]
Expand All @@ -188,7 +186,6 @@ namespace TestNamespace;
public class BaseBaseClass
{
/// <summary>Method doc.</summary>
/// <param name="baz">Parameter details.</param>
public virtual void Bar(string baz) { }
}

Expand All @@ -201,8 +198,7 @@ internal static partial class Query
""");

var content = snapshot.Match();
var emitted = s_description.Matches(content).Single().Groups;
Assert.Equal("Method doc.", emitted[1].Value);
AssertFieldDocumentation(content, "Method doc.");
}

[Fact]
Expand Down Expand Up @@ -231,8 +227,7 @@ internal static partial class Query
""");

var content = snapshot.Match();
var emitted = s_description.Matches(content).Single().Groups;
Assert.Equal("I am a test class. This should not be escaped: >", emitted[1].Value);
AssertFieldDocumentation(content, "I am a test class. This should not be escaped: >");
}

[Fact]
Expand Down Expand Up @@ -262,8 +257,7 @@ internal static partial class Query
""");

var content = snapshot.Match();
var emitted = s_description.Matches(content).Single().Groups;
Assert.Equal("Query and manages users.\\n\\n\\n**Returns:**\\nBar", emitted[1].Value);
AssertFieldDocumentation(content, "Query and manages users.\\n\\n\\n**Returns:**\\nBar");
}

[Fact]
Expand Down Expand Up @@ -295,8 +289,9 @@ internal static partial class Query
""");

var content = snapshot.Match();
var emitted = s_description.Matches(content).Single().Groups;
Assert.Equal("Query and manages users.\\n\\n\\n**Returns:**\\nBar\\n\\n**Errors:**\\n1. FOO_ERROR: Foo Error\\n2. BAR_ERROR: Bar Error", emitted[1].Value);
AssertFieldDocumentation(
content,
"Query and manages users.\\n\\n\\n**Returns:**\\nBar\\n\\n**Errors:**\\n1. FOO_ERROR: Foo Error\\n2. BAR_ERROR: Bar Error");
}

[Fact]
Expand Down Expand Up @@ -329,8 +324,9 @@ internal static partial class Query
""");

var content = snapshot.Match();
var emitted = s_description.Matches(content).Single().Groups;
Assert.Equal("Query and manages users.\\n\\n\\n**Returns:**\\nBar\\n\\n**Errors:**\\n1. FOO_ERROR: Foo Error\\n2. BAR_ERROR: Bar Error", emitted[1].Value);
AssertFieldDocumentation(
content,
"Query and manages users.\\n\\n\\n**Returns:**\\nBar\\n\\n**Errors:**\\n1. FOO_ERROR: Foo Error\\n2. BAR_ERROR: Bar Error");
}

[Fact]
Expand Down Expand Up @@ -361,10 +357,117 @@ internal static partial class Query
""");

var content = snapshot.Match();
AssertFieldDocumentation(content, "Query and manages users.\\n\\n\\n**Returns:**\\nBar");
}

[Fact]
public void When_parameter_has_inheritdoc_then_it_is_resolved()
{
var snapshot =
TestHelper.GetGeneratedSourceSnapshot(
"""
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using HotChocolate;
using HotChocolate.Types;

namespace TestNamespace;

/// <summary>
/// I am the base class.
/// </summary>
public class BaseClass
{
/// <summary>Method doc.</summary>
/// <param name="baz">Parameter details.</param>
public virtual void Bar(string baz) { }
}

public class ClassWithInheritdoc : BaseClass
{
/// <inheritdoc />
public override void Bar(string baz) { }
}

[QueryType]
internal static partial class Query
{
/// <inheritdoc cref="ClassWithInheritdoc.Bar" />
public static int Bar(string baz) => 0;
}
""");

var content = snapshot.Match();
AssertFieldDocumentation(content, "Method doc.", "Parameter details.");
}

[Fact]
public void When_class_implements_interface_and_method_has_description_then_method_parameter_description_is_used()
{
var snapshot =
TestHelper.GetGeneratedSourceSnapshot(
"""
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using HotChocolate;
using HotChocolate.Types;

namespace TestNamespace;

/// <summary>
/// I am the base class.
/// </summary>
public class BaseClass
{
/// <summary>Method doc.</summary>
/// <param name="baz">Parameter details.</param>
public virtual void Bar(string baz) { }
}

public class ClassWithInheritdoc : BaseClass
{
/// <summary>
/// I am my own method.
/// </summary>
/// <param name="baz">I am my own parameter.</param>
public override void Bar(string baz) { }
}

[QueryType]
internal static partial class Query
{
/// <inheritdoc cref="ClassWithInheritdoc.Bar" />
public static int Bar(string baz) => 0;
}
""");

var content = snapshot.Match();
AssertFieldDocumentation(content, "I am my own method.", "I am my own parameter.");
}

private static void AssertFieldDocumentation(string content, string fieldDoc, params string[] parameterDocs)
{
var emitted = s_description.Matches(content).Single().Groups;
Assert.Equal("Query and manages users.\\n\\n\\n**Returns:**\\nBar", emitted[1].Value);
Assert.Equal(fieldDoc, emitted[1].Value);
if (parameterDocs.Length > 0)
{
var paramDescriptions = s_paramDescription.Matches(content).ToArray();
Assert.Equal(parameterDocs.Length, paramDescriptions.Length);
for (var index = 0; index < paramDescriptions.Length; index++)
{
var paramDescription = paramDescriptions[index];
Assert.Equal(parameterDocs[index], paramDescription.Groups[2].Value);
}
}
}

[System.Text.RegularExpressions.GeneratedRegex("configuration.Description = \"(.*)\";")]
private static partial System.Text.RegularExpressions.Regex DescriptionExtractorRegex();

[System.Text.RegularExpressions.GeneratedRegex("(\\s+)Description = \"(.*)\",")]
private static partial System.Text.RegularExpressions.Regex ParameterDescriptionExtractorRegex();
}
Loading
Loading