From d303131d2c0c41c857006c9180932e06ae48d020 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Sun, 27 Oct 2024 17:00:14 -0700 Subject: [PATCH] Rename IAbstractionsContext to ICommonContext and cleaned up XML docs for clarity --- ...ssMustHaveParameterlessConstructorTests.cs | 2 +- ...ctionsContext.cs => EmptyCommonContext.cs} | 6 +- ...stractionsContext.cs => ICommonContext.cs} | 6 +- .../Utility/SerializableTypeSymbols.cs | 2 +- .../Utility/V2AbstractionsContext.cs | 2 +- ...tractionsContext.cs => V3CommonContext.cs} | 20 +- src/xunit.analyzers/Utility/XunitContext.cs | 188 +++++++++--------- ...leClassMustHaveParameterlessConstructor.cs | 4 +- 8 files changed, 121 insertions(+), 109 deletions(-) rename src/xunit.analyzers/Utility/{EmptyAbstractionsContext.cs => EmptyCommonContext.cs} (83%) rename src/xunit.analyzers/Utility/{IAbstractionsContext.cs => ICommonContext.cs} (90%) rename src/xunit.analyzers/Utility/{V3AbstractionsContext.cs => V3CommonContext.cs} (80%) diff --git a/src/xunit.analyzers.tests/Analyzers/X3000/SerializableClassMustHaveParameterlessConstructorTests.cs b/src/xunit.analyzers.tests/Analyzers/X3000/SerializableClassMustHaveParameterlessConstructorTests.cs index 91b3cdc..0722ec7 100644 --- a/src/xunit.analyzers.tests/Analyzers/X3000/SerializableClassMustHaveParameterlessConstructorTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X3000/SerializableClassMustHaveParameterlessConstructorTests.cs @@ -113,6 +113,6 @@ public class SerializableClassMustHaveParameterlessConstructorTests public class V3Analyzer : SerializableClassMustHaveParameterlessConstructor { protected override XunitContext CreateXunitContext(Compilation compilation) => - XunitContext.ForV3Core(compilation); + XunitContext.ForV3(compilation); } } diff --git a/src/xunit.analyzers/Utility/EmptyAbstractionsContext.cs b/src/xunit.analyzers/Utility/EmptyCommonContext.cs similarity index 83% rename from src/xunit.analyzers/Utility/EmptyAbstractionsContext.cs rename to src/xunit.analyzers/Utility/EmptyCommonContext.cs index 9e5de31..81cd903 100644 --- a/src/xunit.analyzers/Utility/EmptyAbstractionsContext.cs +++ b/src/xunit.analyzers/Utility/EmptyCommonContext.cs @@ -3,12 +3,12 @@ using Microsoft.CodeAnalysis; namespace Xunit.Analyzers; -public class EmptyAbstractionsContext : IAbstractionsContext +public class EmptyCommonContext : ICommonContext { - EmptyAbstractionsContext() + EmptyCommonContext() { } - public static EmptyAbstractionsContext Instance { get; } = new(); + public static EmptyCommonContext Instance { get; } = new(); public INamedTypeSymbol? IMessageSinkType => null; diff --git a/src/xunit.analyzers/Utility/IAbstractionsContext.cs b/src/xunit.analyzers/Utility/ICommonContext.cs similarity index 90% rename from src/xunit.analyzers/Utility/IAbstractionsContext.cs rename to src/xunit.analyzers/Utility/ICommonContext.cs index be5389b..e42f2bc 100644 --- a/src/xunit.analyzers/Utility/IAbstractionsContext.cs +++ b/src/xunit.analyzers/Utility/ICommonContext.cs @@ -4,10 +4,10 @@ using Microsoft.CodeAnalysis; namespace Xunit.Analyzers; /// -/// Context with information from xunit.abstractions (in v2) or xunit.v3.common or xunit.v3.core (in v3). -/// The types here are the ones common to both. +/// Context for types that that originated in xunit.abstractions in v2, and moved in v3 +/// to one of xunit.v3.common, xunit.v3.core, or xunit.v3.runner.common. /// -public interface IAbstractionsContext +public interface ICommonContext { /// /// Gets a reference to type IMessageSink, if available. diff --git a/src/xunit.analyzers/Utility/SerializableTypeSymbols.cs b/src/xunit.analyzers/Utility/SerializableTypeSymbols.cs index e10857f..61c29a2 100644 --- a/src/xunit.analyzers/Utility/SerializableTypeSymbols.cs +++ b/src/xunit.analyzers/Utility/SerializableTypeSymbols.cs @@ -34,7 +34,7 @@ public sealed class SerializableTypeSymbols bigInteger = new(() => TypeSymbolFactory.BigInteger(compilation)); dateOnly = new(() => TypeSymbolFactory.DateOnly(compilation)); dateTimeOffset = new(() => TypeSymbolFactory.DateTimeOffset(compilation)); - iXunitSerializable = new(() => xunitContext.Abstractions.IXunitSerializableType); + iXunitSerializable = new(() => xunitContext.Common.IXunitSerializableType); // For v2 and early versions of v3, the base type is "TheoryData" (non-generic). For later versions // of v3, it's "TheoryDataBase". In either case, getting "TheoryData" // and going up one layer gets us the type we want to be able to search for. diff --git a/src/xunit.analyzers/Utility/V2AbstractionsContext.cs b/src/xunit.analyzers/Utility/V2AbstractionsContext.cs index 4bf9896..f852625 100644 --- a/src/xunit.analyzers/Utility/V2AbstractionsContext.cs +++ b/src/xunit.analyzers/Utility/V2AbstractionsContext.cs @@ -4,7 +4,7 @@ using Microsoft.CodeAnalysis; namespace Xunit.Analyzers; -public class V2AbstractionsContext : IAbstractionsContext +public class V2AbstractionsContext : ICommonContext { readonly Lazy lazyIAssemblyInfoType; readonly Lazy lazyIAttributeInfoType; diff --git a/src/xunit.analyzers/Utility/V3AbstractionsContext.cs b/src/xunit.analyzers/Utility/V3CommonContext.cs similarity index 80% rename from src/xunit.analyzers/Utility/V3AbstractionsContext.cs rename to src/xunit.analyzers/Utility/V3CommonContext.cs index 53cdcb4..44d19e8 100644 --- a/src/xunit.analyzers/Utility/V3AbstractionsContext.cs +++ b/src/xunit.analyzers/Utility/V3CommonContext.cs @@ -4,9 +4,7 @@ using Microsoft.CodeAnalysis; namespace Xunit.Analyzers; -// Technically xunit.abstractions doesn't exist in v3; all the co-existent/updated types are present in xunit.v3.common, instead. - -public class V3AbstractionsContext : IAbstractionsContext +public class V3CommonContext : ICommonContext { readonly Lazy lazyIMessageSinkType; readonly Lazy lazyISourceInformationProviderType; @@ -21,7 +19,7 @@ public class V3AbstractionsContext : IAbstractionsContext readonly Lazy lazyITestType; readonly Lazy lazyIXunitSerializableType; - V3AbstractionsContext( + V3CommonContext( Compilation compilation, Version version) { @@ -42,50 +40,62 @@ public class V3AbstractionsContext : IAbstractionsContext } /// + /// This type lives in xunit.v3.common. public INamedTypeSymbol? IMessageSinkType => lazyIMessageSinkType.Value; /// + /// This type lives in xunit.v3.runner.common. public INamedTypeSymbol? ISourceInformationProviderType => lazyISourceInformationProviderType.Value; /// + /// This type lives in xunit.v3.common. public INamedTypeSymbol? ITestAssemblyType => lazyITestAssemblyType.Value; /// + /// This type lives in xunit.v3.common. public INamedTypeSymbol? ITestCaseType => lazyITestCaseType.Value; /// + /// This type lives in xunit.v3.common. public INamedTypeSymbol? ITestClassType => lazyITestClassType.Value; /// + /// This type lives in xunit.v3.common. public INamedTypeSymbol? ITestCollectionType => lazyITestCollectionType.Value; /// + /// This type lives in xunit.v3.core. public INamedTypeSymbol? ITestFrameworkDiscovererType => lazyITestFrameworkDiscovererType.Value; /// + /// This type lives in xunit.v3.core. public INamedTypeSymbol? ITestFrameworkExecutorType => lazyITestFrameworkExecutorType.Value; /// + /// This type lives in xunit.v3.core. public INamedTypeSymbol? ITestFrameworkType => lazyITestFrameworkType.Value; /// + /// This type lives in xunit.v3.common. public INamedTypeSymbol? ITestMethodType => lazyITestMethodType.Value; /// + /// This type lives in xunit.v3.common. public INamedTypeSymbol? ITestType => lazyITestType.Value; /// + /// This type lives in xunit.v3.common. public INamedTypeSymbol? IXunitSerializableType => lazyIXunitSerializableType.Value; @@ -94,7 +104,7 @@ public class V3AbstractionsContext : IAbstractionsContext /// public Version Version { get; } - public static V3AbstractionsContext? Get( + public static V3CommonContext? Get( Compilation compilation, Version? versionOverride = null) { diff --git a/src/xunit.analyzers/Utility/XunitContext.cs b/src/xunit.analyzers/Utility/XunitContext.cs index a90b73c..5fbe132 100644 --- a/src/xunit.analyzers/Utility/XunitContext.cs +++ b/src/xunit.analyzers/Utility/XunitContext.cs @@ -8,8 +8,8 @@ namespace Xunit.Analyzers; /// public class XunitContext { - IAbstractionsContext? abstractions; IAssertContext? assert; + ICommonContext? common; ICoreContext? core; IRunnerUtilityContext? runnerUtility; static readonly Version v2AbstractionsVersion = new(2, 0, 3); @@ -29,41 +29,42 @@ public class XunitContext V2Core = V2CoreContext.Get(compilation); V2Execution = V2ExecutionContext.Get(compilation); V2RunnerUtility = V2RunnerUtilityContext.Get(compilation); - V3Abstractions = V3AbstractionsContext.Get(compilation); + V3Assert = V3AssertContext.Get(compilation); + V3Common = V3CommonContext.Get(compilation); V3Core = V3CoreContext.Get(compilation); } - /// - /// Gets a combined view of features available to either v2 tests (linked against - /// xunit.abstractions) or v3 tests (linked against xunit.v3.common and xunit.v3.core). - /// - public IAbstractionsContext Abstractions - { - get - { - abstractions ??= V3Abstractions ?? (IAbstractionsContext?)V2Abstractions ?? EmptyAbstractionsContext.Instance; - return abstractions; - } - } - /// /// Gets a combined view of the assertion library features available to either v2 tests (linked - /// against xunit.assert or xunit.assert.source) or v3 tests (linked against xunit.v3.assert or - /// xunit.v3.assert.source). + /// against xunit.assert or xunit.assert.source) or v3 tests (linked against + /// xunit.v3.assert or xunit.v3.assert.source). /// public IAssertContext Assert { get { - assert ??= V2Assert ?? (IAssertContext?)V3Assert ?? EmptyAssertContext.Instance; + assert ??= V3Assert ?? (IAssertContext?)V2Assert ?? EmptyAssertContext.Instance; return assert; } } /// - /// Gets a combined view of features available to either v2 tests (linked against xunit.core) - /// or v3 tests (linked against xunit.v3.core). + /// Gets a combined view of features that are common to both tests and runners, available to either + /// v2 tests (linked against xunit.abstractions) or v3 tests (linked against xunit.v3.common). + /// + public ICommonContext Common + { + get + { + common ??= V3Common ?? (ICommonContext?)V2Abstractions ?? EmptyCommonContext.Instance; + return common; + } + } + + /// + /// Gets a combined view of features available to either v2 tests (linked against xunit.core) + /// or v3 tests (linked against xunit.v3.core). /// public ICoreContext Core { @@ -76,21 +77,21 @@ public class XunitContext /// /// Gets a flag which indicates whether there are any xUnit.net v2 references in the project - /// (including abstractions, assert, core, and execution references). + /// (including abstractions, assert, core, execution, and runner utility references). /// public bool HasV2References => V2Abstractions is not null || V2Assert is not null || V2Core is not null || V2Execution is not null || V2RunnerUtility is not null; /// /// Gets a flag which indicates whether there are any xUnit.net v3 references in the project - /// (including assert and core references). + /// (including assert, common, and core references). /// public bool HasV3References => - V3Abstractions is not null || V3Assert is not null || V3Core is not null; + V3Assert is not null || V3Common is not null || V3Core is not null; /// - /// Gets a combined view of features available to either v2 runners (linked against xunit.runner.utility.*) - /// or v3 runners (linked against xunit.v3.runner.utility.*). + /// Gets a combined view of features available to either v2 runners (linked against xunit.runner.utility) + /// or v3 runners (linked against xunit.v3.runner.utility). /// public IRunnerUtilityContext RunnerUtility { @@ -102,64 +103,67 @@ public class XunitContext } /// - /// Gets information about the reference to xunit.abstractions (v2). If the project does - /// not reference v2 Abstractions, then returns null. + /// Gets information about the reference to xunit.abstractions (v2). If the project does + /// not reference the v2 abstractions library, then returns null. /// public V2AbstractionsContext? V2Abstractions { get; private set; } /// - /// Gets information about the reference to xunit.assert or xunit.assert.source (v2). If + /// Gets information about the reference to xunit.assert or xunit.assert.source (v2). If /// the project does not reference the v2 assertion library, then returns null. /// public V2AssertContext? V2Assert { get; private set; } /// - /// Gets information about the reference to xunit.core (v2). If the project does not - /// reference v2 Core, then returns null. + /// Gets information about the reference to xunit.core(v2). If the project does not + /// reference the v2 core library, then returns null. /// public V2CoreContext? V2Core { get; private set; } /// - /// Gets information about the reference to xunit.execution.* (v2). If the project does - /// not reference v2 Execution, then returns null. + /// Gets information about the reference to xunit.execution (v2). If the project does + /// not reference the v2 execution library, then returns null. /// public V2ExecutionContext? V2Execution { get; private set; } /// - /// Gets information about the reference to xunit.runner.utility.* (v2). If the project does - /// not reference v2 Runner Utility, then returns null. + /// Gets information about the reference to xunit.runner.utility (v2). If the project does + /// not reference the v2 runner utility library, then returns null. /// public V2RunnerUtilityContext? V2RunnerUtility { get; private set; } /// - /// Gets information about the v3 equivalent to v2's xunit.abstractions, which comes from a mix - /// of xunit.v3.common and xunit.v3.core. If the project does not reference xunit.v3.common, then - /// returns null. - /// - public V3AbstractionsContext? V3Abstractions { get; private set; } - - /// - /// Gets information about the reference to xunit.v3.assert or xunit.v3.assert.source (v3). - /// If the project does not reference the v3 assertion library, then returns null. + /// Gets information about the reference to xunit.v3.assert or xunit.v3.assert.source + /// (v3). If the project does not reference the v3 assertion library, then returns null. /// public V3AssertContext? V3Assert { get; private set; } /// - /// Gets information about the reference to xunit.v3.core (v3). If the project does not - /// reference v3 Core, then returns null. + /// Gets types that exist in xunit.v3.common (v3). If the project does not reference + /// the v3 common library, then returns null. + /// + /// + /// This also contains a few selected types from xunit.v3.core and xunit.v3.runner.common + /// to align with the types that were all originally in xunit.abstractions in v2, to support + /// the composite view from . + /// + public V3CommonContext? V3Common { get; private set; } + + /// + /// Gets information about the reference to xunit.v3.core (v3). If the project does not + /// reference the v3 core library, then returns null. /// public V3CoreContext? V3Core { get; private set; } /// - /// Gets information about the reference to xunit.v3.runner.utility.* (v3). If the project does - /// not reference v3 Runner Utility, then returns null. + /// Gets information about the reference to xunit.v3.runner.utility (v3). If the project does + /// not reference the v3 runner utility library, then returns null. /// public V3RunnerUtilityContext? V3RunnerUtility { get; private set; } /// - /// Used to create a context object for test purposes, which only contains a reference to - /// xunit.abstraction (which is always set to version 2.0.3, since it did not float versions). - /// + /// Used to create a context object for testing v2 analyzers and fixers. This includes references + /// to xunit.abstactions (at version 2.0.3). /// The Roslyn compilation object used to look up types public static XunitContext ForV2Abstractions(Compilation compilation) => new() @@ -168,93 +172,91 @@ public class XunitContext }; /// - /// Used to create a context object for testing purposes, which is optionally stuck to a specific version - /// of xunit.assert. + /// Used to create a context object for testing v2 analyzers and fixers. This includes references + /// to xunit.assert. /// /// The Roslyn compilation object used to look up types - /// The overridden version for xunit.core and xunit.execution.* + /// The overridden version for xunit.assert public static XunitContext ForV2Assert( Compilation compilation, - Version? v2VersionOverride = null) => + Version? versionOverride = null) => new() { - V2Assert = V2AssertContext.Get(compilation, v2VersionOverride), + V2Assert = V2AssertContext.Get(compilation, versionOverride), }; /// - /// Used to create a context object for testing purposes, which is optionally stuck to a specific version - /// of xunit.core (xunit.abstractions is always version 2.0.3, since it did not float versions). + /// Used to create a context object for testing v2 analyzers and fixers. This includes references + /// to xunit.abstractions (at version 2.0.3) and xunit.core. /// /// The Roslyn compilation object used to look up types - /// The overridden version for xunit.core and xunit.execution.* + /// The overridden version for xunit.core public static XunitContext ForV2Core( Compilation compilation, - Version? v2VersionOverride = null) => + Version? versionOverride = null) => new() { V2Abstractions = V2AbstractionsContext.Get(compilation, v2AbstractionsVersion), - V2Core = V2CoreContext.Get(compilation, v2VersionOverride), + V2Core = V2CoreContext.Get(compilation, versionOverride), }; /// - /// Used to create a context object for testing purposes, which is optionally stuck to a specific version - /// of xunit.execution.* (xunit.abstractions is always version 2.0.3, since it did not float - /// versions). + /// Used to create a context object for testing v2 analyzers and fixers. This includes references + /// to xunit.abstractions (at version 2.0.3) and xunit.execution. /// /// The Roslyn compilation object used to look up types - /// The overridden version for xunit.execution.* + /// The overridden version for xunit.execution public static XunitContext ForV2Execution( Compilation compilation, - Version? v2VersionOverride = null) => + Version? versionOverride = null) => new() { V2Abstractions = V2AbstractionsContext.Get(compilation, v2AbstractionsVersion), - V2Execution = V2ExecutionContext.Get(compilation, v2VersionOverride), + V2Execution = V2ExecutionContext.Get(compilation, versionOverride), }; /// - /// Used to create a context object for testing purposes, which is optionally stuck to a specific version - /// of xunit.runner.utility.* (xunit.abstractions is always version 2.0.3, since it did not float - /// versions). + /// Used to create a context object for testing v2 analyzers and fixers. This includes references + /// to xunit.abstractions (at version 2.0.3) and xunit.runner.utility. /// /// The Roslyn compilation object used to look up types - /// The overridden version for xunit.execution.* + /// The overridden version for xunit.runner.utility public static XunitContext ForV2RunnerUtility( Compilation compilation, - Version? v2VersionOverride = null) => + Version? versionOverride = null) => new() { V2Abstractions = V2AbstractionsContext.Get(compilation, v2AbstractionsVersion), - V2RunnerUtility = V2RunnerUtilityContext.Get(compilation, v2VersionOverride), + V2RunnerUtility = V2RunnerUtilityContext.Get(compilation, versionOverride), }; /// - /// Used to create a context object for testing purposes, which is optionally stuck to a specific version - /// of the v3 assemblies. + /// Used to create a context object for testing v3 analyzers and fixers. This includes references + /// for xunit.v3.assert, xunit.v3.common, and xunit.v3.core. /// /// The Roslyn compilation object used to look up types - /// The overridden version + /// The overridden version for all libraries + public static XunitContext ForV3( + Compilation compilation, + Version? versionOverride = null) => + new() + { + V3Assert = V3AssertContext.Get(compilation, versionOverride), + V3Common = V3CommonContext.Get(compilation, versionOverride), + V3Core = V3CoreContext.Get(compilation, versionOverride), + }; + + /// + /// Used to create a context object for testing v3 analyzers and fixers. This includes references + /// for xunit.v3.assert. + /// + /// The Roslyn compilation object used to look up types + /// The overridden version for xunit.v3.assert public static XunitContext ForV3Assert( Compilation compilation, - Version? v3VersionOverride = null) => + Version? versionOverride = null) => new() { - V3Assert = V3AssertContext.Get(compilation, v3VersionOverride), - }; - - /// - /// Used to create a context object for testing purposes, which is optionally stuck to a specific version - /// of the v3 assemblies. - /// - /// The Roslyn compilation object used to look up types - /// The overridden version - public static XunitContext ForV3Core( - Compilation compilation, - Version? v3VersionOverride = null) => - new() - { - V3Abstractions = V3AbstractionsContext.Get(compilation, v3VersionOverride), - V3Assert = V3AssertContext.Get(compilation, v3VersionOverride), - V3Core = V3CoreContext.Get(compilation, v3VersionOverride), + V3Assert = V3AssertContext.Get(compilation, versionOverride), }; } diff --git a/src/xunit.analyzers/X3000/SerializableClassMustHaveParameterlessConstructor.cs b/src/xunit.analyzers/X3000/SerializableClassMustHaveParameterlessConstructor.cs index fca5f0f..a30cdc6 100644 --- a/src/xunit.analyzers/X3000/SerializableClassMustHaveParameterlessConstructor.cs +++ b/src/xunit.analyzers/X3000/SerializableClassMustHaveParameterlessConstructor.cs @@ -50,8 +50,8 @@ public class SerializableClassMustHaveParameterlessConstructor : XunitDiagnostic INamedTypeSymbol namedType) { // Types that implement IXunitSerializable - if (xunitContext.Abstractions.IXunitSerializableType?.IsAssignableFrom(namedType) == true) - return xunitContext.Abstractions.IXunitSerializableType.ToDisplayString(); + if (xunitContext.Common.IXunitSerializableType?.IsAssignableFrom(namedType) == true) + return xunitContext.Common.IXunitSerializableType.ToDisplayString(); // Types that decorate with [JsonTypeID] if (xunitContext.V3Core?.JsonTypeIDAttributeType is INamedTypeSymbol jsonTypeIDAttributeType)