diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 16b73fca7..a7c9f00bf 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -15,4 +15,5 @@ jobs: with: productNamespacePrefix: "Refit" srcFolder: "./" - installWorkflows: true + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e8a209595..31459f15d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,6 @@ jobs: configuration: Release productNamespacePrefix: "Refit" srcFolder: "./" - installWorkflows: false secrets: SIGN_ACCOUNT_NAME: ${{ secrets.SIGN_ACCOUNT_NAME }} SIGN_PROFILE_NAME: ${{ secrets.SIGN_PROFILE_NAME }} diff --git a/Directory.Build.props b/Directory.Build.props index 8063aebf5..2adbaa5cc 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -23,7 +23,9 @@ true $(MSBuildThisFileDirectory)buildtask.snk - net462;netstandard2.0;net8.0;net9.0 + net462 + net8.0;net9.0;net10.0 + $(RefitTargets);netstandard2.0;$(RefitTestTargets) IDE0040;CA1054;CA1510 diff --git a/InterfaceStubGenerator.Shared/Emitter.cs b/InterfaceStubGenerator.Shared/Emitter.cs index a83789309..f8364a2fc 100644 --- a/InterfaceStubGenerator.Shared/Emitter.cs +++ b/InterfaceStubGenerator.Shared/Emitter.cs @@ -195,7 +195,8 @@ UniqueNameBuilder uniqueNames ), }; - WriteMethodOpening(source, methodModel, !isTopLevel, isAsync); + var isExplicit = methodModel.IsExplicitInterface || !isTopLevel; + WriteMethodOpening(source, methodModel, isExplicit, isExplicit, isAsync); // Build the list of args for the array var argArray = methodModel @@ -219,10 +220,18 @@ UniqueNameBuilder uniqueNames ? $", new global::System.Type[] {{ {string.Join(", ", genericArray)} }}" : string.Empty; + // Normalize method lookup key: strip explicit interface prefix if present (e.g. IFoo.Bar -> Bar) + var lookupName = methodModel.Name; + var lastDotIndex = lookupName.LastIndexOf('.'); + if (lastDotIndex >= 0 && lastDotIndex < lookupName.Length - 1) + { + lookupName = lookupName.Substring(lastDotIndex + 1); + } + source.WriteLine( $""" var ______arguments = {argumentsArrayString}; - var ______func = requestBuilder.BuildRestResultFuncForMethod("{methodModel.Name}", {parameterTypesExpression}{genericString} ); + var ______func = requestBuilder.BuildRestResultFuncForMethod("{lookupName}", {parameterTypesExpression}{genericString} ); {@return}({returnType})______func(this.Client, ______arguments){configureAwait}; """ @@ -233,7 +242,8 @@ UniqueNameBuilder uniqueNames private static void WriteNonRefitMethod(SourceWriter source, MethodModel methodModel) { - WriteMethodOpening(source, methodModel, true); + var isExplicit = methodModel.IsExplicitInterface; + WriteMethodOpening(source, methodModel, isExplicit, isExplicit); source.WriteLine( @"throw new global::System.NotImplementedException(""Either this method has no Refit HTTP method attribute or you've used something other than a string literal for the 'path' argument."");" @@ -242,9 +252,6 @@ private static void WriteNonRefitMethod(SourceWriter source, MethodModel methodM WriteMethodClosing(source); } - // TODO: This assumes that the Dispose method is a void that takes no parameters. - // The previous version did not. - // Does the bool overload cause an issue here. private static void WriteDisposableMethod(SourceWriter source) { source.WriteLine( @@ -293,6 +300,7 @@ UniqueNameBuilder uniqueNames private static void WriteMethodOpening( SourceWriter source, MethodModel methodModel, + bool isDerivedExplicitImpl, bool isExplicitInterface, bool isAsync = false ) @@ -308,7 +316,12 @@ private static void WriteMethodOpening( if (isExplicitInterface) { - builder.Append(@$"{methodModel.ContainingType}."); + var ct = methodModel.ContainingType; + if (!ct.StartsWith("global::")) + { + ct = "global::" + ct; + } + builder.Append(@$"{ct}."); } builder.Append(@$"{methodModel.DeclaredMethod}("); @@ -318,7 +331,6 @@ private static void WriteMethodOpening( foreach (var param in methodModel.Parameters) { var annotation = param.Annotation; - list.Add($@"{param.Type}{(annotation ? '?' : string.Empty)} @{param.MetadataName}"); } @@ -330,7 +342,7 @@ private static void WriteMethodOpening( source.WriteLine(); source.WriteLine(builder.ToString()); source.Indentation++; - GenerateConstraints(source, methodModel.Constraints, isExplicitInterface); + GenerateConstraints(source, methodModel.Constraints, isDerivedExplicitImpl || isExplicitInterface); source.Indentation--; source.WriteLine("{"); source.Indentation++; diff --git a/InterfaceStubGenerator.Shared/ImmutableEquatableArray.cs b/InterfaceStubGenerator.Shared/ImmutableEquatableArray.cs index 23c1d9009..8b342063c 100644 --- a/InterfaceStubGenerator.Shared/ImmutableEquatableArray.cs +++ b/InterfaceStubGenerator.Shared/ImmutableEquatableArray.cs @@ -64,7 +64,7 @@ static int Combine(int h1, int h2) IEnumerator IEnumerable.GetEnumerator() => _values.GetEnumerator(); - public struct Enumerator + public record struct Enumerator { private readonly T[] _values; private int _index; diff --git a/InterfaceStubGenerator.Shared/InterfaceStubGenerator.Shared.projitems b/InterfaceStubGenerator.Shared/InterfaceStubGenerator.Shared.projitems index 92de97af5..e5322e8d8 100644 --- a/InterfaceStubGenerator.Shared/InterfaceStubGenerator.Shared.projitems +++ b/InterfaceStubGenerator.Shared/InterfaceStubGenerator.Shared.projitems @@ -23,6 +23,7 @@ + diff --git a/InterfaceStubGenerator.Shared/InterfaceStubGenerator.cs b/InterfaceStubGenerator.Shared/InterfaceStubGenerator.cs index bd6e91cde..3ab4481fa 100644 --- a/InterfaceStubGenerator.Shared/InterfaceStubGenerator.cs +++ b/InterfaceStubGenerator.Shared/InterfaceStubGenerator.cs @@ -10,13 +10,8 @@ namespace Refit.Generator { - // * Search for all Interfaces, find the method definitions - // and make sure there's at least one Refit attribute on one - // * Generate the data we need for the template based on interface method - // defn's - /// - /// InterfaceStubGeneratorV2. + /// InterfaceStubGenerator. /// [Generator] #if ROSLYN_4 @@ -28,7 +23,6 @@ public class InterfaceStubGenerator : ISourceGenerator private const string TypeParameterVariableName = "______typeParameters"; #if !ROSLYN_4 - /// /// Executes the specified context. /// @@ -51,13 +45,11 @@ out var refitInternalNamespace context.CancellationToken ); - // Emit diagnostics foreach (var diagnostic in parseStep.diagnostics) { context.ReportDiagnostic(diagnostic); } - // Emit interface stubs foreach (var interfaceModel in parseStep.contextGenerationSpec.Interfaces) { var interfaceText = Emitter.EmitInterface(interfaceModel); @@ -67,7 +59,6 @@ out var refitInternalNamespace ); } - // Emit PreserveAttribute and Generated.Initialize Emitter.EmitSharedCode( parseStep.contextGenerationSpec, (name, code) => context.AddSource(name, code) @@ -76,15 +67,9 @@ out var refitInternalNamespace #endif #if ROSLYN_4 - - /// - /// Initializes the specified context. - /// - /// The context. - /// + /// public void Initialize(IncrementalGeneratorInitializationContext context) { - // We're looking for methods with an attribute that are in an interface var candidateMethodsProvider = context.SyntaxProvider.CreateSyntaxProvider( (syntax, cancellationToken) => syntax @@ -96,8 +81,6 @@ is MethodDeclarationSyntax (context, cancellationToken) => (MethodDeclarationSyntax)context.Node ); - // We also look for interfaces that derive from others, so we can see if any base methods contain - // Refit methods var candidateInterfacesProvider = context.SyntaxProvider.CreateSyntaxProvider( (syntax, cancellationToken) => syntax is InterfaceDeclarationSyntax { BaseList: not null }, @@ -146,9 +129,6 @@ out var refitInternalNamespace } ); - // output the diagnostics - // use `ImmutableEquatableArray` to cache cases where there are no diagnostics - // otherwise the subsequent steps will always rerun. var diagnostics = parseStep .Select(static (x, _) => x.diagnostics.ToImmutableEquatableArray()) .WithTrackingName(RefitGeneratorStepName.ReportDiagnostics); @@ -168,14 +148,11 @@ out var refitInternalNamespace } ); } - #else - /// /// Initializes the specified context. /// /// The context. - /// public void Initialize(GeneratorInitializationContext context) { context.RegisterForSyntaxNotifications(() => new SyntaxReceiver()); @@ -189,7 +166,6 @@ class SyntaxReceiver : ISyntaxReceiver public void OnVisitSyntaxNode(SyntaxNode syntaxNode) { - // We're looking for methods with an attribute that are in an interfaces if ( syntaxNode is MethodDeclarationSyntax methodDeclarationSyntax && methodDeclarationSyntax.Parent is InterfaceDeclarationSyntax @@ -199,15 +175,12 @@ syntaxNode is MethodDeclarationSyntax methodDeclarationSyntax CandidateMethods.Add(methodDeclarationSyntax); } - // We also look for interfaces that derive from others, so we can see if any base methods contain - // Refit methods if (syntaxNode is InterfaceDeclarationSyntax iface && iface.BaseList is not null) { CandidateInterfaces.Add(iface); } } } - #endif } diff --git a/InterfaceStubGenerator.Shared/Models/MethodModel.cs b/InterfaceStubGenerator.Shared/Models/MethodModel.cs index 513a8b93b..6f6170c10 100644 --- a/InterfaceStubGenerator.Shared/Models/MethodModel.cs +++ b/InterfaceStubGenerator.Shared/Models/MethodModel.cs @@ -1,4 +1,6 @@ -namespace Refit.Generator; +using System.Collections.Immutable; + +namespace Refit.Generator; internal sealed record MethodModel( string Name, @@ -7,7 +9,8 @@ internal sealed record MethodModel( string DeclaredMethod, ReturnTypeInfo ReturnTypeMetadata, ImmutableEquatableArray Parameters, - ImmutableEquatableArray Constraints + ImmutableEquatableArray Constraints, + bool IsExplicitInterface ); internal enum ReturnTypeInfo : byte diff --git a/InterfaceStubGenerator.Shared/Models/WellKnownTypes.cs b/InterfaceStubGenerator.Shared/Models/WellKnownTypes.cs index 28ea5e403..656e98c63 100644 --- a/InterfaceStubGenerator.Shared/Models/WellKnownTypes.cs +++ b/InterfaceStubGenerator.Shared/Models/WellKnownTypes.cs @@ -2,16 +2,41 @@ namespace Refit.Generator; +/// +/// WellKnownTypes. +/// public class WellKnownTypes(Compilation compilation) { - readonly Dictionary cachedTypes = new(); + readonly Dictionary cachedTypes = []; + /// + /// Gets this instance. + /// + /// + /// public INamedTypeSymbol Get() => Get(typeof(T)); + + /// + /// Gets the specified type. + /// + /// The type. + /// + /// Could not get name of type " + type public INamedTypeSymbol Get(Type type) { + if (type is null) + { + throw new ArgumentNullException(nameof(type)); + } + return Get(type.FullName ?? throw new InvalidOperationException("Could not get name of type " + type)); } + /// + /// Tries the get. + /// + /// Full name of the type. + /// public INamedTypeSymbol? TryGet(string typeFullName) { if (cachedTypes.TryGetValue(typeFullName, out var typeSymbol)) diff --git a/InterfaceStubGenerator.Shared/Parser.cs b/InterfaceStubGenerator.Shared/Parser.cs index 280c74d9b..ebd7e6dee 100644 --- a/InterfaceStubGenerator.Shared/Parser.cs +++ b/InterfaceStubGenerator.Shared/Parser.cs @@ -309,6 +309,34 @@ bool nullableEnabled .Cast() .ToArray(); + // Exclude base interface methods that the current interface explicitly implements. + // This avoids false positive RF001 diagnostics for cases like: + // interface IFoo { int Bar(); } and interface IRemoteFoo : IFoo { [Get] abstract int IFoo.Bar(); } + if (derivedNonRefitMethods.Length > 0) + { + var explicitlyImplementedBaseMethods = new HashSet( + SymbolEqualityComparer.Default + ); + + foreach (var member in interfaceSymbol.GetMembers().OfType()) + { + foreach (var baseMethod in member.ExplicitInterfaceImplementations) + { + // Use OriginalDefinition for robustness when comparing generic methods + explicitlyImplementedBaseMethods.Add( + baseMethod.OriginalDefinition ?? baseMethod + ); + } + } + + if (explicitlyImplementedBaseMethods.Count > 0) + { + derivedNonRefitMethods = derivedNonRefitMethods + .Where(m => !explicitlyImplementedBaseMethods.Contains(m.OriginalDefinition ?? m)) + .ToArray(); + } + } + var memberNames = interfaceSymbol .GetMembers() .Select(x => x.Name) @@ -319,24 +347,39 @@ bool nullableEnabled var refitMethodsArray = refitMethods .Select(m => ParseMethod(m, true)) .ToImmutableEquatableArray(); - var derivedRefitMethodsArray = refitMethods - .Concat(derivedRefitMethods) + + // Only include refit methods discovered on base interfaces here. + // Do NOT duplicate the current interface's refit methods. + var derivedRefitMethodsArray = derivedRefitMethods .Select(m => ParseMethod(m, false)) .ToImmutableEquatableArray(); // Handle non-refit Methods that aren't static or properties or have a method body var nonRefitMethodModelList = new List(); - foreach (var method in nonRefitMethods.Concat(derivedNonRefitMethods)) + foreach (var method in nonRefitMethods) { if ( method.IsStatic || method.MethodKind == MethodKind.PropertyGet || method.MethodKind == MethodKind.PropertySet || !method.IsAbstract - ) // If an interface method has a body, it won't be abstract + ) continue; - nonRefitMethodModelList.Add(ParseNonRefitMethod(method, diagnostics)); + nonRefitMethodModelList.Add(ParseNonRefitMethod(method, diagnostics, isDerived: false)); + } + foreach (var method in derivedNonRefitMethods) + { + if ( + method.IsStatic + || method.MethodKind == MethodKind.PropertyGet + || method.MethodKind == MethodKind.PropertySet + || !method.IsAbstract + ) + continue; + + // Derived non-refit methods should be emitted as explicit interface implementations + nonRefitMethodModelList.Add(ParseNonRefitMethod(method, diagnostics, isDerived: true)); } var nonRefitMethodModels = nonRefitMethodModelList.ToImmutableEquatableArray(); @@ -369,7 +412,8 @@ bool nullableEnabled private static MethodModel ParseNonRefitMethod( IMethodSymbol methodSymbol, - List diagnostics + List diagnostics, + bool isDerived ) { // report invalid error diagnostic @@ -384,7 +428,58 @@ List diagnostics diagnostics.Add(diagnostic); } - return ParseMethod(methodSymbol, false); + // Parse like a regular method, but force explicit implementation for derived base-interface methods + var explicitImpl = methodSymbol.ExplicitInterfaceImplementations.FirstOrDefault(); + var containingTypeSymbol = explicitImpl?.ContainingType ?? methodSymbol.ContainingType; + var containingType = containingTypeSymbol.ToDisplayString( + SymbolDisplayFormat.FullyQualifiedFormat + ); + + // Method name should be simple name only (never include interface qualifier) + var declaredBaseName = methodSymbol.Name; + var lastDot = declaredBaseName.LastIndexOf('.'); + if (lastDot >= 0) + { + declaredBaseName = declaredBaseName.Substring(lastDot + 1); + } + + if (methodSymbol.TypeParameters.Length > 0) + { + var typeParams = string.Join( + ", ", + methodSymbol.TypeParameters.Select( + tp => tp.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + ) + ); + declaredBaseName += $"<{typeParams}>"; + } + + var returnType = methodSymbol.ReturnType.ToDisplayString( + SymbolDisplayFormat.FullyQualifiedFormat + ); + + var returnTypeInfo = methodSymbol.ReturnType.MetadataName switch + { + "Task" => ReturnTypeInfo.AsyncVoid, + "Task`1" or "ValueTask`1" => ReturnTypeInfo.AsyncResult, + _ => ReturnTypeInfo.Return, + }; + + var parameters = methodSymbol.Parameters.Select(ParseParameter).ToImmutableEquatableArray(); + + var isExplicit = isDerived || explicitImpl is not null; + var constraints = GenerateConstraints(methodSymbol.TypeParameters, isExplicit); + + return new MethodModel( + methodSymbol.Name, + returnType, + containingType, + declaredBaseName, + returnTypeInfo, + parameters, + constraints, + isExplicit + ); } private static bool IsRefitMethod( @@ -497,10 +592,33 @@ private static MethodModel ParseMethod(IMethodSymbol methodSymbol, bool isImplic SymbolDisplayFormat.FullyQualifiedFormat ); - var containingType = methodSymbol.ContainingType.ToDisplayString( + // For explicit interface implementations, the containing type for the explicit method signature + // must be the interface being implemented (e.g. IFoo), not the interface that declares it. + var explicitImpl = methodSymbol.ExplicitInterfaceImplementations.FirstOrDefault(); + var containingTypeSymbol = explicitImpl?.ContainingType ?? methodSymbol.ContainingType; + var containingType = containingTypeSymbol.ToDisplayString( SymbolDisplayFormat.FullyQualifiedFormat ); - var declaredMethod = methodSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + + // Simple method name (strip any explicit interface qualifier if present) + var declaredBaseName = methodSymbol.Name; + var lastDot = declaredBaseName.LastIndexOf('.'); + if (lastDot >= 0) + { + declaredBaseName = declaredBaseName.Substring(lastDot + 1); + } + + if (methodSymbol.TypeParameters.Length > 0) + { + var typeParams = string.Join( + ", ", + methodSymbol.TypeParameters.Select( + tp => tp.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + ) + ); + declaredBaseName += $"<{typeParams}>"; + } + var returnTypeInfo = methodSymbol.ReturnType.MetadataName switch { "Task" => ReturnTypeInfo.AsyncVoid, @@ -510,16 +628,18 @@ private static MethodModel ParseMethod(IMethodSymbol methodSymbol, bool isImplic var parameters = methodSymbol.Parameters.Select(ParseParameter).ToImmutableEquatableArray(); - var constraints = GenerateConstraints(methodSymbol.TypeParameters, !isImplicitInterface); + var isExplicit = explicitImpl is not null; + var constraints = GenerateConstraints(methodSymbol.TypeParameters, isExplicit || !isImplicitInterface); return new MethodModel( methodSymbol.Name, returnType, containingType, - declaredMethod, + declaredBaseName, returnTypeInfo, parameters, - constraints + constraints, + isExplicit ); } } diff --git a/InterfaceStubGenerator.Shared/Polyfills/IndexRange.cs b/InterfaceStubGenerator.Shared/Polyfills/IndexRange.cs new file mode 100644 index 000000000..15a772f37 --- /dev/null +++ b/InterfaceStubGenerator.Shared/Polyfills/IndexRange.cs @@ -0,0 +1,110 @@ +#if NETSTANDARD2_0 || NET462 +namespace System +{ + /// + /// Minimal polyfill for System.Index to support the C# index syntax when targeting + /// .NET Standard 2.0 or .NET Framework 4.6.2. This implementation only exposes the members + /// required by this codebase and is not a full replacement for the BCL type. + /// + /// + /// This type exists solely to allow the source to compile on older targets where + /// System.Index is not available. It should not be used as a general-purpose + /// substitute outside of this project. + /// + public readonly record struct Index + { + private readonly int _value; + private readonly bool _fromEnd; + + /// + /// Creates a new from the start of a sequence. + /// + /// The zero-based index from the start. + public Index(int value) { _value = value; _fromEnd = false; } + + /// + /// Creates a new with the specified origin. + /// + /// The index position value. + /// + /// When , the index is calculated from the end of the sequence; otherwise from the start. + /// + public Index(int value, bool fromEnd) { _value = value; _fromEnd = fromEnd; } + + /// + /// Gets the index value. + /// + public int Value => _value; + + /// + /// Gets a value indicating whether the index is from the end of the sequence. + /// + public bool IsFromEnd => _fromEnd; + + /// + /// Gets an that points to the start of a sequence. + /// + public static Index Start => new(0); + + /// + /// Gets an that points just past the end of a sequence. + /// + public static Index End => new(0, true); + + /// + /// Implicitly converts an to an from the start. + /// + /// The zero-based index from the start. + public static implicit operator Index(int value) => new(value); + } + + /// + /// Minimal polyfill for System.Range to support the C# range syntax when targeting + /// .NET Standard 2.0 or .NET Framework 4.6.2. This implementation only exposes the members + /// required by this codebase and is not a full replacement for the BCL type. + /// + /// + /// This type exists solely to allow the source to compile on older targets where + /// System.Range is not available. It should not be used as a general-purpose + /// substitute outside of this project. + /// + public readonly record struct Range + { + /// + /// Initializes a new instance of the struct. + /// + /// The inclusive start . + /// The exclusive end . + public Range(Index start, Index end) { Start = start; End = end; } + + /// + /// Gets the inclusive start of the range. + /// + public Index Start { get; } + + /// + /// Gets the exclusive end of the range. + /// + public Index End { get; } + + /// + /// Creates a that starts at the specified index and ends at . + /// + /// The inclusive start . + /// A new . + public static Range StartAt(Index start) => new(start, Index.End); + + /// + /// Creates a that starts at and ends at the specified index. + /// + /// The exclusive end . + /// A new . + public static Range EndAt(Index end) => new(Index.Start, end); + + /// + /// Gets a that represents the entire sequence. + /// + public static Range All => new(Index.Start, Index.End); + } +} +#endif diff --git a/Refit.GeneratorTests/Refit.GeneratorTests.csproj b/Refit.GeneratorTests/Refit.GeneratorTests.csproj index 70d202a36..688333a31 100644 --- a/Refit.GeneratorTests/Refit.GeneratorTests.csproj +++ b/Refit.GeneratorTests/Refit.GeneratorTests.csproj @@ -12,20 +12,20 @@ $(NoWarn);CS1591;CA1819;CA2000;CA2007;CA1056;CA1707;CA1861;xUnit1031 - + - + - + - + diff --git a/Refit.GeneratorTests/_snapshots/GeneratedTest.ShouldEmitAllFiles#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/GeneratedTest.ShouldEmitAllFiles#IGeneratedClient.g.verified.cs index cf4bd8e1e..13e4e6715 100644 --- a/Refit.GeneratorTests/_snapshots/GeneratedTest.ShouldEmitAllFiles#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/GeneratedTest.ShouldEmitAllFiles#IGeneratedClient.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.ContainedInterfaceTest#IContainedInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.ContainedInterfaceTest#IContainedInterface.g.verified.cs index 4dbdeb198..3c8871890 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.ContainedInterfaceTest#IContainedInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.ContainedInterfaceTest#IContainedInterface.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestContainerTypeIContainedInterface(global::System.Net.Htt return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.ContainerType.IContainedInterface.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.DefaultInterfaceMethod#IGeneratedInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.DefaultInterfaceMethod#IGeneratedInterface.g.verified.cs index 1b673f330..0445c5eb2 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.DefaultInterfaceMethod#IGeneratedInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.DefaultInterfaceMethod#IGeneratedInterface.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIGeneratedInterface(global::System.Net.Http.HttpClient return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedInterface.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.DerivedDefaultInterfaceMethod#IBaseInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.DerivedDefaultInterfaceMethod#IBaseInterface.g.verified.cs index 063b62640..9a3996e22 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.DerivedDefaultInterfaceMethod#IBaseInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.DerivedDefaultInterfaceMethod#IBaseInterface.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIBaseInterface(global::System.Net.Http.HttpClient clien return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IBaseInterface.GetPosts() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetPosts", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.DerivedDefaultInterfaceMethod#IGeneratedInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.DerivedDefaultInterfaceMethod#IGeneratedInterface.g.verified.cs index 9cb1c45fa..1657d578a 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.DerivedDefaultInterfaceMethod#IGeneratedInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.DerivedDefaultInterfaceMethod#IGeneratedInterface.g.verified.cs @@ -37,15 +37,6 @@ public RefitGeneratorTestIGeneratedInterface(global::System.Net.Http.HttpClient return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedInterface.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - /// async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IBaseInterface.GetPosts() { diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.DisposableTest#IGeneratedInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.DisposableTest#IGeneratedInterface.g.verified.cs index ad4d825b5..86a7f792f 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.DisposableTest#IGeneratedInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.DisposableTest#IGeneratedInterface.g.verified.cs @@ -37,15 +37,6 @@ public IGeneratedInterface(global::System.Net.Http.HttpClient client, global::Re return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - /// - async global::System.Threading.Tasks.Task global::IGeneratedInterface.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - /// void global::System.IDisposable.Dispose() { diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.GlobalNamespaceTest#IGeneratedInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.GlobalNamespaceTest#IGeneratedInterface.g.verified.cs index 8898f89da..283467dd9 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.GlobalNamespaceTest#IGeneratedInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.GlobalNamespaceTest#IGeneratedInterface.g.verified.cs @@ -36,15 +36,6 @@ public IGeneratedInterface(global::System.Net.Http.HttpClient client, global::Re return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::IGeneratedInterface.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfaceDerivedFromRefitBaseTest#IBaseInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfaceDerivedFromRefitBaseTest#IBaseInterface.g.verified.cs index 1fdef57d0..14b2eba91 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfaceDerivedFromRefitBaseTest#IBaseInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfaceDerivedFromRefitBaseTest#IBaseInterface.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIBaseInterface(global::System.Net.Http.HttpClient clien return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IBaseInterface.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfaceWithGenericConstraint#IGeneratedInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfaceWithGenericConstraint#IGeneratedInterface.g.verified.cs index 74cfe8256..5138d4bb8 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfaceWithGenericConstraint#IGeneratedInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfaceWithGenericConstraint#IGeneratedInterface.g.verified.cs @@ -41,15 +41,6 @@ public IGeneratedInterface(global::System.Net.Http.HttpClient client, global::Re return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::IGeneratedInterface.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentCasing#IApi.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentCasing#IApi.g.verified.cs index 95d2ad750..f7094ab77 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentCasing#IApi.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentCasing#IApi.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIApi(global::System.Net.Http.HttpClient client, global: return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IApi.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentCasing#Iapi1.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentCasing#Iapi1.g.verified.cs index 69d01c015..c8252eaa6 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentCasing#Iapi1.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentCasing#Iapi1.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIapi(global::System.Net.Http.HttpClient client, global: return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.Iapi.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentSignature#IApi.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentSignature#IApi.g.verified.cs index 95d2ad750..f7094ab77 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentSignature#IApi.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentSignature#IApi.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIApi(global::System.Net.Http.HttpClient client, global: return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IApi.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentSignature#IApi1.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentSignature#IApi1.g.verified.cs index 50d79cefb..662df620f 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentSignature#IApi1.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.InterfacesWithDifferentSignature#IApi1.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIApi(global::System.Net.Http.HttpClient client, global: return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IApi.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.NestedNamespaceTest#IGeneratedInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.NestedNamespaceTest#IGeneratedInterface.g.verified.cs index 30c264ff8..5f1cb1d44 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.NestedNamespaceTest#IGeneratedInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.NestedNamespaceTest#IGeneratedInterface.g.verified.cs @@ -36,15 +36,6 @@ public NestedRefitGeneratorTestIGeneratedInterface(global::System.Net.Http.HttpC return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::Nested.RefitGeneratorTest.IGeneratedInterface.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.NonRefitMethodShouldRaiseDiagnostic#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.NonRefitMethodShouldRaiseDiagnostic#IGeneratedClient.g.verified.cs index 52abe662f..d221572ff 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.NonRefitMethodShouldRaiseDiagnostic#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.NonRefitMethodShouldRaiseDiagnostic#IGeneratedClient.g.verified.cs @@ -38,16 +38,7 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli } /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - /// - void global::RefitGeneratorTest.IGeneratedClient.NonRefitMethod() + public void NonRefitMethod() { throw new global::System.NotImplementedException("Either this method has no Refit HTTP method attribute or you've used something other than a string literal for the 'path' argument."); } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromBaseTest#IGeneratedInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromBaseTest#IGeneratedInterface.g.verified.cs index dcafe653f..a5fa1d22a 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromBaseTest#IGeneratedInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromBaseTest#IGeneratedInterface.g.verified.cs @@ -37,15 +37,6 @@ public RefitGeneratorTestIGeneratedInterface(global::System.Net.Http.HttpClient return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedInterface.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - /// void global::RefitGeneratorTest.IBaseInterface.NonRefitMethod() { diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromRefitBaseTest#IBaseInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromRefitBaseTest#IBaseInterface.g.verified.cs index 063b62640..9a3996e22 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromRefitBaseTest#IBaseInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromRefitBaseTest#IBaseInterface.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIBaseInterface(global::System.Net.Http.HttpClient clien return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IBaseInterface.GetPosts() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetPosts", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromRefitBaseTest#IGeneratedInterface.g.verified.cs b/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromRefitBaseTest#IGeneratedInterface.g.verified.cs index 9cb1c45fa..1657d578a 100644 --- a/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromRefitBaseTest#IGeneratedInterface.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/InterfaceTests.RefitInterfaceDerivedFromRefitBaseTest#IGeneratedInterface.g.verified.cs @@ -37,15 +37,6 @@ public RefitGeneratorTestIGeneratedInterface(global::System.Net.Http.HttpClient return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedInterface.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - /// async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IBaseInterface.GetPosts() { diff --git a/Refit.GeneratorTests/_snapshots/MethodTests.MethodsWithGenericConstraints#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/MethodTests.MethodsWithGenericConstraints#IGeneratedClient.g.verified.cs index 904f8e427..149ea20f6 100644 --- a/Refit.GeneratorTests/_snapshots/MethodTests.MethodsWithGenericConstraints#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/MethodTests.MethodsWithGenericConstraints#IGeneratedClient.g.verified.cs @@ -43,22 +43,12 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli } /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get() - where T1 : class - where T3 : struct - where T5 : class - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty(), new global::System.Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) } ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - /// - void global::RefitGeneratorTest.IGeneratedClient.NonRefitMethod() + public void NonRefitMethod() where T1 : class + where T2 : unmanaged where T3 : struct - where T5 : class + where T4 : notnull + where T5 : class, global::System.IDisposable, new() { throw new global::System.NotImplementedException("Either this method has no Refit HTTP method attribute or you've used something other than a string literal for the 'path' argument."); } diff --git a/Refit.GeneratorTests/_snapshots/ParameterTests.NullableRouteParameter#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ParameterTests.NullableRouteParameter#IGeneratedClient.g.verified.cs index 2156a7cf8..08eb2f630 100644 --- a/Refit.GeneratorTests/_snapshots/ParameterTests.NullableRouteParameter#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ParameterTests.NullableRouteParameter#IGeneratedClient.g.verified.cs @@ -38,17 +38,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - private static readonly global::System.Type[] ______typeParameters0 = new global::System.Type[] {typeof(string) }; - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get(string? @user) - { - var ______arguments = new object[] { @user }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", ______typeParameters0 ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ParameterTests.NullableValueTypeRouteParameter#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ParameterTests.NullableValueTypeRouteParameter#IGeneratedClient.g.verified.cs index 1b3eb9d15..aa000d400 100644 --- a/Refit.GeneratorTests/_snapshots/ParameterTests.NullableValueTypeRouteParameter#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ParameterTests.NullableValueTypeRouteParameter#IGeneratedClient.g.verified.cs @@ -38,17 +38,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - private static readonly global::System.Type[] ______typeParameters0 = new global::System.Type[] {typeof(int?) }; - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get(int? @user) - { - var ______arguments = new object[] { @user }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", ______typeParameters0 ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ParameterTests.RouteParameter#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ParameterTests.RouteParameter#IGeneratedClient.g.verified.cs index c6b644a1c..7aad65b94 100644 --- a/Refit.GeneratorTests/_snapshots/ParameterTests.RouteParameter#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ParameterTests.RouteParameter#IGeneratedClient.g.verified.cs @@ -38,17 +38,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - private static readonly global::System.Type[] ______typeParameters0 = new global::System.Type[] {typeof(string) }; - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get(string @user) - { - var ______arguments = new object[] { @user }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", ______typeParameters0 ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameter#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameter#IGeneratedClient.g.verified.cs index f95e97ded..ba81410dc 100644 --- a/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameter#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameter#IGeneratedClient.g.verified.cs @@ -38,17 +38,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - private static readonly global::System.Type[] ______typeParameters0 = new global::System.Type[] {typeof(int) }; - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get(int @user) - { - var ______arguments = new object[] { @user }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", ______typeParameters0 ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericConstraintReturnTask#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericConstraintReturnTask#IGeneratedClient.g.verified.cs index f42908c61..0f7f6a710 100644 --- a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericConstraintReturnTask#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericConstraintReturnTask#IGeneratedClient.g.verified.cs @@ -37,16 +37,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get() - where T : class - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty(), new global::System.Type[] { typeof(T) } ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericStructConstraintReturnTask#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericStructConstraintReturnTask#IGeneratedClient.g.verified.cs index 36f015960..b34478645 100644 --- a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericStructConstraintReturnTask#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericStructConstraintReturnTask#IGeneratedClient.g.verified.cs @@ -37,16 +37,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get() - where T : struct - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty(), new global::System.Type[] { typeof(T) } ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericTaskShouldWork#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericTaskShouldWork#IGeneratedClient.g.verified.cs index cf4bd8e1e..13e4e6715 100644 --- a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericTaskShouldWork#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericTaskShouldWork#IGeneratedClient.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericUnmanagedConstraintReturnTask#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericUnmanagedConstraintReturnTask#IGeneratedClient.g.verified.cs index 534764c6a..ce70ee952 100644 --- a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericUnmanagedConstraintReturnTask#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.GenericUnmanagedConstraintReturnTask#IGeneratedClient.g.verified.cs @@ -37,15 +37,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty(), new global::System.Type[] { typeof(T) } ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnIObservable#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnIObservable#IGeneratedClient.g.verified.cs index 9403e5d7e..2d675affb 100644 --- a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnIObservable#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnIObservable#IGeneratedClient.g.verified.cs @@ -38,17 +38,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return (global::System.IObservable)______func(this.Client, ______arguments); } - - private static readonly global::System.Type[] ______typeParameters0 = new global::System.Type[] {typeof(string) }; - - /// - global::System.IObservable global::RefitGeneratorTest.IGeneratedClient.GetUser(string @user) - { - var ______arguments = new object[] { @user }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetUser", ______typeParameters0 ); - - return (global::System.IObservable)______func(this.Client, ______arguments); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnNullableObject#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnNullableObject#IGeneratedClient.g.verified.cs index cf4bd8e1e..13e4e6715 100644 --- a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnNullableObject#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnNullableObject#IGeneratedClient.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnNullableValueType#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnNullableValueType#IGeneratedClient.g.verified.cs index 22fc97efc..79d9d861b 100644 --- a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnNullableValueType#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnNullableValueType#IGeneratedClient.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Get() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Get", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnUnsupportedType#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnUnsupportedType#IGeneratedClient.g.verified.cs index bd5ad4aaf..ee18b4f8d 100644 --- a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnUnsupportedType#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.ReturnUnsupportedType#IGeneratedClient.g.verified.cs @@ -38,17 +38,6 @@ public string GetUser(string @user) return (string)______func(this.Client, ______arguments); } - - private static readonly global::System.Type[] ______typeParameters0 = new global::System.Type[] {typeof(string) }; - - /// - string global::RefitGeneratorTest.IGeneratedClient.GetUser(string @user) - { - var ______arguments = new object[] { @user }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetUser", ______typeParameters0 ); - - return (string)______func(this.Client, ______arguments); - } } } } diff --git a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.VoidTaskShouldWork#IGeneratedClient.g.verified.cs b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.VoidTaskShouldWork#IGeneratedClient.g.verified.cs index 3242d081d..b7c48fa53 100644 --- a/Refit.GeneratorTests/_snapshots/ReturnTypeTests.VoidTaskShouldWork#IGeneratedClient.g.verified.cs +++ b/Refit.GeneratorTests/_snapshots/ReturnTypeTests.VoidTaskShouldWork#IGeneratedClient.g.verified.cs @@ -36,15 +36,6 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::RefitGeneratorTest.IGeneratedClient.Post() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("Post", global::System.Array.Empty() ); - - await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.HttpClientFactory/HttpClientFactoryExtensions.cs b/Refit.HttpClientFactory/HttpClientFactoryExtensions.cs index 8c39372be..ff188bf9c 100644 --- a/Refit.HttpClientFactory/HttpClientFactoryExtensions.cs +++ b/Refit.HttpClientFactory/HttpClientFactoryExtensions.cs @@ -213,10 +213,9 @@ public static IHttpClientBuilder AddRefitClient( .MakeGenericMethod(refitInterfaceType) .Invoke( null, - new object?[] - { + [ ((ISettingsFor)provider.GetRequiredService(settingsType)).Settings - } + ] )! ); @@ -284,10 +283,9 @@ public static IHttpClientBuilder AddKeyedRefitClient( .MakeGenericMethod(refitInterfaceType) .Invoke( null, - new object?[] - { + [ ((ISettingsFor)provider.GetRequiredKeyedService(settingsType, serviceKey)).Settings - } + ] )! ); diff --git a/Refit.Tests/API/_snapshots/ApiApprovalTests.Refit.DotNet10_0.verified.txt b/Refit.Tests/API/_snapshots/ApiApprovalTests.Refit.DotNet10_0.verified.txt new file mode 100644 index 000000000..bbb331d37 --- /dev/null +++ b/Refit.Tests/API/_snapshots/ApiApprovalTests.Refit.DotNet10_0.verified.txt @@ -0,0 +1,435 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Newtonsoft.Json")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Xml")] +[assembly: System.Runtime.Versioning.TargetFramework(".NETCoreApp,Version=v10.0", FrameworkDisplayName=".NET 10.0")] +namespace Refit +{ + [System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Parameter)] + public class AliasAsAttribute : System.Attribute + { + public AliasAsAttribute(string name) { } + public string Name { get; protected set; } + } + [System.Serializable] + public class ApiException : System.Exception + { + protected ApiException(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, string? content, System.Net.HttpStatusCode statusCode, string? reasonPhrase, System.Net.Http.Headers.HttpResponseHeaders headers, Refit.RefitSettings refitSettings, System.Exception? innerException = null) { } + protected ApiException(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, string? content, System.Net.HttpStatusCode statusCode, string? reasonPhrase, System.Net.Http.Headers.HttpResponseHeaders headers, Refit.RefitSettings refitSettings, System.Exception? innerException = null) { } + public string? Content { get; } + public System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; } + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] + public bool HasContent { get; } + public System.Net.Http.Headers.HttpResponseHeaders Headers { get; } + public System.Net.Http.HttpMethod HttpMethod { get; } + public string? ReasonPhrase { get; } + public Refit.RefitSettings RefitSettings { get; } + public System.Net.Http.HttpRequestMessage RequestMessage { get; } + public System.Net.HttpStatusCode StatusCode { get; } + public System.Uri? Uri { get; } + public System.Threading.Tasks.Task GetContentAsAsync() { } + public static System.Threading.Tasks.Task Create(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, System.Net.Http.HttpResponseMessage response, Refit.RefitSettings refitSettings, System.Exception? innerException = null) { } + public static System.Threading.Tasks.Task Create(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, System.Net.Http.HttpResponseMessage response, Refit.RefitSettings refitSettings, System.Exception? innerException = null) { } + } + public sealed class ApiResponse : Refit.IApiResponse, Refit.IApiResponse, System.IDisposable + { + public ApiResponse(System.Net.Http.HttpResponseMessage response, T? content, Refit.RefitSettings settings, Refit.ApiException? error = null) { } + public T Content { get; } + public System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; } + public Refit.ApiException? Error { get; } + public System.Net.Http.Headers.HttpResponseHeaders Headers { get; } + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + public bool IsSuccessStatusCode { get; } + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + public bool IsSuccessful { get; } + public string? ReasonPhrase { get; } + public System.Net.Http.HttpRequestMessage? RequestMessage { get; } + public Refit.RefitSettings Settings { get; } + public System.Net.HttpStatusCode StatusCode { get; } + public System.Version Version { get; } + public void Dispose() { } + public System.Threading.Tasks.Task> EnsureSuccessStatusCodeAsync() { } + public System.Threading.Tasks.Task> EnsureSuccessfulAsync() { } + } + [System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Parameter)] + [System.Obsolete("Use Refit.StreamPart, Refit.ByteArrayPart, Refit.FileInfoPart or if necessary, in" + + "herit from Refit.MultipartItem", false)] + public class AttachmentNameAttribute : System.Attribute + { + public AttachmentNameAttribute(string name) { } + public string Name { get; protected set; } + } + [System.AttributeUsage(System.AttributeTargets.Parameter)] + public class AuthorizeAttribute : System.Attribute + { + public AuthorizeAttribute(string scheme = "Bearer") { } + public string Scheme { get; } + } + [System.AttributeUsage(System.AttributeTargets.Parameter)] + public class BodyAttribute : System.Attribute + { + public BodyAttribute() { } + public BodyAttribute(Refit.BodySerializationMethod serializationMethod = 0) { } + public BodyAttribute(bool buffered) { } + public BodyAttribute(Refit.BodySerializationMethod serializationMethod, bool buffered) { } + public bool? Buffered { get; } + public Refit.BodySerializationMethod SerializationMethod { get; } + } + public enum BodySerializationMethod + { + Default = 0, + [System.Obsolete("Use BodySerializationMethod.Serialized instead", false)] + Json = 1, + UrlEncoded = 2, + Serialized = 3, + } + public class ByteArrayPart : Refit.MultipartItem + { + public ByteArrayPart(byte[] value, string fileName, string? contentType = null, string? name = null) { } + public byte[] Value { get; } + protected override System.Net.Http.HttpContent CreateContent() { } + } + public class CamelCaseUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter + { + public CamelCaseUrlParameterKeyFormatter() { } + public string Format(string key) { } + } + public enum CollectionFormat + { + RefitParameterFormatter = 0, + Csv = 1, + Ssv = 2, + Tsv = 3, + Pipes = 4, + Multi = 5, + } + public class DefaultApiExceptionFactory + { + public DefaultApiExceptionFactory(Refit.RefitSettings refitSettings) { } + public System.Threading.Tasks.Task CreateAsync(System.Net.Http.HttpResponseMessage responseMessage) { } + } + public class DefaultFormUrlEncodedParameterFormatter : Refit.IFormUrlEncodedParameterFormatter + { + public DefaultFormUrlEncodedParameterFormatter() { } + public virtual string? Format(object? parameterValue, string? formatString) { } + } + public class DefaultUrlParameterFormatter : Refit.IUrlParameterFormatter + { + public DefaultUrlParameterFormatter() { } + public void AddFormat(string format) { } + public void AddFormat(string format) { } + public virtual string? Format(object? parameterValue, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + } + public class DefaultUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter + { + public DefaultUrlParameterKeyFormatter() { } + public virtual string Format(string key) { } + } + [System.AttributeUsage(System.AttributeTargets.Method)] + public class DeleteAttribute : Refit.HttpMethodAttribute + { + public DeleteAttribute(string path) { } + public override System.Net.Http.HttpMethod Method { get; } + } + public class FileInfoPart : Refit.MultipartItem + { + public FileInfoPart(System.IO.FileInfo value, string fileName, string? contentType = null, string? name = null) { } + public System.IO.FileInfo Value { get; } + protected override System.Net.Http.HttpContent CreateContent() { } + } + [System.AttributeUsage(System.AttributeTargets.Method)] + public class GetAttribute : Refit.HttpMethodAttribute + { + public GetAttribute(string path) { } + public override System.Net.Http.HttpMethod Method { get; } + } + [System.AttributeUsage(System.AttributeTargets.Method)] + public class HeadAttribute : Refit.HttpMethodAttribute + { + public HeadAttribute(string path) { } + public override System.Net.Http.HttpMethod Method { get; } + } + [System.AttributeUsage(System.AttributeTargets.Parameter)] + public class HeaderAttribute : System.Attribute + { + public HeaderAttribute(string header) { } + public string Header { get; } + } + [System.AttributeUsage(System.AttributeTargets.Parameter)] + public class HeaderCollectionAttribute : System.Attribute + { + public HeaderCollectionAttribute() { } + } + [System.AttributeUsage(System.AttributeTargets.Method | System.AttributeTargets.Interface)] + public class HeadersAttribute : System.Attribute + { + public HeadersAttribute(params string[] headers) { } + public string[] Headers { get; } + } + public abstract class HttpMethodAttribute : System.Attribute + { + protected HttpMethodAttribute(string path) { } + public abstract System.Net.Http.HttpMethod Method { get; } + public virtual string Path { get; protected set; } + } + public static class HttpRequestMessageOptions + { + public static string InterfaceType { get; } + public static string RestMethodInfo { get; } + } + public interface IApiResponse : System.IDisposable + { + System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; } + Refit.ApiException? Error { get; } + System.Net.Http.Headers.HttpResponseHeaders Headers { get; } + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + bool IsSuccessStatusCode { get; } + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + bool IsSuccessful { get; } + string? ReasonPhrase { get; } + System.Net.Http.HttpRequestMessage? RequestMessage { get; } + System.Net.HttpStatusCode StatusCode { get; } + System.Version Version { get; } + } + public interface IApiResponse : Refit.IApiResponse, System.IDisposable + { + T Content { get; } + new System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; } + new Refit.ApiException? Error { get; } + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + new bool IsSuccessStatusCode { get; } + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] + [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(false, "Error")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] + [get: System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "ContentHeaders")] + new bool IsSuccessful { get; } + } + public interface IFormUrlEncodedParameterFormatter + { + string? Format(object? value, string? formatString); + } + public interface IHttpContentSerializer + { + System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default); + string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo); + System.Net.Http.HttpContent ToHttpContent(T item); + } + public interface IRequestBuilder + { + System.Func BuildRestResultFuncForMethod(string methodName, System.Type[]? parameterTypes = null, System.Type[]? genericArgumentTypes = null); + } + public interface IRequestBuilder : Refit.IRequestBuilder { } + public interface IUrlParameterFormatter + { + string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type); + } + public interface IUrlParameterKeyFormatter + { + string Format(string key); + } + [System.Obsolete("Use NewtonsoftJsonContentSerializer in the Refit.Newtonsoft.Json package instead", true)] + public class JsonContentSerializer : Refit.IHttpContentSerializer + { + public JsonContentSerializer() { } + public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } + public string GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } + public System.Net.Http.HttpContent ToHttpContent(T item) { } + } + [System.AttributeUsage(System.AttributeTargets.Method)] + public class MultipartAttribute : System.Attribute + { + public MultipartAttribute(string boundaryText = "----MyGreatBoundary") { } + public string BoundaryText { get; } + } + public abstract class MultipartItem + { + protected MultipartItem(string fileName, string? contentType) { } + public MultipartItem(string fileName, string? contentType, string? name) { } + public string? ContentType { get; } + public string FileName { get; } + public string? Name { get; } + protected abstract System.Net.Http.HttpContent CreateContent(); + public System.Net.Http.HttpContent ToContent() { } + } + public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter + { + public ObjectToInferredTypesConverter() { } + public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } + public override void Write(System.Text.Json.Utf8JsonWriter writer, object objectToWrite, System.Text.Json.JsonSerializerOptions options) { } + } + [System.AttributeUsage(System.AttributeTargets.Method)] + public class OptionsAttribute : Refit.HttpMethodAttribute + { + public OptionsAttribute(string path) { } + public override System.Net.Http.HttpMethod Method { get; } + } + public enum ParameterType + { + Normal = 0, + RoundTripping = 1, + } + [System.AttributeUsage(System.AttributeTargets.Method)] + public class PatchAttribute : Refit.HttpMethodAttribute + { + public PatchAttribute(string path) { } + public override System.Net.Http.HttpMethod Method { get; } + } + [System.AttributeUsage(System.AttributeTargets.Method)] + public class PostAttribute : Refit.HttpMethodAttribute + { + public PostAttribute(string path) { } + public override System.Net.Http.HttpMethod Method { get; } + } + public class ProblemDetails + { + public ProblemDetails() { } + public string? Detail { get; set; } + public System.Collections.Generic.Dictionary Errors { get; set; } + [System.Text.Json.Serialization.JsonExtensionData] + public System.Collections.Generic.IDictionary Extensions { get; set; } + public string? Instance { get; set; } + public int Status { get; set; } + public string? Title { get; set; } + public string? Type { get; set; } + } + [System.AttributeUsage(System.AttributeTargets.Parameter)] + public class PropertyAttribute : System.Attribute + { + public PropertyAttribute() { } + public PropertyAttribute(string key) { } + public string? Key { get; } + } + [System.AttributeUsage(System.AttributeTargets.Method)] + public class PutAttribute : Refit.HttpMethodAttribute + { + public PutAttribute(string path) { } + public override System.Net.Http.HttpMethod Method { get; } + } + [System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Parameter)] + public class QueryAttribute : System.Attribute + { + public QueryAttribute() { } + public QueryAttribute(Refit.CollectionFormat collectionFormat) { } + public QueryAttribute(string delimiter) { } + public QueryAttribute(string delimiter, string prefix) { } + public QueryAttribute(string delimiter, string prefix, string format) { } + public Refit.CollectionFormat CollectionFormat { get; set; } + public string Delimiter { get; protected set; } + public string? Format { get; set; } + public bool IsCollectionFormatSpecified { get; } + public string? Prefix { get; protected set; } + public bool TreatAsString { get; set; } + } + [System.AttributeUsage(System.AttributeTargets.Method)] + public class QueryUriFormatAttribute : System.Attribute + { + public QueryUriFormatAttribute(System.UriFormat uriFormat) { } + public System.UriFormat UriFormat { get; } + } + public class RefitSettings + { + public RefitSettings() { } + public RefitSettings(Refit.IHttpContentSerializer contentSerializer, Refit.IUrlParameterFormatter? urlParameterFormatter, Refit.IFormUrlEncodedParameterFormatter? formUrlEncodedParameterFormatter) { } + public RefitSettings(Refit.IHttpContentSerializer contentSerializer, Refit.IUrlParameterFormatter? urlParameterFormatter = null, Refit.IFormUrlEncodedParameterFormatter? formUrlEncodedParameterFormatter = null, Refit.IUrlParameterKeyFormatter? urlParameterKeyFormatter = null) { } + public System.Func>? AuthorizationHeaderValueGetter { get; set; } + public bool Buffered { get; set; } + public Refit.CollectionFormat CollectionFormat { get; set; } + public Refit.IHttpContentSerializer ContentSerializer { get; set; } + public System.Func>? DeserializationExceptionFactory { get; set; } + public System.Func> ExceptionFactory { get; set; } + public Refit.IFormUrlEncodedParameterFormatter FormUrlEncodedParameterFormatter { get; set; } + public System.Func? HttpMessageHandlerFactory { get; set; } + public System.Collections.Generic.Dictionary? HttpRequestMessageOptions { get; set; } + public Refit.IUrlParameterFormatter UrlParameterFormatter { get; set; } + public Refit.IUrlParameterKeyFormatter UrlParameterKeyFormatter { get; set; } + public System.Version Version { get; set; } + public System.Net.Http.HttpVersionPolicy VersionPolicy { get; set; } + } + public static class RequestBuilder + { + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public static Refit.IRequestBuilder ForType() { } + public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } + } + public class RestMethodInfo : System.IEquatable + { + public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } + public System.Type HostingType { get; init; } + public System.Reflection.MethodInfo MethodInfo { get; init; } + public string Name { get; init; } + public string RelativePath { get; init; } + public System.Type ReturnType { get; init; } + } + public class RestMethodParameterInfo + { + public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } + public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } + public bool IsObjectPropertyParameter { get; set; } + public string? Name { get; set; } + public System.Reflection.ParameterInfo ParameterInfo { get; set; } + public System.Collections.Generic.List ParameterProperties { get; set; } + public Refit.ParameterType Type { get; set; } + } + public class RestMethodParameterProperty + { + public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } + public string Name { get; set; } + public System.Reflection.PropertyInfo PropertyInfo { get; set; } + } + public static class RestService + { + public static System.Net.Http.HttpClient CreateHttpClient(string hostUrl, Refit.RefitSettings? settings) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } + public static object For(System.Type refitInterfaceType, string hostUrl) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } + public static T For(System.Net.Http.HttpClient client) { } + public static T For(string hostUrl) { } + public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + public static T For(string hostUrl, Refit.RefitSettings? settings) { } + } + public class StreamPart : Refit.MultipartItem + { + public StreamPart(System.IO.Stream value, string fileName, string? contentType = null, string? name = null) { } + public System.IO.Stream Value { get; } + protected override System.Net.Http.HttpContent CreateContent() { } + } + public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializer + { + public SystemTextJsonContentSerializer() { } + public SystemTextJsonContentSerializer(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } + public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } + public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } + public System.Net.Http.HttpContent ToHttpContent(T item) { } + public static System.Text.Json.JsonSerializerOptions GetDefaultJsonSerializerOptions() { } + } + [System.Serializable] + public class ValidationApiException : Refit.ApiException + { + public new Refit.ProblemDetails? Content { get; } + public static Refit.ValidationApiException Create(Refit.ApiException exception) { } + } +} \ No newline at end of file diff --git a/Refit.Tests/ExplicitInterfaceRefitTests.cs b/Refit.Tests/ExplicitInterfaceRefitTests.cs new file mode 100644 index 000000000..1e1e30e32 --- /dev/null +++ b/Refit.Tests/ExplicitInterfaceRefitTests.cs @@ -0,0 +1,67 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Refit; +using RichardSzalay.MockHttp; +using Xunit; + +namespace Refit.Tests; + +public class ExplicitInterfaceRefitTests +{ + public interface IFoo + { + int Bar(); + } + + // Internal interface with a default implementation of IFoo.Bar that calls an internal Refit method + internal interface IInternalFoo : IFoo + { + int IFoo.Bar() => InternalBar() + 1; + + [Get("/bar")] + internal int InternalBar(); + } + + // Derived interface that explicitly implements IFoo.Bar and marks it as a Refit method + public interface IRemoteFoo2 : IFoo + { + [Get("/bar")] + abstract int IFoo.Bar(); + } + + [Fact] + public void DefaultInterfaceImplementation_calls_internal_refit_method() + { + var mockHttp = new MockHttpMessageHandler(); + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; + + mockHttp + .Expect(HttpMethod.Get, "http://foo/bar") + .Respond("application/json", "41"); + + var fixture = RestService.For("http://foo", settings); + + var result = ((IFoo)fixture).Bar(); + Assert.Equal(42, result); + + mockHttp.VerifyNoOutstandingExpectation(); + } + + [Fact] + public void Explicit_interface_member_with_refit_attribute_is_invoked() + { + var mockHttp = new MockHttpMessageHandler(); + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp }; + + mockHttp + .Expect(HttpMethod.Get, "http://foo/bar") + .Respond("application/json", "41"); + + var fixture = RestService.For("http://foo", settings); + + var result = ((IFoo)fixture).Bar(); + Assert.Equal(41, result); + + mockHttp.VerifyNoOutstandingExpectation(); + } +} diff --git a/Refit.Tests/Refit.Tests.csproj b/Refit.Tests/Refit.Tests.csproj index 762357630..a48371a17 100644 --- a/Refit.Tests/Refit.Tests.csproj +++ b/Refit.Tests/Refit.Tests.csproj @@ -3,7 +3,7 @@ - net48;net8.0;net9.0 + $(RefitTestTargets) false https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json @@ -16,16 +16,19 @@ - + - + + + + - + - + diff --git a/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#IGitHubApi.g.verified.cs b/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#IGitHubApi.g.verified.cs index e1f3523ac..d369011a2 100644 --- a/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#IGitHubApi.g.verified.cs +++ b/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#IGitHubApi.g.verified.cs @@ -173,152 +173,6 @@ public RefitTestsIGitHubApi(global::System.Net.Http.HttpClient client, global::R return await ((global::System.Threading.Tasks.Task>)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - private static readonly global::System.Type[] ______typeParameters9 = new global::System.Type[] {typeof(string) }; - - /// - async global::System.Threading.Tasks.Task global::Refit.Tests.IGitHubApi.GetUser(string @userName) - { - var ______arguments = new object[] { @userName }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetUser", ______typeParameters9 ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - private static readonly global::System.Type[] ______typeParameters10 = new global::System.Type[] {typeof(string) }; - - /// - global::System.IObservable global::Refit.Tests.IGitHubApi.GetUserObservable(string @userName) - { - var ______arguments = new object[] { @userName }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetUserObservable", ______typeParameters10 ); - - return (global::System.IObservable)______func(this.Client, ______arguments); - } - - private static readonly global::System.Type[] ______typeParameters11 = new global::System.Type[] {typeof(string) }; - - /// - global::System.IObservable global::Refit.Tests.IGitHubApi.GetUserCamelCase(string @userName) - { - var ______arguments = new object[] { @userName }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetUserCamelCase", ______typeParameters11 ); - - return (global::System.IObservable)______func(this.Client, ______arguments); - } - - private static readonly global::System.Type[] ______typeParameters12 = new global::System.Type[] {typeof(string), typeof(global::System.Threading.CancellationToken) }; - - /// - async global::System.Threading.Tasks.Task> global::Refit.Tests.IGitHubApi.GetOrgMembers(string @orgName, global::System.Threading.CancellationToken @cancellationToken) - { - var ______arguments = new object[] { @orgName, @cancellationToken }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetOrgMembers", ______typeParameters12 ); - - return await ((global::System.Threading.Tasks.Task>)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - private static readonly global::System.Type[] ______typeParameters13 = new global::System.Type[] {typeof(string) }; - - /// - async global::System.Threading.Tasks.Task global::Refit.Tests.IGitHubApi.FindUsers(string @q) - { - var ______arguments = new object[] { @q }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("FindUsers", ______typeParameters13 ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - /// - async global::System.Threading.Tasks.Task global::Refit.Tests.IGitHubApi.GetIndex() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetIndex", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - /// - global::System.IObservable global::Refit.Tests.IGitHubApi.GetIndexObservable() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetIndexObservable", global::System.Array.Empty() ); - - return (global::System.IObservable)______func(this.Client, ______arguments); - } - - /// - async global::System.Threading.Tasks.Task global::Refit.Tests.IGitHubApi.NothingToSeeHere() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("NothingToSeeHere", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - /// - async global::System.Threading.Tasks.Task> global::Refit.Tests.IGitHubApi.NothingToSeeHereWithMetadata() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("NothingToSeeHereWithMetadata", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task>)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - private static readonly global::System.Type[] ______typeParameters14 = new global::System.Type[] {typeof(string) }; - - /// - async global::System.Threading.Tasks.Task> global::Refit.Tests.IGitHubApi.GetUserWithMetadata(string @userName) - { - var ______arguments = new object[] { @userName }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetUserWithMetadata", ______typeParameters14 ); - - return await ((global::System.Threading.Tasks.Task>)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - private static readonly global::System.Type[] ______typeParameters15 = new global::System.Type[] {typeof(string) }; - - /// - global::System.IObservable> global::Refit.Tests.IGitHubApi.GetUserObservableWithMetadata(string @userName) - { - var ______arguments = new object[] { @userName }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetUserObservableWithMetadata", ______typeParameters15 ); - - return (global::System.IObservable>)______func(this.Client, ______arguments); - } - - private static readonly global::System.Type[] ______typeParameters16 = new global::System.Type[] {typeof(string) }; - - /// - global::System.IObservable> global::Refit.Tests.IGitHubApi.GetUserIApiResponseObservableWithMetadata(string @userName) - { - var ______arguments = new object[] { @userName }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetUserIApiResponseObservableWithMetadata", ______typeParameters16 ); - - return (global::System.IObservable>)______func(this.Client, ______arguments); - } - - private static readonly global::System.Type[] ______typeParameters17 = new global::System.Type[] {typeof(global::Refit.Tests.User) }; - - /// - async global::System.Threading.Tasks.Task global::Refit.Tests.IGitHubApi.CreateUser(global::Refit.Tests.User @user) - { - var ______arguments = new object[] { @user }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("CreateUser", ______typeParameters17 ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - private static readonly global::System.Type[] ______typeParameters18 = new global::System.Type[] {typeof(global::Refit.Tests.User) }; - - /// - async global::System.Threading.Tasks.Task> global::Refit.Tests.IGitHubApi.CreateUserWithMetadata(global::Refit.Tests.User @user) - { - var ______arguments = new object[] { @user }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("CreateUserWithMetadata", ______typeParameters18 ); - - return await ((global::System.Threading.Tasks.Task>)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#IGitHubApiDisposable.g.verified.cs b/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#IGitHubApiDisposable.g.verified.cs index 03c579cf4..ae11f238a 100644 --- a/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#IGitHubApiDisposable.g.verified.cs +++ b/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#IGitHubApiDisposable.g.verified.cs @@ -37,15 +37,6 @@ public RefitTestsIGitHubApiDisposable(global::System.Net.Http.HttpClient client, await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - /// - async global::System.Threading.Tasks.Task global::Refit.Tests.IGitHubApiDisposable.RefitMethod() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("RefitMethod", global::System.Array.Empty() ); - - await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - /// void global::System.IDisposable.Dispose() { diff --git a/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#INestedGitHubApi.g.verified.cs b/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#INestedGitHubApi.g.verified.cs index 56f107e8b..622e6b707 100644 --- a/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#INestedGitHubApi.g.verified.cs +++ b/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#INestedGitHubApi.g.verified.cs @@ -109,88 +109,6 @@ public RefitTestsTestNestedINestedGitHubApi(global::System.Net.Http.HttpClient c await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - private static readonly global::System.Type[] ______typeParameters4 = new global::System.Type[] {typeof(string) }; - - /// - async global::System.Threading.Tasks.Task global::Refit.Tests.TestNested.INestedGitHubApi.GetUser(string @userName) - { - var ______arguments = new object[] { @userName }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetUser", ______typeParameters4 ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - private static readonly global::System.Type[] ______typeParameters5 = new global::System.Type[] {typeof(string) }; - - /// - global::System.IObservable global::Refit.Tests.TestNested.INestedGitHubApi.GetUserObservable(string @userName) - { - var ______arguments = new object[] { @userName }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetUserObservable", ______typeParameters5 ); - - return (global::System.IObservable)______func(this.Client, ______arguments); - } - - private static readonly global::System.Type[] ______typeParameters6 = new global::System.Type[] {typeof(string) }; - - /// - global::System.IObservable global::Refit.Tests.TestNested.INestedGitHubApi.GetUserCamelCase(string @userName) - { - var ______arguments = new object[] { @userName }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetUserCamelCase", ______typeParameters6 ); - - return (global::System.IObservable)______func(this.Client, ______arguments); - } - - private static readonly global::System.Type[] ______typeParameters7 = new global::System.Type[] {typeof(string) }; - - /// - async global::System.Threading.Tasks.Task> global::Refit.Tests.TestNested.INestedGitHubApi.GetOrgMembers(string @orgName) - { - var ______arguments = new object[] { @orgName }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetOrgMembers", ______typeParameters7 ); - - return await ((global::System.Threading.Tasks.Task>)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - private static readonly global::System.Type[] ______typeParameters8 = new global::System.Type[] {typeof(string) }; - - /// - async global::System.Threading.Tasks.Task global::Refit.Tests.TestNested.INestedGitHubApi.FindUsers(string @q) - { - var ______arguments = new object[] { @q }; - var ______func = requestBuilder.BuildRestResultFuncForMethod("FindUsers", ______typeParameters8 ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - /// - async global::System.Threading.Tasks.Task global::Refit.Tests.TestNested.INestedGitHubApi.GetIndex() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetIndex", global::System.Array.Empty() ); - - return await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - /// - global::System.IObservable global::Refit.Tests.TestNested.INestedGitHubApi.GetIndexObservable() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetIndexObservable", global::System.Array.Empty() ); - - return (global::System.IObservable)______func(this.Client, ______arguments); - } - - /// - async global::System.Threading.Tasks.Task global::Refit.Tests.TestNested.INestedGitHubApi.NothingToSeeHere() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("NothingToSeeHere", global::System.Array.Empty() ); - - await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.GenerateInterfaceStubsWithoutNamespaceSmokeTest#IServiceWithoutNamespace.g.verified.cs b/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.GenerateInterfaceStubsWithoutNamespaceSmokeTest#IServiceWithoutNamespace.g.verified.cs index d4e8fdac4..88fa24c4a 100644 --- a/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.GenerateInterfaceStubsWithoutNamespaceSmokeTest#IServiceWithoutNamespace.g.verified.cs +++ b/Refit.Tests/_snapshots/InterfaceStubGeneratorTests.GenerateInterfaceStubsWithoutNamespaceSmokeTest#IServiceWithoutNamespace.g.verified.cs @@ -45,24 +45,6 @@ public IServiceWithoutNamespace(global::System.Net.Http.HttpClient client, globa await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); } - - /// - async global::System.Threading.Tasks.Task global::IServiceWithoutNamespace.GetRoot() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("GetRoot", global::System.Array.Empty() ); - - await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } - - /// - async global::System.Threading.Tasks.Task global::IServiceWithoutNamespace.PostRoot() - { - var ______arguments = global::System.Array.Empty(); - var ______func = requestBuilder.BuildRestResultFuncForMethod("PostRoot", global::System.Array.Empty() ); - - await ((global::System.Threading.Tasks.Task)______func(this.Client, ______arguments)).ConfigureAwait(false); - } } } } diff --git a/Refit/AnonymousDisposable.cs b/Refit/AnonymousDisposable.cs index 1f1215939..029535bcd 100644 --- a/Refit/AnonymousDisposable.cs +++ b/Refit/AnonymousDisposable.cs @@ -1,14 +1,7 @@ namespace Refit { - sealed class AnonymousDisposable : IDisposable + sealed class AnonymousDisposable(Action block) : IDisposable { - readonly Action block; - - public AnonymousDisposable(Action block) - { - this.block = block; - } - public void Dispose() { block(); diff --git a/Refit/CloseGenericMethodKey.cs b/Refit/CloseGenericMethodKey.cs index d9560140f..03bb0c795 100644 --- a/Refit/CloseGenericMethodKey.cs +++ b/Refit/CloseGenericMethodKey.cs @@ -2,7 +2,7 @@ namespace Refit { - struct CloseGenericMethodKey : IEquatable + readonly struct CloseGenericMethodKey : IEquatable { internal CloseGenericMethodKey(MethodInfo openMethodInfo, Type[] types) { diff --git a/Refit/FormValueMultimap.cs b/Refit/FormValueMultimap.cs index 72092231c..d305a3c5f 100644 --- a/Refit/FormValueMultimap.cs +++ b/Refit/FormValueMultimap.cs @@ -166,9 +166,7 @@ string GetFieldNameForProperty(PropertyInfo propertyInfo) static PropertyInfo[] GetProperties(Type type) { - return type.GetProperties(BindingFlags.Instance | BindingFlags.Public) - .Where(p => p.CanRead && p.GetMethod?.IsPublic == true) - .ToArray(); + return [.. type.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanRead && p.GetMethod?.IsPublic == true)]; } public IEnumerator> GetEnumerator() diff --git a/Refit/NameValueCollection.cs b/Refit/NameValueCollection.cs index e313b184b..3a4d13231 100644 --- a/Refit/NameValueCollection.cs +++ b/Refit/NameValueCollection.cs @@ -2,6 +2,6 @@ { class NameValueCollection : Dictionary { - public string[] AllKeys => Keys.ToArray(); + public string[] AllKeys => [.. Keys]; } } diff --git a/Refit/Refit.csproj b/Refit/Refit.csproj index d15b9c9ac..ede96070f 100644 --- a/Refit/Refit.csproj +++ b/Refit/Refit.csproj @@ -7,7 +7,7 @@ enable - + true diff --git a/Refit/RequestBuilderImplementation.cs b/Refit/RequestBuilderImplementation.cs index ce7dc63c0..f7fddd4d4 100644 --- a/Refit/RequestBuilderImplementation.cs +++ b/Refit/RequestBuilderImplementation.cs @@ -46,7 +46,7 @@ public RequestBuilderImplementation( TargetType = refitInterfaceType; - var dict = new Dictionary>(); + var dict = new Dictionary>(StringComparer.Ordinal); AddInterfaceHttpMethods(refitInterfaceType, dict); foreach (var inheritedInterface in targetInterfaceInheritedInterfaces) @@ -57,12 +57,18 @@ public RequestBuilderImplementation( interfaceHttpMethods = dict; } + static string GetLookupKeyForMethod(MethodInfo methodInfo) + { + var name = methodInfo.Name; + var lastDot = name.LastIndexOf('.'); + return lastDot >= 0 ? name.Substring(lastDot + 1) : name; + } + void AddInterfaceHttpMethods( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]Type interfaceType, Dictionary> methods ) { - // Consider public (the implicit visibility) and non-public abstract members of the interfaceType var methodInfos = interfaceType .GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) .Where(i => i.IsAbstract); @@ -73,10 +79,11 @@ Dictionary> methods var hasHttpMethod = attrs.OfType().Any(); if (hasHttpMethod) { - if (!methods.TryGetValue(methodInfo.Name, out var value)) + var key = GetLookupKeyForMethod(methodInfo); + if (!methods.TryGetValue(key, out var value)) { value = []; - methods.Add(methodInfo.Name, value); + methods.Add(key, value); } var restinfo = new RestMethodInfoInternal(interfaceType, methodInfo, settings); @@ -116,7 +123,6 @@ RestMethodInfoInternal FindMatchingRestMethodInfo( method => method.MethodInfo.GetParameters().Length == parameterTypes.Length ); - // If it's a generic method, add that filter if (isGeneric) possibleMethodsCollection = possibleMethodsCollection.Where( method => @@ -124,7 +130,7 @@ RestMethodInfoInternal FindMatchingRestMethodInfo( && method.MethodInfo.GetGenericArguments().Length == genericArgumentTypes!.Length ); - else // exclude generic methods + else possibleMethodsCollection = possibleMethodsCollection.Where( method => !method.MethodInfo.IsGenericMethod ); @@ -187,17 +193,16 @@ RestMethodInfoInternal CloseGenericMethodIfNeeded( parameterTypes, genericArgumentTypes ); + + // Task (void) if (restMethod.ReturnType == typeof(Task)) { return BuildVoidTaskFuncForMethod(restMethod); } - if (restMethod.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)) + // Task + if (restMethod.ReturnType.GetTypeInfo().IsGenericType && restMethod.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)) { - // NB: This jacked up reflection code is here because it's - // difficult to upcast Task to an arbitrary T, especially - // if you need to AOT everything, so we need to reflectively - // invoke buildTaskFuncForMethod. var taskFuncMi = typeof(RequestBuilderImplementation).GetMethod( nameof(BuildTaskFuncForMethod), BindingFlags.NonPublic | BindingFlags.Instance @@ -213,20 +218,48 @@ RestMethodInfoInternal CloseGenericMethodIfNeeded( return (client, args) => taskFunc!.DynamicInvoke(client, args); } - // Same deal - var rxFuncMi = typeof(RequestBuilderImplementation).GetMethod( - nameof(BuildRxFuncForMethod), + // IObservable + if (restMethod.ReturnType.GetTypeInfo().IsGenericType && restMethod.ReturnType.GetGenericTypeDefinition() == typeof(IObservable<>)) + { + var rxFuncMi = typeof(RequestBuilderImplementation).GetMethod( + nameof(BuildRxFuncForMethod), + BindingFlags.NonPublic | BindingFlags.Instance + ); + var rxFunc = (MulticastDelegate?) + ( + rxFuncMi!.MakeGenericMethod( + restMethod.ReturnResultType, + restMethod.DeserializedResultType + ) + ).Invoke(this, [restMethod]); + + return (client, args) => rxFunc!.DynamicInvoke(client, args); + } + + // Synchronous return types: build a sync wrapper that awaits internally and returns the value + var syncFuncMi = typeof(RequestBuilderImplementation).GetMethod( + nameof(BuildSyncFuncForMethod), BindingFlags.NonPublic | BindingFlags.Instance ); - var rxFunc = (MulticastDelegate?) + var syncFunc = (MulticastDelegate?) ( - rxFuncMi!.MakeGenericMethod( + syncFuncMi!.MakeGenericMethod( restMethod.ReturnResultType, restMethod.DeserializedResultType ) ).Invoke(this, [restMethod]); - return (client, args) => rxFunc!.DynamicInvoke(client, args); + return (client, args) => syncFunc!.DynamicInvoke(client, args); + } + + private Func BuildSyncFuncForMethod(RestMethodInfoInternal restMethod) + { + var taskFunc = BuildTaskFuncForMethod(restMethod); + return (client, paramList) => + { + var task = taskFunc(client, paramList); + return (object?)task.GetAwaiter().GetResult(); + }; } void AddMultipartItem( diff --git a/Refit/RestMethodInfo.cs b/Refit/RestMethodInfo.cs index 6273967b2..b87c8248d 100644 --- a/Refit/RestMethodInfo.cs +++ b/Refit/RestMethodInfo.cs @@ -672,9 +672,24 @@ void DetermineReturnTypeInfo(MethodInfo methodInfo) DeserializedResultType = typeof(void); } else - throw new ArgumentException( - $"Method \"{methodInfo.Name}\" is invalid. All REST Methods must return either Task or ValueTask or IObservable" - ); + { + // Allow synchronous return types only for non-public or explicit interface members. + // This supports internal Refit methods and explicit interface members annotated with Refit attributes. + var isExplicitInterfaceMember = methodInfo.Name.IndexOf('.') >= 0; + var isNonPublic = !(methodInfo.IsPublic); + if (!(isExplicitInterfaceMember || isNonPublic)) + { + throw new ArgumentException( + $"Method \"{methodInfo.Name}\" is invalid. All REST Methods must return either Task or ValueTask or IObservable" + ); + } + + ReturnType = methodInfo.ReturnType; + ReturnResultType = methodInfo.ReturnType; + DeserializedResultType = methodInfo.ReturnType == typeof(IApiResponse) + ? typeof(HttpContent) + : methodInfo.ReturnType; + } } void DetermineIfResponseMustBeDisposed() diff --git a/Refit/RestMethodParameterInfo.cs b/Refit/RestMethodParameterInfo.cs index dd748e85f..8b384fb15 100644 --- a/Refit/RestMethodParameterInfo.cs +++ b/Refit/RestMethodParameterInfo.cs @@ -73,26 +73,20 @@ public RestMethodParameterInfo(bool isObjectPropertyParameter, ParameterInfo par /// /// RestMethodParameterProperty. /// - public class RestMethodParameterProperty + /// + /// Initializes a new instance of the class. + /// + /// The name. + /// The property information. + public class RestMethodParameterProperty(string name, PropertyInfo propertyInfo) { - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The property information. - public RestMethodParameterProperty(string name, PropertyInfo propertyInfo) - { - Name = name; - PropertyInfo = propertyInfo; - } - /// /// Gets or sets the name. /// /// /// The name. /// - public string Name { get; set; } + public string Name { get; set; } = name; /// /// Gets or sets the property information. @@ -100,7 +94,7 @@ public RestMethodParameterProperty(string name, PropertyInfo propertyInfo) /// /// The property information. /// - public PropertyInfo PropertyInfo { get; set; } + public PropertyInfo PropertyInfo { get; set; } = propertyInfo; } /// diff --git a/Refit/SystemTextJsonContentSerializer.cs b/Refit/SystemTextJsonContentSerializer.cs index 79469f0c9..0152071ab 100644 --- a/Refit/SystemTextJsonContentSerializer.cs +++ b/Refit/SystemTextJsonContentSerializer.cs @@ -9,28 +9,18 @@ namespace Refit /// /// A implementing using the System.Text.Json APIs /// - public sealed class SystemTextJsonContentSerializer : IHttpContentSerializer + /// + /// Creates a new instance with the specified parameters + /// + /// The serialization options to use for the current instance + public sealed class SystemTextJsonContentSerializer(JsonSerializerOptions jsonSerializerOptions) : IHttpContentSerializer { - /// - /// The JSON serialization options to use - /// - readonly JsonSerializerOptions jsonSerializerOptions; - /// /// Creates a new instance /// public SystemTextJsonContentSerializer() : this(GetDefaultJsonSerializerOptions()) { } - /// - /// Creates a new instance with the specified parameters - /// - /// The serialization options to use for the current instance - public SystemTextJsonContentSerializer(JsonSerializerOptions jsonSerializerOptions) - { - this.jsonSerializerOptions = jsonSerializerOptions; - } - /// public HttpContent ToHttpContent(T item) {