diff --git a/src/Zomp.SyncMethodGenerator/AsyncToSyncRewriter.cs b/src/Zomp.SyncMethodGenerator/AsyncToSyncRewriter.cs
index 0b1aa26..6c0a2b2 100644
--- a/src/Zomp.SyncMethodGenerator/AsyncToSyncRewriter.cs
+++ b/src/Zomp.SyncMethodGenerator/AsyncToSyncRewriter.cs
@@ -957,6 +957,14 @@ bool RemoveType(TypeSyntax z, int index) =>
var originalName = @base.Identifier.Text;
var newName = RemoveAsync(originalName);
+ // A method which returned a task returns nothing once it is synchronized, so whatever
+ // its documentation said about the task it returned no longer describes anything. The
+ // documentation of a value which survives is left alone: it is imprecise about the task
+ // it mentions, but dropping it would say less than saying it imprecisely.
+ var returnsNothing = GetReturnType(@base.ReturnType, symbol)
+ is PredefinedTypeSyntax { Keyword.RawKind: (int)SyntaxKind.VoidKeyword }
+ or IdentifierNameSyntax { Identifier.ValueText: "void" };
+
// Documentation
var trivia = node.GetLeadingTrivia();
var newTriviaList = trivia;
@@ -982,6 +990,12 @@ bool RemoveType(TypeSyntax z, int index) =>
indicesToRemove.Add(i - 1); // preceding slashes
indicesToRemove.Add(i);
}
+ else if (returnsNothing
+ && xes.StartTag.Name.LocalName.ValueText.Equals("returns", StringComparison.Ordinal))
+ {
+ indicesToRemove.Add(i - 1); // preceding slashes
+ indicesToRemove.Add(i);
+ }
}
++i;
diff --git a/src/Zomp.SyncMethodGenerator/MethodToGenerate.cs b/src/Zomp.SyncMethodGenerator/MethodToGenerate.cs
index 90d7b2b..6094d2b 100644
--- a/src/Zomp.SyncMethodGenerator/MethodToGenerate.cs
+++ b/src/Zomp.SyncMethodGenerator/MethodToGenerate.cs
@@ -5,6 +5,8 @@
///
/// Index of the method in the source file.
/// List of namespaces this method is under.
+/// Using directives the source file declares outside its namespace.
+/// Using directives the source file declares inside its namespace.
/// True if namespace is file scoped.
/// True if this is C# 14 extension.
/// List of classes/structs/records this method belongs to starting from the outer-most class.
@@ -17,6 +19,8 @@
internal sealed record MethodToGenerate(
int Index,
EquatableArray Namespaces,
+ EquatableArray OuterUsings,
+ EquatableArray InnerUsings,
bool IsNamespaceFileScoped,
bool IsCSharp14Extension,
EquatableArray Parents,
diff --git a/src/Zomp.SyncMethodGenerator/SourceGenerationHelper.cs b/src/Zomp.SyncMethodGenerator/SourceGenerationHelper.cs
index e3d2575..bd736fb 100644
--- a/src/Zomp.SyncMethodGenerator/SourceGenerationHelper.cs
+++ b/src/Zomp.SyncMethodGenerator/SourceGenerationHelper.cs
@@ -100,6 +100,24 @@ internal static string GenerateExtensionClass(MethodToGenerate methodToGenerate)
}
}
+ // Directives which were written inside the namespace are emitted inside it, at the
+ // innermost level. One which names a namespace relatively still resolves from there.
+ foreach (var @using in methodToGenerate.InnerUsings)
+ {
+ _ = sbBegin.Append($$"""
+{{new string(' ', 4 * i)}}{{@using}}
+
+""");
+ }
+
+ if (!methodToGenerate.InnerUsings.IsEmpty)
+ {
+ _ = sbBegin.Append("""
+
+
+""");
+ }
+
// Handle classes
foreach (var parent in methodToGenerate.Parents)
{
@@ -136,11 +154,30 @@ internal static string GenerateExtensionClass(MethodToGenerate methodToGenerate)
++i;
}
+ var sbOuterUsings = new StringBuilder();
+ foreach (var @using in methodToGenerate.OuterUsings)
+ {
+ if (sbOuterUsings.Length == 0)
+ {
+ // Separates the directives from the header above them.
+ _ = sbOuterUsings.Append("""
+
+
+
+""");
+ }
+
+ _ = sbOuterUsings.Append($$"""
+{{@using}}
+
+""");
+ }
+
var beforeNamespace = $"""
// {(methodToGenerate.DisableNullable ? string.Empty : """
#nullable enable
-""")}
+""")}{sbOuterUsings}
""";
return methodToGenerate.IsNamespaceFileScoped ? $$"""
diff --git a/src/Zomp.SyncMethodGenerator/SyncMethodSourceGenerator.cs b/src/Zomp.SyncMethodGenerator/SyncMethodSourceGenerator.cs
index a3d69fa..3b76bfc 100644
--- a/src/Zomp.SyncMethodGenerator/SyncMethodSourceGenerator.cs
+++ b/src/Zomp.SyncMethodGenerator/SyncMethodSourceGenerator.cs
@@ -372,6 +372,15 @@ private static string Hash(string value)
var isNamespaceFileScoped = false;
var namespaces = ImmutableArray.CreateBuilder();
+ // Documentation comments are copied across verbatim, and a cref in one is resolved
+ // against the file it lands in rather than the file it was written in. Without the
+ // using directives which were in scope where it was written, every cref which relied on
+ // one goes unresolved, which a project building with warnings as errors reads as a
+ // build failure. The directives are kept on the side of the namespace they were
+ // declared on, since one declared inside a namespace may name it only relatively.
+ var outerUsings = ImmutableArray.CreateBuilder();
+ var innerUsings = ImmutableArray.CreateBuilder();
+
if (!hasErrors)
{
while (node is not null and not CompilationUnitSyntax)
@@ -380,9 +389,11 @@ private static string Hash(string value)
{
case NamespaceDeclarationSyntax nds:
namespaces.Insert(0, nds.Name.ToString());
+ InsertUsings(innerUsings, nds.Usings);
break;
case FileScopedNamespaceDeclarationSyntax file:
namespaces.Add(file.Name.ToString());
+ InsertUsings(innerUsings, file.Usings);
isNamespaceFileScoped = true;
break;
default:
@@ -391,6 +402,11 @@ private static string Hash(string value)
node = node.Parent;
}
+
+ if (node is CompilationUnitSyntax compilationUnit)
+ {
+ InsertUsings(outerUsings, compilationUnit.Usings);
+ }
}
#if ROSLYN_5_0_OR_GREATER
@@ -400,11 +416,26 @@ private static string Hash(string value)
#endif
var signature = BuildSignature(sn, namespaces, classes, methodDeclarationSyntax);
- var result = new MethodToGenerate(index, namespaces.ToImmutable(), isNamespaceFileScoped, isCSharp14Extension, classes.ToImmutable(), methodDeclarationSyntax.Identifier.ValueText, content, disableNullable, rewriter.Diagnostics, hasErrors, signature);
+ var result = new MethodToGenerate(index, namespaces.ToImmutable(), outerUsings.ToImmutable(), innerUsings.ToImmutable(), isNamespaceFileScoped, isCSharp14Extension, classes.ToImmutable(), methodDeclarationSyntax.Identifier.ValueText, content, disableNullable, rewriter.Diagnostics, hasErrors, signature);
return result;
}
+ ///
+ /// Records the directives, innermost first, so that walking outwards from the method builds
+ /// them up in the order they were written.
+ ///
+ /// Collected directives.
+ /// Directives declared at one level.
+ private static void InsertUsings(ImmutableArray.Builder destination, SyntaxList usings)
+ {
+ var index = 0;
+ foreach (var @using in usings)
+ {
+ destination.Insert(index++, @using.ToString());
+ }
+ }
+
///
/// Describes the method which is about to be emitted, precisely enough to tell whether two
/// of them would declare the same member. The rewritten declaration is used rather than the
diff --git a/tests/Generator.Tests/Snapshots/ExtensionMethodTests.CSharp_14_ExtensionCallingAnotherExtension#Callers.StreamCallers.ext.CopyAndDrainAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/ExtensionMethodTests.CSharp_14_ExtensionCallingAnotherExtension#Callers.StreamCallers.ext.CopyAndDrainAsync.g.verified.cs
index 50c07d8..e52af22 100644
--- a/tests/Generator.Tests/Snapshots/ExtensionMethodTests.CSharp_14_ExtensionCallingAnotherExtension#Callers.StreamCallers.ext.CopyAndDrainAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/ExtensionMethodTests.CSharp_14_ExtensionCallingAnotherExtension#Callers.StreamCallers.ext.CopyAndDrainAsync.g.verified.cs
@@ -3,6 +3,8 @@
#nullable enable
namespace Callers
{
+ using Helpers;
+
public static partial class StreamCallers
{
extension(global::System.IO.Stream stream)
diff --git a/tests/Generator.Tests/Snapshots/ExtensionMethodTests.CSharp_14_ExtensionUnwrapsOntoOneLine#Callers.StreamCallers.ext.DrainTwiceAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/ExtensionMethodTests.CSharp_14_ExtensionUnwrapsOntoOneLine#Callers.StreamCallers.ext.DrainTwiceAsync.g.verified.cs
index 6149c8d..1b475ad 100644
--- a/tests/Generator.Tests/Snapshots/ExtensionMethodTests.CSharp_14_ExtensionUnwrapsOntoOneLine#Callers.StreamCallers.ext.DrainTwiceAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/ExtensionMethodTests.CSharp_14_ExtensionUnwrapsOntoOneLine#Callers.StreamCallers.ext.DrainTwiceAsync.g.verified.cs
@@ -3,6 +3,8 @@
#nullable enable
namespace Callers
{
+ using Helpers;
+
public static partial class StreamCallers
{
extension(global::System.IO.Stream stream)
diff --git a/tests/Generator.Tests/Snapshots/ExtensionMethodTests.EntityFrameworkQueryableExtensions#Zomp.SyncMethodGenerator.IntegrationTests.EntityFrameworkQuery_0f26cde8.QueryableExtensionAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/ExtensionMethodTests.EntityFrameworkQueryableExtensions#Zomp.SyncMethodGenerator.IntegrationTests.EntityFrameworkQuery_0f26cde8.QueryableExtensionAsync.g.verified.cs
index 2377bed..fe5a317 100644
--- a/tests/Generator.Tests/Snapshots/ExtensionMethodTests.EntityFrameworkQueryableExtensions#Zomp.SyncMethodGenerator.IntegrationTests.EntityFrameworkQuery_0f26cde8.QueryableExtensionAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/ExtensionMethodTests.EntityFrameworkQueryableExtensions#Zomp.SyncMethodGenerator.IntegrationTests.EntityFrameworkQuery_0f26cde8.QueryableExtensionAsync.g.verified.cs
@@ -1,8 +1,14 @@
//HintName: Zomp.SyncMethodGenerator.IntegrationTests.EntityFrameworkQuery_0f26cde8.QueryableExtensionAsync.g.cs
//
#nullable enable
+
+using System.Threading;
+using System.Threading.Tasks;
+
namespace Zomp.SyncMethodGenerator.IntegrationTests
{
+ using Microsoft.EntityFrameworkCore;
+
public partial class EntityFrameworkQueryableExtensions
{
public int QueryableExtension(global::Microsoft.EntityFrameworkCore.DbContext dbContext)
diff --git a/tests/Generator.Tests/Snapshots/ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGeneric2ExtensionAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGeneric2ExtensionAsync.g.verified.cs
index 16675a6..52b17d6 100644
--- a/tests/Generator.Tests/Snapshots/ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGeneric2ExtensionAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGeneric2ExtensionAsync.g.verified.cs
@@ -1,13 +1,20 @@
-//HintName: Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGeneric2ExtensionAsync.g.cs
-//
-#nullable enable
-namespace Zomp.SyncMethodGenerator.IntegrationTests
-{
- partial class Extensions
- {
- public static void HasGeneric2Extension(object o)
- {
- var z = global::Extensi.ons123.MyExtensionClass.TryGetValue(o, out var _, out var _1);
- }
- }
-}
+//HintName: Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGeneric2ExtensionAsync.g.cs
+//
+#nullable enable
+
+using System.Drawing;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Zomp.SyncMethodGenerator.IntegrationTests
+{
+ using Extensi.ons123;
+
+ partial class Extensions
+ {
+ public static void HasGeneric2Extension(object o)
+ {
+ var z = global::Extensi.ons123.MyExtensionClass.TryGetValue(o, out var _, out var _1);
+ }
+ }
+}
diff --git a/tests/Generator.Tests/Snapshots/ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGenericExtensionAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGenericExtensionAsync.g.verified.cs
index 86fde87..1cb1e58 100644
--- a/tests/Generator.Tests/Snapshots/ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGenericExtensionAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGenericExtensionAsync.g.verified.cs
@@ -1,13 +1,20 @@
-//HintName: Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGenericExtensionAsync.g.cs
-//
-#nullable enable
-namespace Zomp.SyncMethodGenerator.IntegrationTests
-{
- partial class Extensions
- {
- public static void HasGenericExtension(object o)
- {
- var z = global::Extensi.ons123.MyExtensionClass.TryGetValue(o, out var item);
- }
- }
-}
+//HintName: Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGenericExtensionAsync.g.cs
+//
+#nullable enable
+
+using System.Drawing;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Zomp.SyncMethodGenerator.IntegrationTests
+{
+ using Extensi.ons123;
+
+ partial class Extensions
+ {
+ public static void HasGenericExtension(object o)
+ {
+ var z = global::Extensi.ons123.MyExtensionClass.TryGetValue(o, out var item);
+ }
+ }
+}
diff --git a/tests/Generator.Tests/Snapshots/MemoryTests.NonPredefinedTypes#N1.Class.FillAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/MemoryTests.NonPredefinedTypes#N1.Class.FillAsync.g.verified.cs
index 450c3c8..6beaa27 100644
--- a/tests/Generator.Tests/Snapshots/MemoryTests.NonPredefinedTypes#N1.Class.FillAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/MemoryTests.NonPredefinedTypes#N1.Class.FillAsync.g.verified.cs
@@ -1,14 +1,18 @@
-//HintName: N1.Class.FillAsync.g.cs
-//
-#nullable enable
-namespace N1
-{
- partial class Class
- {
- void Fill(global::System.Span accelerometers)
- {
- global::N2.C1.C2.Accelerometer a = new(1, 2, 3);
- accelerometers[0] = a;
- }
- }
-}
+//HintName: N1.Class.FillAsync.g.cs
+//
+#nullable enable
+
+using N2;
+using static N2.C1;
+
+namespace N1
+{
+ partial class Class
+ {
+ void Fill(global::System.Span accelerometers)
+ {
+ global::N2.C1.C2.Accelerometer a = new(1, 2, 3);
+ accelerometers[0] = a;
+ }
+ }
+}
diff --git a/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.ConfiguredCancelableAsyncEnumerableExtensionUsingStatic#Test.Extensions.GetConfiguredAsyncEnumerator.g.verified.cs b/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.ConfiguredCancelableAsyncEnumerableExtensionUsingStatic#Test.Extensions.GetConfiguredAsyncEnumerator.g.verified.cs
index 468c0bc..d15b9fb 100644
--- a/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.ConfiguredCancelableAsyncEnumerableExtensionUsingStatic#Test.Extensions.GetConfiguredAsyncEnumerator.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.ConfiguredCancelableAsyncEnumerableExtensionUsingStatic#Test.Extensions.GetConfiguredAsyncEnumerator.g.verified.cs
@@ -1,11 +1,14 @@
-//HintName: Test.Extensions.GetConfiguredAsyncEnumerator.g.cs
-//
-#nullable enable
-namespace Test;
-internal static partial class Extensions
-{
- public static System.Collections.Generic.IEnumerator GetConfiguredEnumerator(global::System.Collections.Generic.IEnumerable enumerable)
- {
- return enumerable.GetEnumerator();
- }
-}
+//HintName: Test.Extensions.GetConfiguredAsyncEnumerator.g.cs
+//
+#nullable enable
+
+using static System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable;
+
+namespace Test;
+internal static partial class Extensions
+{
+ public static System.Collections.Generic.IEnumerator GetConfiguredEnumerator(global::System.Collections.Generic.IEnumerable enumerable)
+ {
+ return enumerable.GetEnumerator();
+ }
+}
diff --git a/tests/Generator.Tests/Snapshots/TypeTests.EnumPattern#g.verified.cs b/tests/Generator.Tests/Snapshots/TypeTests.EnumPattern#g.verified.cs
index 1d96052..3f3f147 100644
--- a/tests/Generator.Tests/Snapshots/TypeTests.EnumPattern#g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/TypeTests.EnumPattern#g.verified.cs
@@ -1,2 +1,14 @@
//HintName: Test.Class.MethodAsync.g.cs
-_ = global::System.Data.ConnectionState.Closed is global::System.Data.ConnectionState.Closed;
+//
+#nullable enable
+
+using static System.Data.ConnectionState;
+
+namespace Test;
+partial class Class
+{
+ public void Method()
+ {
+ _ = global::System.Data.ConnectionState.Closed is global::System.Data.ConnectionState.Closed;
+ }
+}
diff --git a/tests/Generator.Tests/Snapshots/UnitTests.DropReturnsDocumentationWhenNothingIsReturned#CountAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/UnitTests.DropReturnsDocumentationWhenNothingIsReturned#CountAsync.g.verified.cs
new file mode 100644
index 0000000..d8f04fe
--- /dev/null
+++ b/tests/Generator.Tests/Snapshots/UnitTests.DropReturnsDocumentationWhenNothingIsReturned#CountAsync.g.verified.cs
@@ -0,0 +1,11 @@
+//HintName: Test.Class.CountAsync.g.cs
+///
+/// Counts the values.
+///
+/// Where to read from.
+/// A whose result is the number of values.
+public int Count(global::System.IO.Stream input)
+{
+ input.Flush();
+ return 0;
+}
diff --git a/tests/Generator.Tests/Snapshots/UnitTests.DropReturnsDocumentationWhenNothingIsReturned#ReadAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/UnitTests.DropReturnsDocumentationWhenNothingIsReturned#ReadAsync.g.verified.cs
new file mode 100644
index 0000000..118b784
--- /dev/null
+++ b/tests/Generator.Tests/Snapshots/UnitTests.DropReturnsDocumentationWhenNothingIsReturned#ReadAsync.g.verified.cs
@@ -0,0 +1,7 @@
+//HintName: Test.Class.ReadAsync.g.cs
+///
+/// Reads a value.
+///
+/// Where to read from.
+public void Read(global::System.IO.Stream input)
+ => input.Flush();
diff --git a/tests/Generator.Tests/Snapshots/UnitTests.GenericTypeInDeclarationPattern#M.B.DoSomethingAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/UnitTests.GenericTypeInDeclarationPattern#M.B.DoSomethingAsync.g.verified.cs
index cbd7124..ec8cd27 100644
--- a/tests/Generator.Tests/Snapshots/UnitTests.GenericTypeInDeclarationPattern#M.B.DoSomethingAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/UnitTests.GenericTypeInDeclarationPattern#M.B.DoSomethingAsync.g.verified.cs
@@ -3,6 +3,8 @@
#nullable enable
namespace M
{
+ using N;
+
public partial class B
{
public void DoSomething(object arg)
diff --git a/tests/Generator.Tests/Snapshots/UnitTests.GenericTypeInTypeOfExpression#M.B.DoSomethingAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/UnitTests.GenericTypeInTypeOfExpression#M.B.DoSomethingAsync.g.verified.cs
index 1c8ff6b..9e3779c 100644
--- a/tests/Generator.Tests/Snapshots/UnitTests.GenericTypeInTypeOfExpression#M.B.DoSomethingAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/UnitTests.GenericTypeInTypeOfExpression#M.B.DoSomethingAsync.g.verified.cs
@@ -3,6 +3,8 @@
#nullable enable
namespace M
{
+ using N;
+
public partial class B
{
public void DoSomething()
diff --git a/tests/Generator.Tests/Snapshots/UnitTests.HandleAttribute#ReadSomeBytesAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/UnitTests.HandleAttribute#ReadSomeBytesAsync.g.verified.cs
index 7a40f2c..108284f 100644
--- a/tests/Generator.Tests/Snapshots/UnitTests.HandleAttribute#ReadSomeBytesAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/UnitTests.HandleAttribute#ReadSomeBytesAsync.g.verified.cs
@@ -1,12 +1,15 @@
-//HintName: Test.Class.ReadSomeBytesAsync.g.cs
-//
-#nullable enable
-namespace Test;
-public partial class Class
-{
- public int ReadSomeBytes(global::System.IO.Stream stream)
- {
- var buffer = new byte[100];
- return stream.Read(buffer, 0, 100);
- }
-}
+//HintName: Test.Class.ReadSomeBytesAsync.g.cs
+//
+#nullable enable
+
+using System.Diagnostics.CodeAnalysis;
+
+namespace Test;
+public partial class Class
+{
+ public int ReadSomeBytes(global::System.IO.Stream stream)
+ {
+ var buffer = new byte[100];
+ return stream.Read(buffer, 0, 100);
+ }
+}
diff --git a/tests/Generator.Tests/Snapshots/UnitTests.KeepUsingsSoDocumentationCrefsResolve#SendAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/UnitTests.KeepUsingsSoDocumentationCrefsResolve#SendAsync.g.verified.cs
new file mode 100644
index 0000000..d6d7e58
--- /dev/null
+++ b/tests/Generator.Tests/Snapshots/UnitTests.KeepUsingsSoDocumentationCrefsResolve#SendAsync.g.verified.cs
@@ -0,0 +1,20 @@
+//HintName: Test.Class.SendAsync.g.cs
+//
+#nullable enable
+
+using System.Text;
+
+namespace Test
+{
+ using System.Net.Sockets;
+
+ public partial class Class
+ {
+ ///
+ /// Sends a over a .
+ ///
+ /// Where to read from.
+ public void Send(global::System.IO.Stream input)
+ => input.Flush();
+ }
+}
diff --git a/tests/Generator.Tests/Snapshots/UnitTests.Preprocessor#WrappedAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/UnitTests.Preprocessor#WrappedAsync.g.verified.cs
index 4cbb8ab..7572de3 100644
--- a/tests/Generator.Tests/Snapshots/UnitTests.Preprocessor#WrappedAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/UnitTests.Preprocessor#WrappedAsync.g.verified.cs
@@ -1,11 +1,15 @@
-//HintName: Test.Class.WrappedAsync.g.cs
-//
-#nullable enable
-namespace Test;
-public partial class Class
-{
- ///
- /// A summary
- ///
- public void Wrapped() { }
-}
+//HintName: Test.Class.WrappedAsync.g.cs
+//
+#nullable enable
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Test;
+public partial class Class
+{
+ ///
+ /// A summary
+ ///
+ public void Wrapped() { }
+}
diff --git a/tests/Generator.Tests/Snapshots/UnitTests.StaticUsings#N1.C1.MethodAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/UnitTests.StaticUsings#N1.C1.MethodAsync.g.verified.cs
index b0e977c..a1f40f5 100644
--- a/tests/Generator.Tests/Snapshots/UnitTests.StaticUsings#N1.C1.MethodAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/UnitTests.StaticUsings#N1.C1.MethodAsync.g.verified.cs
@@ -1,13 +1,16 @@
-//HintName: N1.C1.MethodAsync.g.cs
-//
-#nullable enable
-namespace N1
-{
- public partial class C1
- {
- public void Method()
- {
- _ = global::N2.C2.OtherConst;
- }
- }
-}
+//HintName: N1.C1.MethodAsync.g.cs
+//
+#nullable enable
+
+using static N2.C2;
+
+namespace N1
+{
+ public partial class C1
+ {
+ public void Method()
+ {
+ _ = global::N2.C2.OtherConst;
+ }
+ }
+}
diff --git a/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.OneParamsAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.OneParamsAsync.g.verified.cs
index 05d3421..87493f6 100644
--- a/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.OneParamsAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.OneParamsAsync.g.verified.cs
@@ -1,10 +1,16 @@
-//HintName: Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.OneParamsAsync.g.cs
-//
-#nullable enable
-namespace Zomp.SyncMethodGenerator.IntegrationTests
-{
- partial class ExtensionMethods
- {
- public static void OneParams(object o, string s) => global::Extensi.ons123.MyExtensionClass.SomeMethod(o, s);
- }
-}
+//HintName: Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.OneParamsAsync.g.cs
+//
+#nullable enable
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Zomp.SyncMethodGenerator.IntegrationTests
+{
+ using Extensi.ons123;
+
+ partial class ExtensionMethods
+ {
+ public static void OneParams(object o, string s) => global::Extensi.ons123.MyExtensionClass.SomeMethod(o, s);
+ }
+}
diff --git a/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.TwoParamsAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.TwoParamsAsync.g.verified.cs
index 0d91e8e..7f5f080 100644
--- a/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.TwoParamsAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.TwoParamsAsync.g.verified.cs
@@ -1,10 +1,16 @@
-//HintName: Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.TwoParamsAsync.g.cs
-//
-#nullable enable
-namespace Zomp.SyncMethodGenerator.IntegrationTests
-{
- partial class ExtensionMethods
- {
- public static void TwoParams(object o, string s, int i) => global::Extensi.ons123.MyExtensionClass.SomeMethod(o, s, i);
- }
-}
+//HintName: Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.TwoParamsAsync.g.cs
+//
+#nullable enable
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Zomp.SyncMethodGenerator.IntegrationTests
+{
+ using Extensi.ons123;
+
+ partial class ExtensionMethods
+ {
+ public static void TwoParams(object o, string s, int i) => global::Extensi.ons123.MyExtensionClass.SomeMethod(o, s, i);
+ }
+}
diff --git a/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.ZeroParamsAsync.g.verified.cs b/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.ZeroParamsAsync.g.verified.cs
index 01feca1..ab68f68 100644
--- a/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.ZeroParamsAsync.g.verified.cs
+++ b/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.ZeroParamsAsync.g.verified.cs
@@ -1,10 +1,16 @@
-//HintName: Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.ZeroParamsAsync.g.cs
-//
-#nullable enable
-namespace Zomp.SyncMethodGenerator.IntegrationTests
-{
- partial class ExtensionMethods
- {
- public static void ZeroParams(object o) => global::Extensi.ons123.MyExtensionClass.SomeMethod(o);
- }
-}
+//HintName: Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.ZeroParamsAsync.g.cs
+//
+#nullable enable
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Zomp.SyncMethodGenerator.IntegrationTests
+{
+ using Extensi.ons123;
+
+ partial class ExtensionMethods
+ {
+ public static void ZeroParams(object o) => global::Extensi.ons123.MyExtensionClass.SomeMethod(o);
+ }
+}
diff --git a/tests/Generator.Tests/UnitTests.cs b/tests/Generator.Tests/UnitTests.cs
index a335e80..326fdb6 100644
--- a/tests/Generator.Tests/UnitTests.cs
+++ b/tests/Generator.Tests/UnitTests.cs
@@ -853,6 +853,63 @@ public async Task ReadAsync(Stream input, CancellationToken cancellationToken =
}
""".Verify(sourceType: SourceType.Full, documentationMode: DocumentationMode.None);
+ ///
+ /// A cref is resolved against the file it lands in, so the generated file needs the using
+ /// directives which were in scope where the documentation was written. Without them a
+ /// project building with warnings as errors fails on CS1574.
+ ///
+ /// A task.
+ [Fact]
+ public Task KeepUsingsSoDocumentationCrefsResolve() => """
+using System.Text;
+
+namespace Test
+{
+ using System.Net.Sockets;
+
+ public partial class Class
+ {
+ ///
+ /// Sends a over a .
+ ///
+ /// Where to read from.
+ /// Cancellation token.
+ [Zomp.SyncMethodGenerator.CreateSyncVersion]
+ public async Task SendAsync(Stream input, CancellationToken cancellationToken = default)
+ => await input.FlushAsync(cancellationToken);
+ }
+}
+""".Verify(sourceType: SourceType.Full);
+
+ ///
+ /// The task a method returned is not returned by its synchronized version, so documentation
+ /// describing that task describes nothing. Documentation of a value which survives stays.
+ ///
+ /// A task.
+ [Fact]
+ public Task DropReturnsDocumentationWhenNothingIsReturned() => """
+///
+/// Reads a value.
+///
+/// Where to read from.
+/// A that represents the asynchronous read.
+[Zomp.SyncMethodGenerator.CreateSyncVersion]
+public async Task ReadAsync(Stream input)
+ => await input.FlushAsync();
+
+///
+/// Counts the values.
+///
+/// Where to read from.
+/// A whose result is the number of values.
+[Zomp.SyncMethodGenerator.CreateSyncVersion]
+public async Task CountAsync(Stream input)
+{
+ await input.FlushAsync();
+ return 0;
+}
+""".Verify();
+
[Fact]
public Task VerifyParamHandling() => $$"""
static byte[] HelperMethod(params int[] myParams) => null;