diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/PostProcessor.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/PostProcessor.cs index be96e11df59..2800967b4a9 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/PostProcessor.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/PostProcessing/PostProcessor.cs @@ -20,6 +20,21 @@ internal class PostProcessor private readonly HashSet _typesToKeep; private INamedTypeSymbol? _modelFactorySymbol; + // CS8019: Unnecessary using directive. + private const string UnnecessaryUsingDirectiveDiagnosticId = "CS8019"; + + // Diagnostics that indicate a type, namespace, or name could not be resolved. When any of these are + // present in a document the compiler cannot reliably determine whether a using directive is used, so + // the CS8019 ("unnecessary using") diagnostic may be a false positive and must not be trusted. + private static readonly HashSet UnresolvedReferenceDiagnosticIds = + [ + "CS0103", // The name does not exist in the current context. + "CS0234", // The type or namespace name does not exist in the namespace (missing assembly reference?). + "CS0246", // The type or namespace name could not be found (missing using or assembly reference?). + "CS0305", // Using the generic type requires type arguments. + "CS0308", // The non-generic type cannot be used with type arguments. + ]; + public PostProcessor( HashSet typesToKeep, string? modelFactoryFullName = null, @@ -156,20 +171,39 @@ public async Task InternalizeAsync(Project project) project = MarkInternal(project, model, documentId); } + if (nodesToInternalize.Count > 0) + { + CodeModelGenerator.Instance.Emitter.Info( + $"Internalized {nodesToInternalize.Count} unreferenced public type(s)."); + } + var modelNamesToRemove = nodesToInternalize.Keys.Select(item => item.Identifier.Text); - project = await RemoveMethodsFromModelFactoryAsync(project, definitions, modelNamesToRemove.ToHashSet()); + DocumentId? modelFactoryDocumentId; + (project, modelFactoryDocumentId) = await RemoveMethodsFromModelFactoryAsync(project, definitions, modelNamesToRemove.ToHashSet()); + + if (nodesToInternalize.Count > 0) + { + var documentsToClean = nodesToInternalize.Values.ToHashSet(); + // Removing methods from the model factory can leave a using directive (for a model in a + // different namespace) unused, so include the model factory document in the cleanup pass. + if (modelFactoryDocumentId != null) + { + documentsToClean.Add(modelFactoryDocumentId); + } + project = await RemoveUnusedUsingsAsync(project, documentsToClean); + } return project; } - private async Task RemoveMethodsFromModelFactoryAsync(Project project, + private async Task<(Project Project, DocumentId? ModelFactoryDocumentId)> RemoveMethodsFromModelFactoryAsync(Project project, TypeSymbols definitions, HashSet namesToRemove) { var modelFactorySymbol = definitions.ModelFactorySymbol; if (modelFactorySymbol == null) - return project; + return (project, null); var nodesToRemove = new List(); @@ -203,7 +237,7 @@ private async Task RemoveMethodsFromModelFactoryAsync(Project project, // maybe this is possible, for instance, we could be adding the customization all entries previously inside the generated model factory so that the generated model factory is empty and removed. if (modelFactoryGeneratedDocument == null) - return project; + return (project, null); var root = await modelFactoryGeneratedDocument.GetSyntaxRootAsync(); Debug.Assert(root is not null); @@ -214,10 +248,10 @@ private async Task RemoveMethodsFromModelFactoryAsync(Project project, var methods = root.DescendantNodes().OfType(); if (!methods.Any()) { - return project.RemoveDocument(modelFactoryGeneratedDocument.Id); + return (project.RemoveDocument(modelFactoryGeneratedDocument.Id), null); } - return modelFactoryGeneratedDocument.Project; + return (modelFactoryGeneratedDocument.Project, modelFactoryGeneratedDocument.Id); } /// @@ -336,6 +370,9 @@ private static IEnumerable GetReferencedTypes(T definition, private Project MarkInternal(Project project, BaseTypeDeclarationSyntax declarationNode, DocumentId documentId) { + CodeModelGenerator.Instance.Emitter.Debug( + $"Internalizing unreferenced public type '{declarationNode.Identifier.Text}'."); + var newNode = ChangeModifier(declarationNode, SyntaxKind.PublicKeyword, SyntaxKind.InternalKeyword); var tree = declarationNode.SyntaxTree; var document = project.GetDocument(documentId)!; @@ -432,6 +469,76 @@ private async Task RemoveInvalidRefs(Project project) return solution.GetProject(project.Id)!; } + private async Task RemoveUnusedUsingsAsync(Project project, IEnumerable documentIds) + { + var solution = project.Solution; + foreach (var documentId in documentIds) + { + solution = await RemoveUnusedUsings(solution, documentId); + } + + return solution.GetProject(project.Id) ?? project; + } + + private async Task RemoveUnusedUsings(Solution solution, DocumentId documentId) + { + var document = solution.GetDocument(documentId); + if (document == null) + { + return solution; + } + + document = await Simplifier.ReduceAsync(document); + + var root = await document.GetSyntaxRootAsync(); + var model = await document.GetSemanticModelAsync(); + + if (root is not CompilationUnitSyntax cu || model == null) + { + return solution; + } + + var diagnostics = model.GetDiagnostics(); + + if (diagnostics.Any(d => UnresolvedReferenceDiagnosticIds.Contains(d.Id))) + { + return solution; + } + + var unusedUsings = diagnostics + .Where(d => d.Id == UnnecessaryUsingDirectiveDiagnosticId) + .Select(d => cu.FindNode(d.Location.SourceSpan).FirstAncestorOrSelf()) + .OfType() + .ToList(); + + if (unusedUsings.Count == 0) + { + return solution; + } + + // Preserve any leading trivia on the first using directive (such as the file header and the + // #nullable directive) when that directive is removed, by carrying it over to the node that + // follows the removed directives. + var firstUsing = cu.Usings.FirstOrDefault(); + var leadingTrivia = firstUsing is not null && unusedUsings.Contains(firstUsing) + ? firstUsing.GetLeadingTrivia() + : default; + + var updatedRoot = cu.RemoveNodes(unusedUsings, SyntaxRemoveOptions.KeepNoTrivia); + if (updatedRoot == null) + { + return solution; + } + + if (leadingTrivia.Count > 0) + { + var firstToken = updatedRoot.GetFirstToken(); + updatedRoot = updatedRoot.ReplaceToken(firstToken, firstToken.WithLeadingTrivia(leadingTrivia.AddRange(firstToken.LeadingTrivia))); + } + + return solution.WithDocumentSyntaxRoot(documentId, updatedRoot); + } + private async Task RemoveInvalidUsings(Solution solution, DocumentId documentId) { var document = solution.GetDocument(documentId)!; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/PostProcessorTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/PostProcessorTests.cs index 28981148a4d..33105cb4328 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/PostProcessorTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/PostProcessorTests.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.TypeSpec.Generator.Tests.Common; using NUnit.Framework; @@ -289,11 +290,156 @@ public async Task DoesNotRemoveValidAttributes() Assert.AreEqual(Helpers.GetExpectedFromFile().TrimEnd(), output, "The output should match the expected content."); } + [Test] + public async Task RemovesUnusedUsingFromModelFactoryWhenInternalizing() + { + MockHelpers.LoadMockGenerator(); + var workspace = new AdhocWorkspace(); + var projectInfo = ProjectInfo.Create( + ProjectId.CreateNewId(), + VersionStamp.Create(), + name: "TestProj", + assemblyName: "TestProj", + language: LanguageNames.CSharp) + .WithMetadataReferences(new[] + { + MetadataReference.CreateFromFile(typeof(object).Assembly.Location) + }); + + var project = workspace.AddProject(projectInfo); + var folder = Helpers.GetAssetFileOrDirectoryPath(false); + const string rootFileName = "ModelFactoryRoot.cs"; + string[] modelFileNames = + [ + "KeptModel.cs", + "OtherNamespaceModel.cs" + ]; + foreach (var fileName in modelFileNames) + { + project = project.AddDocument( + fileName, + File.ReadAllText(Path.Join(folder, fileName))).Project; + } + // The model factory lives in a generated document so the post-processor can rewrite it. + const string modelFactoryFileName = "SampleModelFactory.cs"; + project = project.AddDocument( + modelFactoryFileName, + File.ReadAllText(Path.Join(folder, modelFactoryFileName)), + folders: ["Generated"]).Project; + project = project.AddDocument( + rootFileName, + File.ReadAllText(Path.Join(folder, rootFileName))).Project; + var postProcessor = new TestPostProcessor(rootFileName, modelFactoryFullName: "Sample.SampleModelFactory"); + + var resultProject = await postProcessor.InternalizeAsync(project); + + // The model in the other namespace is unreferenced and is internalized. + var otherNamespaceModel = await GetSingleClassAsync(resultProject, "OtherNamespaceModel.cs", "OtherNamespaceModel"); + Assert.IsTrue(otherNamespaceModel.Modifiers.Any(m => m.IsKind(SyntaxKind.InternalKeyword))); + + // The referenced model stays public and keeps its model factory method. + var keptModel = await GetSingleClassAsync(resultProject, "KeptModel.cs", "KeptModel"); + Assert.IsTrue(keptModel.Modifiers.Any(m => m.IsKind(SyntaxKind.PublicKeyword))); + + var modelFactory = await GetSingleClassAsync(resultProject, modelFactoryFileName, "SampleModelFactory"); + var methodNames = modelFactory.Members + .OfType() + .Select(m => m.Identifier.Text) + .ToList(); + Assert.IsTrue(methodNames.Contains("KeptModel"), "The model factory method for the referenced model should be preserved."); + Assert.IsFalse(methodNames.Contains("OtherNamespaceModel"), "The model factory method for the internalized model should be removed."); + + // Removing the model factory method for the internalized model leaves the using for its namespace unused, so it is removed. + Assert.IsFalse( + await HasUsingAsync(resultProject, modelFactoryFileName, "Sample.Models"), + "Unused using for the internalized model's namespace should be removed from the model factory."); + + Assert.AreEqual( + Helpers.GetExpectedFromFile().TrimEnd(), + (await GetDocumentTextAsync(resultProject, modelFactoryFileName)).TrimEnd(), + "The generated model factory output should match the expected content."); + } + + [Test] + public async Task KeepsUsedUsingWhenTypeReferencesAreUnresolved() + { + MockHelpers.LoadMockGenerator(); + var workspace = new AdhocWorkspace(); + // Intentionally omit the System.ClientModel reference so that the BinaryContent/ClientResult + // type references in the serialization document cannot be resolved. This mirrors the post-processing + // compilation in real generation, where not every external assembly is referenced. + var projectInfo = ProjectInfo.Create( + ProjectId.CreateNewId(), + VersionStamp.Create(), + name: "TestProj", + assemblyName: "TestProj", + language: LanguageNames.CSharp) + .WithMetadataReferences(new[] + { + MetadataReference.CreateFromFile(typeof(object).Assembly.Location), + MetadataReference.CreateFromFile(typeof(System.BinaryData).Assembly.Location) + }); + + var project = workspace.AddProject(projectInfo); + var folder = Helpers.GetAssetFileOrDirectoryPath(false); + const string rootFileName = "Root.cs"; + const string serializationFileName = "UnreferencedModel.Serialization.cs"; + foreach (var fileName in new[] { "UnreferencedModel.cs", serializationFileName }) + { + project = project.AddDocument(fileName, File.ReadAllText(Path.Join(folder, fileName)), folders: ["Generated"]).Project; + } + project = project.AddDocument(rootFileName, File.ReadAllText(Path.Join(folder, rootFileName))).Project; + var postProcessor = new TestPostProcessor(rootFileName); + + var resultProject = await postProcessor.InternalizeAsync(project); + + // The unreferenced model is internalized. + var model = await GetSingleClassAsync(resultProject, "UnreferencedModel.cs", "UnreferencedModel"); + Assert.IsTrue(model.Modifiers.Any(m => m.IsKind(SyntaxKind.InternalKeyword))); + + // The using is still referenced by the conversion operators, but the type references cannot be + // resolved in this compilation. The using must be preserved rather than removed by the CS8019 pass. + Assert.IsTrue( + await HasUsingAsync(resultProject, serializationFileName, "System.ClientModel"), + "A used using directive must not be removed when its type references cannot be resolved."); + + Assert.AreEqual( + Helpers.GetExpectedFromFile().TrimEnd(), + (await GetDocumentTextAsync(resultProject, serializationFileName)).TrimEnd(), + "The serialization document should be left untouched when references are unresolved."); + } + + private static async Task GetDocumentTextAsync(Project project, string fileName) + { + var doc = project.Documents.Single(d => d.Name == fileName); + var root = await doc.GetSyntaxRootAsync(); + return root!.ToFullString(); + } + + private static async Task HasUsingAsync(Project project, string fileName, string usingName) + { + var doc = project.Documents.Single(d => d.Name == fileName); + var root = await doc.GetSyntaxRootAsync(); + return ((CompilationUnitSyntax)root!) + .Usings + .Any(u => u.Name?.ToString() == usingName); + } + + private static async Task GetSingleClassAsync(Project project, string fileName, string className) + { + var doc = project.Documents.Single(d => d.Name == fileName); + var root = await doc.GetSyntaxRootAsync(); + return ((CompilationUnitSyntax)root!) + .DescendantNodes() + .OfType() + .Single(t => t.Identifier.Text == className); + } + private class TestPostProcessor : PostProcessor { private readonly string _rootFile; - public TestPostProcessor(string rootFile, IEnumerable? nonRootTypes = null) : base([], additionalNonRootTypeNames: nonRootTypes) + public TestPostProcessor(string rootFile, IEnumerable? nonRootTypes = null, string? modelFactoryFullName = null) : base([], modelFactoryFullName: modelFactoryFullName, additionalNonRootTypeNames: nonRootTypes) { _rootFile = rootFile; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved.cs new file mode 100644 index 00000000000..10ef9e57286 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved.cs @@ -0,0 +1,18 @@ +using System.ClientModel; + +namespace Sample.Models +{ + internal partial class UnreferencedModel + { + public static implicit operator BinaryContent(UnreferencedModel model) + { + return BinaryContent.Create(model); + } + + public static explicit operator UnreferencedModel(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + return new UnreferencedModel(); + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved/Root.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved/Root.cs new file mode 100644 index 00000000000..808b8cae401 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved/Root.cs @@ -0,0 +1,7 @@ +namespace Sample +{ + public class Root + { + public int Value { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved/UnreferencedModel.Serialization.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved/UnreferencedModel.Serialization.cs new file mode 100644 index 00000000000..4ad04710c49 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved/UnreferencedModel.Serialization.cs @@ -0,0 +1,18 @@ +using System.ClientModel; + +namespace Sample.Models +{ + public partial class UnreferencedModel + { + public static implicit operator BinaryContent(UnreferencedModel model) + { + return BinaryContent.Create(model); + } + + public static explicit operator UnreferencedModel(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + return new UnreferencedModel(); + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved/UnreferencedModel.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved/UnreferencedModel.cs new file mode 100644 index 00000000000..de228af0eb9 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/KeepsUsedUsingWhenTypeReferencesAreUnresolved/UnreferencedModel.cs @@ -0,0 +1,7 @@ +namespace Sample.Models +{ + public partial class UnreferencedModel + { + public int X { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing.cs new file mode 100644 index 00000000000..92a6592b018 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing.cs @@ -0,0 +1,8 @@ + +namespace Sample +{ + public static partial class SampleModelFactory + { + public static KeptModel KeptModel() => null; + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/KeptModel.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/KeptModel.cs new file mode 100644 index 00000000000..bb8a56d4689 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/KeptModel.cs @@ -0,0 +1,9 @@ +namespace Sample +{ + /// + /// A model referenced from the root type, so it stays public and keeps its model factory method. + /// + public class KeptModel + { + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/ModelFactoryRoot.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/ModelFactoryRoot.cs new file mode 100644 index 00000000000..0253c599a7e --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/ModelFactoryRoot.cs @@ -0,0 +1,7 @@ +namespace Sample +{ + public class ModelFactoryRoot + { + public KeptModel Model { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/OtherNamespaceModel.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/OtherNamespaceModel.cs new file mode 100644 index 00000000000..24f19ea2441 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/OtherNamespaceModel.cs @@ -0,0 +1,10 @@ +namespace Sample.Models +{ + /// + /// A model in a different namespace that is not referenced from any root type and is internalized, + /// so its model factory method (and the using directive for this namespace) is removed. + /// + public class OtherNamespaceModel + { + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/SampleModelFactory.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/SampleModelFactory.cs new file mode 100644 index 00000000000..8f852f65b95 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/PostProcessing/TestData/PostProcessorTests/RemovesUnusedUsingFromModelFactoryWhenInternalizing/SampleModelFactory.cs @@ -0,0 +1,11 @@ +using Sample.Models; + +namespace Sample +{ + public static partial class SampleModelFactory + { + public static KeptModel KeptModel() => null; + + public static OtherNamespaceModel OtherNamespaceModel() => null; + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/parameters/basic/src/Generated/ParametersBasicModelFactory.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/parameters/basic/src/Generated/ParametersBasicModelFactory.cs index 06d44d34bc1..c17dda5eaec 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/parameters/basic/src/Generated/ParametersBasicModelFactory.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/parameters/basic/src/Generated/ParametersBasicModelFactory.cs @@ -3,7 +3,6 @@ #nullable disable using Parameters.Basic._ExplicitBody; -using Parameters.Basic._ImplicitBody; namespace Parameters.Basic { diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/parameters/spread/src/Generated/ParametersSpreadModelFactory.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/parameters/spread/src/Generated/ParametersSpreadModelFactory.cs index 775c933bc6b..4e494c2f2ec 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/parameters/spread/src/Generated/ParametersSpreadModelFactory.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/parameters/spread/src/Generated/ParametersSpreadModelFactory.cs @@ -2,8 +2,6 @@ #nullable disable -using System.Collections.Generic; -using Parameters.Spread._Alias; using Parameters.Spread._Model; namespace Parameters.Spread diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/multipart/src/Generated/PayloadMultiPartModelFactory.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/multipart/src/Generated/PayloadMultiPartModelFactory.cs index 6d036b01c86..e5c87b994a6 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/multipart/src/Generated/PayloadMultiPartModelFactory.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/multipart/src/Generated/PayloadMultiPartModelFactory.cs @@ -2,7 +2,6 @@ #nullable disable -using System; using System.ClientModel; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/pageable/src/Generated/PayloadPageableModelFactory.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/pageable/src/Generated/PayloadPageableModelFactory.cs index 0b66e798a05..9f8c3ce6d6d 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/pageable/src/Generated/PayloadPageableModelFactory.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/payload/pageable/src/Generated/PayloadPageableModelFactory.cs @@ -2,12 +2,7 @@ #nullable disable -using System; -using System.Collections.Generic; -using Payload.Pageable._PageSize; -using Payload.Pageable._ServerDrivenPagination; using Payload.Pageable._ServerDrivenPagination.AlternateInitialVerb; -using Payload.Pageable._ServerDrivenPagination.ContinuationToken; namespace Payload.Pageable { diff --git a/packages/http-client-csharp/generator/TestProjects/Spector/http/special-words/src/Generated/SpecialWordsModelFactory.cs b/packages/http-client-csharp/generator/TestProjects/Spector/http/special-words/src/Generated/SpecialWordsModelFactory.cs index 1abb2114c9a..43aca8db259 100644 --- a/packages/http-client-csharp/generator/TestProjects/Spector/http/special-words/src/Generated/SpecialWordsModelFactory.cs +++ b/packages/http-client-csharp/generator/TestProjects/Spector/http/special-words/src/Generated/SpecialWordsModelFactory.cs @@ -2,10 +2,8 @@ #nullable disable -using System.Collections.Generic; using SpecialWords._ModelProperties; using SpecialWords._Models; -using SpecialWords._ReservedOperationBodyParams; namespace SpecialWords {