From 47449ee79adfa7d54b757f1885293955c30b94ba Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Mon, 16 Dec 2024 22:18:51 +0100 Subject: [PATCH 1/9] Upgrade to support .NET 9 --- Directory.Packages.props | 91 +++++++++---------- gen/SourceGenerator/Extensions.cs | 2 +- gen/SourceGenerator/ImmutableGenerator.cs | 30 ++++-- .../InheritedCloneGenerator.cs | 65 +++++++------ src/Directory.Build.props | 2 +- .../Extensions/GenerateImmutableAttribute.cs | 5 +- src/RestSharp/Response/RestResponse.cs | 2 +- src/RestSharp/RestSharp.csproj | 18 ++-- test/Directory.Build.props | 2 +- .../RestSharp.InteractiveTests.csproj | 2 +- 10 files changed, 120 insertions(+), 99 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 61c85f4c3..f75c6c7ca 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,49 +1,46 @@ - - true - - - [6.0.28,7) - - - 7.0.17 - - - 8.0.3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + true + + + 8.0.3 + + + 9.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gen/SourceGenerator/Extensions.cs b/gen/SourceGenerator/Extensions.cs index 12daff3e6..f529412a1 100644 --- a/gen/SourceGenerator/Extensions.cs +++ b/gen/SourceGenerator/Extensions.cs @@ -21,7 +21,7 @@ public static IEnumerable FindClasses(this Compilation c .SelectMany(model => model.SyntaxTree.GetRoot().DescendantNodes().OfType()) .Where(predicate); - public static IEnumerable FindAnnotatedClass(this Compilation compilation, string attributeName, bool strict) { + public static IEnumerable FindAnnotatedClasses(this Compilation compilation, string attributeName, bool strict) { return compilation.FindClasses( syntax => syntax.AttributeLists.Any(list => list.Attributes.Any(CheckAttribute)) ); diff --git a/gen/SourceGenerator/ImmutableGenerator.cs b/gen/SourceGenerator/ImmutableGenerator.cs index 7576359bd..e0860bd67 100644 --- a/gen/SourceGenerator/ImmutableGenerator.cs +++ b/gen/SourceGenerator/ImmutableGenerator.cs @@ -15,18 +15,28 @@ namespace SourceGenerator; -[Generator] -public class ImmutableGenerator : ISourceGenerator { - public void Initialize(GeneratorInitializationContext context) { } - - public void Execute(GeneratorExecutionContext context) { - var compilation = context.Compilation; +[Generator(LanguageNames.CSharp)] +public class ImmutableGenerator : IIncrementalGenerator { + public void Initialize(IncrementalGeneratorInitializationContext context) { + var c = context.CompilationProvider.SelectMany((x, _) => GetImmutableClasses(x)); + + context.RegisterSourceOutput( + c.Collect(), + static (ctx, sources) => { + foreach (var source in sources) { + ctx.AddSource(source.Item1, source.Item2); + } + } + ); + return; - var mutableClasses = compilation.FindAnnotatedClass("GenerateImmutable", strict: true); + IEnumerable<(string, SourceText)> GetImmutableClasses(Compilation compilation) { + var mutableClasses = compilation.FindAnnotatedClasses("GenerateImmutable", strict: true); - foreach (var mutableClass in mutableClasses) { - var immutableClass = GenerateImmutableClass(mutableClass, compilation); - context.AddSource($"ReadOnly{mutableClass.Identifier.Text}.cs", SourceText.From(immutableClass, Encoding.UTF8)); + foreach (var mutableClass in mutableClasses) { + var immutableClass = GenerateImmutableClass(mutableClass, compilation); + yield return ($"ReadOnly{mutableClass.Identifier.Text}.cs", SourceText.From(immutableClass, Encoding.UTF8)); + } } } diff --git a/gen/SourceGenerator/InheritedCloneGenerator.cs b/gen/SourceGenerator/InheritedCloneGenerator.cs index 2bc635443..76b81911e 100644 --- a/gen/SourceGenerator/InheritedCloneGenerator.cs +++ b/gen/SourceGenerator/InheritedCloneGenerator.cs @@ -14,37 +14,44 @@ namespace SourceGenerator; -[Generator] -public class InheritedCloneGenerator : ISourceGenerator { +[Generator(LanguageNames.CSharp)] +public class InheritedCloneGenerator : IIncrementalGenerator { const string AttributeName = "GenerateClone"; - public void Initialize(GeneratorInitializationContext context) { } - - public void Execute(GeneratorExecutionContext context) { - var compilation = context.Compilation; - - var candidates = compilation.FindAnnotatedClass(AttributeName, false); - - foreach (var candidate in candidates) { - var semanticModel = compilation.GetSemanticModel(candidate.SyntaxTree); - var genericClassSymbol = semanticModel.GetDeclaredSymbol(candidate); - if (genericClassSymbol == null) continue; - - // Get the method name from the attribute Name argument - var attributeData = genericClassSymbol.GetAttributes().FirstOrDefault(a => a.AttributeClass?.Name == $"{AttributeName}Attribute"); - var methodName = (string)attributeData.NamedArguments.FirstOrDefault(arg => arg.Key == "Name").Value.Value; - - // Get the generic argument type where properties need to be copied from - var attributeSyntax = candidate.AttributeLists - .SelectMany(l => l.Attributes) - .FirstOrDefault(a => a.Name.ToString().StartsWith(AttributeName)); - if (attributeSyntax == null) continue; // This should never happen - - var typeArgumentSyntax = ((GenericNameSyntax)attributeSyntax.Name).TypeArgumentList.Arguments[0]; - var typeSymbol = (INamedTypeSymbol)semanticModel.GetSymbolInfo(typeArgumentSyntax).Symbol; - - var code = GenerateMethod(candidate, genericClassSymbol, typeSymbol, methodName); - context.AddSource($"{genericClassSymbol.Name}.Clone.g.cs", SourceText.From(code, Encoding.UTF8)); + public void Initialize(IncrementalGeneratorInitializationContext context) { + var c = context.CompilationProvider.SelectMany((x, _) => GetClones(x)); + + context.RegisterSourceOutput( + c.Collect(), + static (ctx, sources) => { + foreach (var source in sources) { + ctx.AddSource(source.Item1, source.Item2); + } + } + ); + return; + + IEnumerable<(string, SourceText)> GetClones(Compilation compilation) { + var candidates = compilation.FindAnnotatedClasses(AttributeName, false); + + foreach (var candidate in candidates) { + var semanticModel = compilation.GetSemanticModel(candidate.SyntaxTree); + var genericClassSymbol = semanticModel.GetDeclaredSymbol(candidate); + if (genericClassSymbol == null) continue; + + var attributeData = genericClassSymbol.GetAttributes().FirstOrDefault(a => a.AttributeClass?.Name == $"{AttributeName}Attribute"); + var methodName = (string)attributeData.NamedArguments.FirstOrDefault(arg => arg.Key == "Name").Value.Value; + var baseType = attributeData.NamedArguments.FirstOrDefault(arg => arg.Key == "BaseType").Value.Value; + + // Get the generic argument type where properties need to be copied from + var attributeSyntax = candidate.AttributeLists + .SelectMany(l => l.Attributes) + .FirstOrDefault(a => a.Name.ToString().StartsWith(AttributeName)); + if (attributeSyntax == null) continue; // This should never happen + + var code = GenerateMethod(candidate, genericClassSymbol, (INamedTypeSymbol)baseType, methodName); + yield return ($"{genericClassSymbol.Name}.Clone.g.cs", SourceText.From(code, Encoding.UTF8)); + } } } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 70ef2495c..85288d985 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - netstandard2.0;net471;net48;net6.0;net7.0;net8.0 + netstandard2.0;net471;net48;net8.0;net9.0 restsharp.png Apache-2.0 https://restsharp.dev diff --git a/src/RestSharp/Extensions/GenerateImmutableAttribute.cs b/src/RestSharp/Extensions/GenerateImmutableAttribute.cs index 172d7c24e..1cafdb049 100644 --- a/src/RestSharp/Extensions/GenerateImmutableAttribute.cs +++ b/src/RestSharp/Extensions/GenerateImmutableAttribute.cs @@ -19,8 +19,9 @@ namespace RestSharp.Extensions; class GenerateImmutableAttribute : Attribute; [AttributeUsage(AttributeTargets.Class)] -class GenerateCloneAttribute : Attribute where T : class { - public string? Name { get; set; } +class GenerateCloneAttribute : Attribute { + public Type? BaseType { get; set; } + public string? Name { get; set; } }; [AttributeUsage(AttributeTargets.Property)] diff --git a/src/RestSharp/Response/RestResponse.cs b/src/RestSharp/Response/RestResponse.cs index dc48f2ddc..62b5d569a 100644 --- a/src/RestSharp/Response/RestResponse.cs +++ b/src/RestSharp/Response/RestResponse.cs @@ -24,7 +24,7 @@ namespace RestSharp; /// Container for data sent back from API including deserialized data /// /// Type of data to deserialize to -[GenerateClone(Name = "FromResponse")] +[GenerateClone(BaseType = typeof(RestResponse), Name = "FromResponse")] [DebuggerDisplay($"{{{nameof(DebuggerDisplay)}()}}")] public partial class RestResponse(RestRequest request) : RestResponse(request) { /// diff --git a/src/RestSharp/RestSharp.csproj b/src/RestSharp/RestSharp.csproj index d01835924..5643d4c02 100644 --- a/src/RestSharp/RestSharp.csproj +++ b/src/RestSharp/RestSharp.csproj @@ -12,9 +12,6 @@ - - - RestClient.Extensions.cs @@ -63,12 +60,21 @@ - + - + - + + + + + + + + + + diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 9ad7f24e7..b3c32f6d1 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -3,7 +3,7 @@ true false - net48;net6.0;net7.0;net8.0 + net48;net8.0;net9.0 disable xUnit1033 trx%3bLogFileName=$(MSBuildProjectName).trx diff --git a/test/RestSharp.InteractiveTests/RestSharp.InteractiveTests.csproj b/test/RestSharp.InteractiveTests/RestSharp.InteractiveTests.csproj index 36f53edc9..75c24e34a 100644 --- a/test/RestSharp.InteractiveTests/RestSharp.InteractiveTests.csproj +++ b/test/RestSharp.InteractiveTests/RestSharp.InteractiveTests.csproj @@ -2,7 +2,7 @@ Exe false - net6.0 + net9.0 From 034a3509aa634be79859a47df197f351a51f1179 Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Mon, 16 Dec 2024 22:22:04 +0100 Subject: [PATCH 2/9] Update build targets --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index fa1806ee4..664686421 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -47,7 +47,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - dotnet: ['net6.0', 'net7.0', 'net8.0'] + dotnet: ['net8.0', 'net9.0'] steps: - From 422f56a1eb178ed3788ef50f2a83655d57d64b6c Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Mon, 16 Dec 2024 22:22:51 +0100 Subject: [PATCH 3/9] Update Windows targets --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 664686421..021d0a029 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -23,7 +23,7 @@ jobs: runs-on: windows-latest strategy: matrix: - dotnet: ['net48', 'net6.0', 'net7.0', 'net8.0'] + dotnet: ['net48', 'net9.0', 'net9.0'] steps: - From d969e03fead38c0d126e2650235f5d147e50f3a4 Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Mon, 16 Dec 2024 22:24:11 +0100 Subject: [PATCH 4/9] Add .NET 9 setup --- .github/workflows/pull-request.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 021d0a029..d67e302ea 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -29,6 +29,13 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - + name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 8.0.x + 9.0.x - name: Run tests run: dotnet test -f ${{ matrix.dotnet }} @@ -53,6 +60,13 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - + name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 8.0.x + 9.0.x - name: Run tests run: dotnet test -f ${{ matrix.dotnet }} From 1283d6728c559240048583366ed57a9b60341521 Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Mon, 16 Dec 2024 22:34:07 +0100 Subject: [PATCH 5/9] Update targets --- src/Directory.Build.props | 2 +- test/Directory.Build.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 85288d985..298578a85 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - netstandard2.0;net471;net48;net8.0;net9.0 + netstandard2.0;net462;net8.0;net9.0 restsharp.png Apache-2.0 https://restsharp.dev diff --git a/test/Directory.Build.props b/test/Directory.Build.props index b3c32f6d1..1bb3f1b2b 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -3,7 +3,7 @@ true false - net48;net8.0;net9.0 + net462;net8.0;net9.0 disable xUnit1033 trx%3bLogFileName=$(MSBuildProjectName).trx From 4142480b50914627545f8973db4769333da0507f Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Mon, 16 Dec 2024 22:40:41 +0100 Subject: [PATCH 6/9] Update dependencies --- Directory.Packages.props | 2 +- src/Directory.Build.props | 2 +- src/RestSharp/Authenticators/OAuth/OAuthTools.cs | 6 ------ src/RestSharp/Options/RestClientOptions.cs | 10 ---------- test/Directory.Build.props | 2 +- 5 files changed, 3 insertions(+), 19 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index f75c6c7ca..ed1fd4b2e 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -38,7 +38,7 @@ - + diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 298578a85..85288d985 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - netstandard2.0;net462;net8.0;net9.0 + netstandard2.0;net471;net48;net8.0;net9.0 restsharp.png Apache-2.0 https://restsharp.dev diff --git a/src/RestSharp/Authenticators/OAuth/OAuthTools.cs b/src/RestSharp/Authenticators/OAuth/OAuthTools.cs index e8cf4102a..4c70eab8e 100644 --- a/src/RestSharp/Authenticators/OAuth/OAuthTools.cs +++ b/src/RestSharp/Authenticators/OAuth/OAuthTools.cs @@ -83,12 +83,6 @@ public static string GetNonce() { /// /// The value to escape. /// The escaped value. - /// - /// The method is supposed to take on - /// RFC 3986 behavior if certain elements are present in a .config file. Even if this - /// actually worked (which in my experiments it doesn't), we can't rely on every - /// host actually having this configuration element present. - /// [return: NotNullIfNotNull(nameof(value))] public static string? UrlEncodeRelaxed(string? value) { if (value == null) return null; diff --git a/src/RestSharp/Options/RestClientOptions.cs b/src/RestSharp/Options/RestClientOptions.cs index 74fde4ef0..96ebf9df1 100644 --- a/src/RestSharp/Options/RestClientOptions.cs +++ b/src/RestSharp/Options/RestClientOptions.cs @@ -181,16 +181,6 @@ public RestClientOptions(string baseUrl) : this(new Uri(Ensure.NotEmptyString(ba /// public CookieContainer? CookieContainer { get; set; } - /// - /// Maximum request duration in milliseconds. When the request timeout is specified using , - /// the lowest value between the client timeout and request timeout will be used. - /// - [Obsolete("Use Timeout instead.")] - public int MaxTimeout { - get => (int) (Timeout?.TotalMilliseconds ?? 0); - set => Timeout = TimeSpan.FromMilliseconds(value); - } - /// /// Request duration. Used when the request timeout is not specified using , /// diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 1bb3f1b2b..b3c32f6d1 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -3,7 +3,7 @@ true false - net462;net8.0;net9.0 + net48;net8.0;net9.0 disable xUnit1033 trx%3bLogFileName=$(MSBuildProjectName).trx From ff8a7e0f209c972ebf34ab966f58053f4f408baf Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Mon, 16 Dec 2024 22:41:32 +0100 Subject: [PATCH 7/9] Run tests on Windows in debug --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index d67e302ea..1e119f30e 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -38,7 +38,7 @@ jobs: 9.0.x - name: Run tests - run: dotnet test -f ${{ matrix.dotnet }} + run: dotnet test -c Debug -f ${{ matrix.dotnet }} - name: Upload Test Results if: always() From 5e39e4206129aedf7e673cbd23a181282fa778bd Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Mon, 16 Dec 2024 22:44:54 +0100 Subject: [PATCH 8/9] Update benchmarks target --- benchmarks/RestSharp.Benchmarks/RestSharp.Benchmarks.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/RestSharp.Benchmarks/RestSharp.Benchmarks.csproj b/benchmarks/RestSharp.Benchmarks/RestSharp.Benchmarks.csproj index f60295a8f..3d939e0fb 100644 --- a/benchmarks/RestSharp.Benchmarks/RestSharp.Benchmarks.csproj +++ b/benchmarks/RestSharp.Benchmarks/RestSharp.Benchmarks.csproj @@ -1,7 +1,7 @@ Exe - net7.0 + net9.0 false preview enable From 2bbb92f4f847b88e671eba3ae35565b7270984b5 Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Mon, 16 Dec 2024 22:46:52 +0100 Subject: [PATCH 9/9] Fix matrix on Windows --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 1e119f30e..8c1faff17 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -23,7 +23,7 @@ jobs: runs-on: windows-latest strategy: matrix: - dotnet: ['net48', 'net9.0', 'net9.0'] + dotnet: ['net48', 'net8.0', 'net9.0'] steps: -