diff --git a/.editorconfig b/.editorconfig index 6749ca4e54..f4ba4a01db 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,6 +7,7 @@ root = true # Default settings ############################################# [*] +end_of_line = lf insert_final_newline = true indent_style = space indent_size = 4 @@ -182,170 +183,161 @@ csharp_space_between_square_brackets = false dotnet_diagnostic.AvoidAsyncVoid.severity = suggestion ################### -# Microsoft .NET Analyzers (CA) - Design Rules +# Microsoft.CodeAnalysis.NetAnalyzers (CA) ################### +# Design dotnet_diagnostic.CA1000.severity = none # Do not declare static members on generic types — common factory pattern -dotnet_diagnostic.CA1001.severity = none # Types that own disposable fields should be disposable — covered by SST2315 +dotnet_diagnostic.CA1001.severity = error # Types that own disposable fields should be disposable dotnet_diagnostic.CA1002.severity = none # Do not expose generic lists — we deliberately expose List; interface-based collections are an older convention we don't follow -dotnet_diagnostic.CA1003.severity = error # Use generic event handler instances +dotnet_diagnostic.CA1003.severity = none # Use generic event handler instances — covered by SST2304 dotnet_diagnostic.CA1005.severity = none # Avoid excessive parameters on generic types — we deliberately expose 3+ type-parameter types (tuple-style handles, raw engine signals); the ergonomic guidance conflicts with that design dotnet_diagnostic.CA1008.severity = error # Enums should have zero value dotnet_diagnostic.CA1010.severity = none # Collections should implement generic interface — we deliberately expose concrete collection types; interface-based collections are an older convention we don't follow -dotnet_diagnostic.CA1012.severity = error # Abstract types should not have public constructors +dotnet_diagnostic.CA1012.severity = none # Abstract types should not have public constructors — covered by SST1428 dotnet_diagnostic.CA1014.severity = none # Mark assemblies with CLSCompliantAttribute — we don't ship CLS-compliant assemblies dotnet_diagnostic.CA1016.severity = error # Mark assemblies with AssemblyVersionAttribute dotnet_diagnostic.CA1017.severity = none # Mark assemblies with ComVisibleAttribute — we don't ship COM-visible assemblies dotnet_diagnostic.CA1018.severity = error # Mark attributes with AttributeUsageAttribute -dotnet_diagnostic.CA1019.severity = error # Define accessors for attribute arguments +dotnet_diagnostic.CA1019.severity = none # Define accessors for attribute arguments — conflicts with SST2324, which caps an internal attribute's accessor at internal dotnet_diagnostic.CA1021.severity = none # Avoid out parameters - disabled - needed for the zero-allocation idiom in Try/Find APIs and other performance-critical paths dotnet_diagnostic.CA1024.severity = error # Use properties where appropriate dotnet_diagnostic.CA1027.severity = error # Mark enums with FlagsAttribute -dotnet_diagnostic.CA1028.severity = error # Enum storage should be Int32 +dotnet_diagnostic.CA1028.severity = none # Enum storage should be Int32 — covered by SST2313 dotnet_diagnostic.CA1030.severity = none # Use events where appropriate — we use Rx observables instead of CLR events dotnet_diagnostic.CA1031.severity = none # Do not catch general exception types — required at logging/dispose/IO boundaries -dotnet_diagnostic.CA1032.severity = error # Implement standard exception constructors +dotnet_diagnostic.CA1032.severity = none # Implement standard exception constructors — covered by SST1488 dotnet_diagnostic.CA1033.severity = none # Interface methods should be callable by child types — explicit interface implementations are a deliberate design choice dotnet_diagnostic.CA1034.severity = none # Nested types should not be visible — public nested types are sometimes the cleanest API (e.g. interface-scoped exception helpers) dotnet_diagnostic.CA1036.severity = none # Override methods on comparable types — relational operators rarely meaningful for our types dotnet_diagnostic.CA1040.severity = none # Avoid empty interfaces — duplicate of SST1437 (canonical); marker interfaces (IActivatableView etc.) are deliberate public API -dotnet_diagnostic.CA1041.severity = error # Provide ObsoleteAttribute message +dotnet_diagnostic.CA1041.severity = none # Provide ObsoleteAttribute message — covered by SST2308 dotnet_diagnostic.CA1043.severity = error # Use integral or string argument for indexers -dotnet_diagnostic.CA1044.severity = error # Properties should not be write only +dotnet_diagnostic.CA1044.severity = none # Properties should not be write only — covered by SST1421 dotnet_diagnostic.CA1045.severity = none # Do not pass types by reference — we deliberately use ref-passing static helpers so they carry only the data they touch; data-oriented layout is the default here dotnet_diagnostic.CA1046.severity = error # Do not overload operator equals on reference types -dotnet_diagnostic.CA1047.severity = error # Do not declare protected member in sealed type -dotnet_diagnostic.CA1048.severity = error # Do not declare virtual members in sealed types -dotnet_diagnostic.CA1050.severity = error # Declare types in namespaces +dotnet_diagnostic.CA1047.severity = none # Do not declare protected member in sealed type — covered by SST1427 +dotnet_diagnostic.CA1048.severity = none # Do not declare virtual members in sealed types — covered by SST1491 +dotnet_diagnostic.CA1050.severity = none # Declare types in namespaces — covered by SST2312 dotnet_diagnostic.CA1051.severity = none # Duplicate of SST1401 (canonical) — do not declare visible instance fields -dotnet_diagnostic.CA1052.severity = error # Static holder types should be sealed -dotnet_diagnostic.CA1053.severity = error # Static holder types should not have constructors +dotnet_diagnostic.CA1052.severity = none # Static holder types should be sealed — covered by SST1432 +dotnet_diagnostic.CA1053.severity = none # Static holder types should not have constructors — covered by SST1432 dotnet_diagnostic.CA1054.severity = suggestion # URI parameters should not be strings dotnet_diagnostic.CA1055.severity = suggestion # URI return values should not be strings dotnet_diagnostic.CA1056.severity = suggestion # URI properties should not be strings dotnet_diagnostic.CA1058.severity = error # Types should not extend certain base types dotnet_diagnostic.CA1059.severity = error # Members should not expose certain concrete types dotnet_diagnostic.CA1060.severity = error # Move P/Invokes to NativeMethods class -dotnet_diagnostic.CA1061.severity = error # Do not hide base class methods +dotnet_diagnostic.CA1061.severity = none # Do not hide base class methods — covered by SST2427 dotnet_diagnostic.CA1062.severity = none # Validate arguments of public methods - Nullable=enable + we own every consumer, so the compiler already guarantees non-null params -dotnet_diagnostic.CA1063.severity = error # Implement IDisposable correctly +dotnet_diagnostic.CA1063.severity = none # Implement IDisposable correctly — covered by SST2300 dotnet_diagnostic.CA1064.severity = error # Exceptions should be public -dotnet_diagnostic.CA1065.severity = error # Do not raise exceptions in unexpected locations +dotnet_diagnostic.CA1065.severity = none # Do not raise exceptions in unexpected locations — covered by SST1485 dotnet_diagnostic.CA1066.severity = error # Implement IEquatable when overriding Equals dotnet_diagnostic.CA1067.severity = error # Override Equals when implementing IEquatable dotnet_diagnostic.CA1068.severity = error # CancellationToken parameters must come last dotnet_diagnostic.CA1069.severity = error # Enums should not have duplicate values dotnet_diagnostic.CA1070.severity = error # Do not declare event fields as virtual -################### -# Microsoft .NET Analyzers (CA) - Globalization Rules -################### +# Globalization dotnet_diagnostic.CA1303.severity = none # Do not pass literals as localized parameters — we don't ship localized resources +dotnet_diagnostic.CA1307.severity = none # Covered by PSH1207 (canonical) dotnet_diagnostic.CA1308.severity = none # Normalize strings to uppercase — ToLowerInvariant is correct for filesystem path / cache key normalization +dotnet_diagnostic.CA1310.severity = none # Covered by PSH1207 (canonical) -################### -# Microsoft .NET Analyzers (CA) - Interoperability Rules -################### +# Interoperability dotnet_diagnostic.CA1401.severity = error # P/Invokes should not be visible -################### -# Microsoft .NET Analyzers (CA) - Maintainability Rules -################### -dotnet_diagnostic.CA1500.severity = error # Variable names should not match field names -dotnet_diagnostic.CA1501.severity = none # Avoid excessive inheritance — disabled because the analyzer noticeably slows down the build -dotnet_diagnostic.CA1502.severity = none # Avoid excessive complexity — disabled because the analyzer noticeably slows down the build +# Maintainability +dotnet_diagnostic.CA1500.severity = none # Variable names should not match field names — covered by SST1484 +dotnet_diagnostic.CA1501.severity = none # Covered by SST1446 (canonical) +dotnet_diagnostic.CA1502.severity = none # Covered by SST1442 (canonical) dotnet_diagnostic.CA1505.severity = error # Avoid unmaintainable code dotnet_diagnostic.CA1506.severity = none # Avoid excessive class coupling — adds little signal here, mostly trips on legitimate orchestration code -dotnet_diagnostic.CA1507.severity = error # Use nameof in place of string +dotnet_diagnostic.CA1507.severity = none # Use nameof in place of string — covered by SST1463 dotnet_diagnostic.CA1508.severity = error # Avoid dead conditional code dotnet_diagnostic.CA1509.severity = error # Invalid entry in code metrics configuration file -dotnet_diagnostic.CA1510.severity = none # Use ArgumentNullException throw helper — disabled because we target older TFMs and use ArgumentExceptionHelper for cross-platform parity -dotnet_diagnostic.CA1511.severity = none # Use ArgumentException throw helper — disabled because we target older TFMs and use ArgumentExceptionHelper for cross-platform parity -dotnet_diagnostic.CA1512.severity = none # Use ArgumentOutOfRangeException throw helper — disabled because we target older TFMs and use ArgumentExceptionHelper for cross-platform parity -dotnet_diagnostic.CA1513.severity = none # Use ObjectDisposedException throw helper — disabled because we target older TFMs and use ArgumentExceptionHelper for cross-platform parity -dotnet_diagnostic.CA1514.severity = error # Avoid redundant length argument +dotnet_diagnostic.CA1510.severity = none # Covered by PSH1409 (canonical) +dotnet_diagnostic.CA1511.severity = none # Covered by PSH1409 (canonical) +dotnet_diagnostic.CA1512.severity = none # Covered by PSH1409 (canonical) +dotnet_diagnostic.CA1513.severity = none # Covered by PSH1409 (canonical) +dotnet_diagnostic.CA1514.severity = none # Avoid redundant length argument — covered by PSH1220 dotnet_diagnostic.CA1515.severity = none # Consider making public types internal — interferes with tests and reflection-discovered types (BenchmarkDotNet, TUnit, etc.) dotnet_diagnostic.CA1516.severity = error # Use cross-platform intrinsics -################### -# Microsoft .NET Analyzers (CA) - Naming Rules -################### +# Naming dotnet_diagnostic.CA1710.severity = suggestion # Identifiers should have correct suffix dotnet_diagnostic.CA1724.severity = none # Type Names Should Not Match Namespaces — namespace/type name overlap is intentional API surface -################### -# Microsoft .NET Analyzers (CA) - Performance Rules -################### -dotnet_diagnostic.CA1802.severity = error # Use literals where appropriate -dotnet_diagnostic.CA1805.severity = error # Do not initialize unnecessarily +# Performance +dotnet_diagnostic.CA1802.severity = none # Use literals where appropriate — covered by PSH1402 +dotnet_diagnostic.CA1805.severity = none # Do not initialize unnecessarily — covered by PSH1403 dotnet_diagnostic.CA1806.severity = error # Do not ignore method results dotnet_diagnostic.CA1810.severity = none # Initialize reference type static fields inline — explicit static constructors are deliberate in some types dotnet_diagnostic.CA1812.severity = error # Avoid uninstantiated internal classes -dotnet_diagnostic.CA1813.severity = error # Avoid unsealed attributes -dotnet_diagnostic.CA1814.severity = error # Prefer jagged arrays over multidimensional -dotnet_diagnostic.CA1815.severity = error # Override equals and operator equals on value types +dotnet_diagnostic.CA1813.severity = none # Avoid unsealed attributes — covered by PSH1401 +dotnet_diagnostic.CA1814.severity = none # Prefer jagged arrays over multidimensional — covered by PSH1020 +dotnet_diagnostic.CA1815.severity = none # Override equals and operator equals on value types — covered by PSH1005 dotnet_diagnostic.CA1819.severity = none # Properties should not return arrays — incompatible with the RxUI/sqlite-net mapping style we use throughout the codebase -dotnet_diagnostic.CA1820.severity = error # Test for empty strings using string length -dotnet_diagnostic.CA1821.severity = error # Remove empty finalizers -dotnet_diagnostic.CA1822.severity = none # Mark members as static — covered by PSH1414 (framework- and interface-aware) -dotnet_diagnostic.CA1823.severity = error # Avoid unused private fields +dotnet_diagnostic.CA1820.severity = none # Test for empty strings using string length — covered by PSH1204 +dotnet_diagnostic.CA1821.severity = none # Remove empty finalizers — covered by PSH1002 +dotnet_diagnostic.CA1822.severity = none # Mark members as static — covered by PSH1414 +dotnet_diagnostic.CA1823.severity = none # Avoid unused private fields — covered by SST1441 dotnet_diagnostic.CA1824.severity = error # Mark assemblies with NeutralResourcesLanguageAttribute -dotnet_diagnostic.CA1825.severity = error # Avoid zero-length array allocations -dotnet_diagnostic.CA1826.severity = error # Use property instead of Linq Enumerable method -dotnet_diagnostic.CA1827.severity = error # Do not use Count/LongCount when Any can be used -dotnet_diagnostic.CA1828.severity = error # Do not use CountAsync/LongCountAsync when AnyAsync can be used -dotnet_diagnostic.CA1829.severity = error # Use Length/Count property instead of Enumerable.Count method -dotnet_diagnostic.CA1830.severity = error # Prefer strongly-typed Append and Insert method overloads on StringBuilder -dotnet_diagnostic.CA1831.severity = error # Use AsSpan instead of Range-based indexers for string when appropriate -dotnet_diagnostic.CA1832.severity = error # Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array -dotnet_diagnostic.CA1833.severity = error # Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array -dotnet_diagnostic.CA1834.severity = error # Use StringBuilder.Append(char) for single character strings -dotnet_diagnostic.CA1835.severity = error # Prefer the memory-based overloads of ReadAsync/WriteAsync methods in stream-based classes -dotnet_diagnostic.CA1836.severity = error # Prefer IsEmpty over Count when available -dotnet_diagnostic.CA1837.severity = error # Use Environment.ProcessId instead of Process.GetCurrentProcess().Id +dotnet_diagnostic.CA1825.severity = none # Avoid zero-length array allocations — covered by PSH1001 +dotnet_diagnostic.CA1826.severity = none # Use property instead of Linq Enumerable method — covered by PSH1103 +dotnet_diagnostic.CA1827.severity = none # Do not use Count/LongCount when Any can be used — covered by PSH1119 +dotnet_diagnostic.CA1828.severity = none # Do not use CountAsync/LongCountAsync when AnyAsync can be used — covered by PSH1126 +dotnet_diagnostic.CA1829.severity = none # Use Length/Count property instead of Enumerable.Count — covered by PSH1103 +dotnet_diagnostic.CA1830.severity = none # Prefer strongly-typed Append/Insert overloads on StringBuilder — covered by PSH1202 +dotnet_diagnostic.CA1831.severity = none # Use AsSpan instead of Range-based indexers for string — covered by PSH1212 +dotnet_diagnostic.CA1832.severity = none # Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array — covered by PSH1019 +dotnet_diagnostic.CA1833.severity = none # Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array — conflicts with PSH1019, which owns the array range-indexer rewrite and refuses it for mutable Span/Memory targets +dotnet_diagnostic.CA1834.severity = none # Use StringBuilder.Append(char) for single character strings — covered by PSH1202 +dotnet_diagnostic.CA1835.severity = none # Prefer the memory-based overloads of ReadAsync/WriteAsync methods in stream-based classes — covered by PSH1314 +dotnet_diagnostic.CA1836.severity = none # Prefer IsEmpty over Count when available — covered by PSH1117 +dotnet_diagnostic.CA1837.severity = none # Use Environment.ProcessId — covered by PSH1405 dotnet_diagnostic.CA1838.severity = error # Avoid StringBuilder parameters for P/Invokes -dotnet_diagnostic.CA1839.severity = error # Use Environment.ProcessPath instead of Process.GetCurrentProcess().MainModule.FileName -dotnet_diagnostic.CA1840.severity = error # Use Environment.CurrentManagedThreadId instead of Thread.CurrentThread.ManagedThreadId -dotnet_diagnostic.CA1841.severity = error # Prefer Dictionary.Contains methods -dotnet_diagnostic.CA1842.severity = error # Do not use 'WhenAll' with a single task -dotnet_diagnostic.CA1843.severity = error # Do not use 'WaitAll' with a single task +dotnet_diagnostic.CA1839.severity = none # Use Environment.ProcessPath — covered by PSH1405 +dotnet_diagnostic.CA1840.severity = none # Use Environment.CurrentManagedThreadId — covered by PSH1405 +dotnet_diagnostic.CA1841.severity = none # Prefer Dictionary.Contains methods — covered by PSH1407 +dotnet_diagnostic.CA1842.severity = none # Do not use 'WhenAll' with a single task — covered by PSH1301 +dotnet_diagnostic.CA1843.severity = none # Do not use 'WaitAll' with a single task — covered by PSH1301 dotnet_diagnostic.CA1844.severity = error # Provide memory-based overrides of async methods when subclassing 'Stream' -dotnet_diagnostic.CA1845.severity = error # Use span-based 'string.Concat' -dotnet_diagnostic.CA1846.severity = error # Prefer AsSpan over Substring -dotnet_diagnostic.CA1847.severity = none # Use char literal for a single character lookup — disabled because the string.Contains(char) overload doesn't exist on .NET Framework / netstandard2.0 and we target both +dotnet_diagnostic.CA1845.severity = none # Use span-based 'string.Concat' — covered by PSH1222 +dotnet_diagnostic.CA1846.severity = none # Prefer AsSpan over Substring — covered by PSH1212 +dotnet_diagnostic.CA1847.severity = none # Covered by PSH1201 (canonical) dotnet_diagnostic.CA1848.severity = error # Use the LoggerMessage delegates -dotnet_diagnostic.CA1849.severity = error # Call async methods when in an async method -dotnet_diagnostic.CA1850.severity = error # Prefer static HashData method over ComputeHash +dotnet_diagnostic.CA1849.severity = none # Call async methods when in an async method — covered by PSH1313 +dotnet_diagnostic.CA1850.severity = none # Prefer static HashData method over ComputeHash — covered by PSH1400 dotnet_diagnostic.CA1851.severity = error # Possible multiple enumerations of IEnumerable collection -dotnet_diagnostic.CA1852.severity = error # Seal internal types +dotnet_diagnostic.CA1852.severity = none # Seal internal types — covered by PSH1411 dotnet_code_quality.CA1852.api_surface = private, internal # only flag non-public classes; public classes stay open for inheritance -dotnet_diagnostic.CA1853.severity = error # Unnecessary call to 'Dictionary.ContainsKey(key)' -dotnet_diagnostic.CA1854.severity = error # Prefer the IDictionary.TryGetValue(TKey, out TValue) method +dotnet_diagnostic.CA1853.severity = none # Unnecessary call to 'Dictionary.ContainsKey(key)' — covered by PSH1105 +dotnet_diagnostic.CA1854.severity = none # Prefer the IDictionary.TryGetValue method — covered by PSH1104 dotnet_diagnostic.CA1855.severity = error # Prefer 'Clear' over 'Fill' dotnet_diagnostic.CA1856.severity = error # Incorrect usage of ConstantExpected attribute dotnet_diagnostic.CA1857.severity = error # A constant is expected for the parameter -dotnet_diagnostic.CA1858.severity = error # Use 'StartsWith' instead of 'IndexOf' +dotnet_diagnostic.CA1858.severity = none # Use 'StartsWith' instead of 'IndexOf' — covered by PSH1221 dotnet_diagnostic.CA1859.severity = error # Use concrete types when possible for improved performance -dotnet_diagnostic.CA1860.severity = error # Avoid using 'Enumerable.Any()' extension method -dotnet_diagnostic.CA1861.severity = error # Avoid constant arrays as arguments -dotnet_diagnostic.CA1862.severity = error # Use the 'StringComparison' method overloads to perform case-insensitive string comparisons -dotnet_diagnostic.CA1863.severity = none # Use 'CompositeFormat' — covered by PSH1223 (CompositeFormat is unavailable on the net4x target legs) -dotnet_diagnostic.CA1864.severity = error # Prefer the 'IDictionary.TryAdd(TKey, TValue)' method -dotnet_diagnostic.CA1865.severity = none # Use char overload (string.StartsWith) — disabled because the string.StartsWith(char) overload doesn't exist on .NET Framework / netstandard2.0 and we target both -dotnet_diagnostic.CA1866.severity = none # Use char overload (string.EndsWith) — disabled because the string.EndsWith(char) overload doesn't exist on .NET Framework / netstandard2.0 and we target both -dotnet_diagnostic.CA1867.severity = none # Use char overload (string.IndexOf / string.LastIndexOf) — disabled because the char overloads don't exist on .NET Framework / netstandard2.0 and we target both -dotnet_diagnostic.CA1868.severity = error # Unnecessary call to 'Contains' for sets -dotnet_diagnostic.CA1869.severity = error # Cache and reuse 'JsonSerializerOptions' instances -dotnet_diagnostic.CA1870.severity = error # Use a cached 'SearchValues' instance +dotnet_diagnostic.CA1860.severity = none # Avoid using 'Enumerable.Any()' extension method — covered by PSH1103 +dotnet_diagnostic.CA1861.severity = none # Avoid constant arrays as arguments — covered by PSH1004 +dotnet_diagnostic.CA1862.severity = none # Use the 'StringComparison' overloads for case-insensitive comparisons — covered by PSH1200 +dotnet_diagnostic.CA1863.severity = none # Use 'CompositeFormat' — covered by PSH1223 +dotnet_diagnostic.CA1864.severity = none # Prefer the 'IDictionary.TryAdd' method — covered by PSH1115 +dotnet_diagnostic.CA1865.severity = none # Covered by PSH1201 (canonical) +dotnet_diagnostic.CA1866.severity = none # Covered by PSH1201 (canonical) +dotnet_diagnostic.CA1867.severity = none # Covered by PSH1201 (canonical) +dotnet_diagnostic.CA1868.severity = none # Unnecessary call to 'Contains' for sets — covered by PSH1105 +dotnet_diagnostic.CA1869.severity = none # Cache and reuse 'JsonSerializerOptions' instances — covered by PSH1416 +dotnet_diagnostic.CA1870.severity = none # Use a cached 'SearchValues' instance — covered by PSH1213 dotnet_diagnostic.CA1871.severity = error # Do not pass a nullable struct to 'ArgumentNullException.ThrowIfNull' -dotnet_diagnostic.CA1872.severity = error # Prefer 'Convert.ToHexString' and 'Convert.ToHexStringLower' over call chains based on 'BitConverter.ToString' -dotnet_diagnostic.CA1873.severity = error # Avoid potentially expensive evaluation of arguments to 'Debug.Assert' -dotnet_diagnostic.CA1874.severity = error # Use 'Regex.IsMatch' -dotnet_diagnostic.CA1875.severity = error # Use 'Regex.Count' -dotnet_diagnostic.CA1877.severity = error # Use 'Encoding.GetString' instead of 'Encoding.GetChars' +dotnet_diagnostic.CA1872.severity = none # Prefer 'Convert.ToHexString' and 'Convert.ToHexStringLower' over call chains based on 'BitConverter.ToString' — covered by PSH1224 +dotnet_diagnostic.CA1873.severity = none # Avoid potentially expensive evaluation of arguments to 'Debug.Assert' — covered by PSH1417 +dotnet_diagnostic.CA1874.severity = none # Use 'Regex.IsMatch' — covered by PSH1406 +dotnet_diagnostic.CA1875.severity = none # Use 'Regex.Count' — covered by PSH1406 +dotnet_diagnostic.CA1877.severity = none # Use 'Encoding.GetString' instead of 'Encoding.GetChars' — covered by PSH1225 -################### -# Microsoft .NET Analyzers (CA) - Reliability Rules -################### +# Reliability dotnet_diagnostic.CA2000.severity = suggestion # Dispose objects before losing scope dotnet_diagnostic.CA2002.severity = error # Do not lock on objects with weak identity dotnet_diagnostic.CA2007.severity = none # Do not directly await a Task — Rx and library callers drive synchronization context themselves @@ -368,41 +360,39 @@ dotnet_diagnostic.CA2024.severity = error # Do not use 'StreamReader.EndOfStream dotnet_diagnostic.CA2025.severity = error # Do not pass 'IDisposable' instances into unawaited tasks dotnet_diagnostic.CA2026.severity = error # Do not use methods or types annotated with [RequiresDynamicCode] in code that uses [RequiresDynamicCode] -################### -# Microsoft .NET Analyzers (CA) - Usage Rules -################### +# Usage dotnet_diagnostic.CA1801.severity = error # Review unused parameters dotnet_code_quality.CA1801.api_surface = private, internal # only flag non-public APIs so we don't break public signatures dotnet_diagnostic.CA1816.severity = error # Call GC.SuppressFinalize correctly -dotnet_diagnostic.CA2200.severity = error # Rethrow to preserve stack details +dotnet_diagnostic.CA2200.severity = none # Rethrow to preserve stack details — covered by SST1430 dotnet_diagnostic.CA2201.severity = error # Do not raise reserved exception types dotnet_diagnostic.CA2207.severity = error # Initialize value type static fields inline dotnet_diagnostic.CA2208.severity = none # Instantiate argument exceptions correctly — too sensitive: flags valid context-forwarding nameof(arg.Property) patterns -dotnet_diagnostic.CA2211.severity = error # Non-constant fields should not be visible -dotnet_diagnostic.CA2213.severity = none # Disposable fields should be disposed — covered by SST2315/SST2410 (ownership-aware; CA2213 misfires on back-references and passed-in disposables) -dotnet_diagnostic.CA2214.severity = error # Do not call overridable methods in constructors +dotnet_diagnostic.CA2211.severity = none # Non-constant fields should not be visible — covered by SST1499 +dotnet_diagnostic.CA2213.severity = error # Disposable fields should be disposed +dotnet_diagnostic.CA2214.severity = none # Do not call overridable methods in constructors — covered by SST1483 dotnet_diagnostic.CA2215.severity = error # Dispose methods should call base class dispose -dotnet_diagnostic.CA2216.severity = error # Disposable types should declare finalizer -dotnet_diagnostic.CA2217.severity = error # Do not mark enums with FlagsAttribute +dotnet_diagnostic.CA2216.severity = none # Disposable types should declare finalizer — conflicts with SST2317, which owns the owned-native-handle shape and prescribes a SafeHandle instead of a finalizer +dotnet_diagnostic.CA2217.severity = none # Do not mark enums with FlagsAttribute — covered by SST2303 dotnet_diagnostic.CA2218.severity = error # Override GetHashCode on overriding Equals dotnet_diagnostic.CA2219.severity = error # Do not raise exceptions in finally clauses -dotnet_diagnostic.CA2224.severity = error # Override Equals on overloading operator equals +dotnet_diagnostic.CA2224.severity = none # Override Equals on overloading operator equals — covered by SST2302 dotnet_diagnostic.CA2225.severity = error # Operator overloads have named alternates dotnet_diagnostic.CA2226.severity = error # Operators should have symmetrical overloads dotnet_diagnostic.CA2227.severity = none # Collection properties should be read only — settable collection properties are common in our DTOs and config types dotnet_diagnostic.CA2231.severity = error # Overload operator equals on overriding ValueType.Equals dotnet_diagnostic.CA2234.severity = error # Pass System.Uri objects instead of strings dotnet_diagnostic.CA2241.severity = error # Provide correct arguments to formatting methods -dotnet_diagnostic.CA2242.severity = error # Test for NaN correctly +dotnet_diagnostic.CA2242.severity = none # Test for NaN correctly — covered by SST1473 dotnet_diagnostic.CA2243.severity = error # Attribute string literals should parse correctly dotnet_diagnostic.CA2244.severity = error # Do not duplicate indexed element initializations -dotnet_diagnostic.CA2245.severity = error # Do not assign a property to itself +dotnet_diagnostic.CA2245.severity = none # Do not assign a property to itself — covered by SST1189 dotnet_diagnostic.CA2246.severity = error # Do not assign a symbol and its member in the same statement dotnet_diagnostic.CA2247.severity = error # Argument passed to TaskCompletionSource constructor should be TaskCreationOptions enum dotnet_diagnostic.CA2248.severity = error # Provide correct enum argument to Enum.HasFlag dotnet_diagnostic.CA2249.severity = error # Use String.Contains instead of String.IndexOf for substring checks dotnet_diagnostic.CA2250.severity = error # Use ThrowIfCancellationRequested -dotnet_diagnostic.CA2251.severity = error # Use String.Equals over String.Compare +dotnet_diagnostic.CA2251.severity = none # Covered by PSH1216 (canonical) dotnet_diagnostic.CA2252.severity = error # Opt in to preview features before using them dotnet_diagnostic.CA2253.severity = error # Named placeholders should not be numeric values dotnet_diagnostic.CA2254.severity = error # Template should be a static expression @@ -423,9 +413,7 @@ dotnet_diagnostic.CA2268.severity = error # Use 'string.Equals(string, string, S # Skipped (deprecated ISerializable formatter): CA2229 Implement serialization constructors, # CA2235 Mark all non-serializable fields, CA2237 Mark ISerializable types with SerializableAttribute. -################### -# Microsoft .NET Analyzers (CA) - Security Rules -################### +# Security # SQL Injection & Command Injection dotnet_diagnostic.CA2100.severity = error # Review SQL queries for security vulnerabilities @@ -548,15 +536,9 @@ dotnet_diagnostic.CA2153.severity = error # Do not catch corrupted state excepti dotnet_diagnostic.CA5367.severity = error # Do not serialize types with pointer fields ################### -# SonarAnalyzer (Sxxxx) — global suppressions -################### -dotnet_diagnostic.S1075.severity = none # Hardcoded URI — canonical SourceLink hosts are the point -dotnet_diagnostic.S2436.severity = none # Too many generic parameters — needed for the projector overload -dotnet_diagnostic.S4036.severity = none # PATH-relative process spawn — benchmark only, trusted env - -################### -# Microsoft .NET Runtime Obsoletions (SYSLIB0xxx) +# Microsoft .NET SDK Diagnostics (SYSLIB) ################### +# Runtime obsoletions dotnet_diagnostic.SYSLIB0001.severity = error # The UTF-7 encoding is insecure and should not be used dotnet_diagnostic.SYSLIB0002.severity = error # PrincipalPermissionAttribute is not honored by the runtime and must not be used dotnet_diagnostic.SYSLIB0003.severity = error # Code Access Security (CAS) is not supported or honored by the runtime @@ -619,9 +601,7 @@ dotnet_diagnostic.SYSLIB0059.severity = error # SystemEvents.EventsThreadShutdow dotnet_diagnostic.SYSLIB0060.severity = error # Constructors of DirectoryServices.ActiveDirectory.ConfigurationContext are obsolete dotnet_diagnostic.SYSLIB0061.severity = error # CryptographyConfig.AddOID and AddAlgorithm methods are obsolete -################### -# Microsoft .NET Source Generator Diagnostics (SYSLIB1xxx) -################### +# Source generators # LoggerMessage source generator dotnet_diagnostic.SYSLIB1001.severity = error # Logging method names cannot start with _ dotnet_diagnostic.SYSLIB1002.severity = error # Don't include log level parameters as templates in the logging message @@ -709,8 +689,9 @@ dotnet_diagnostic.SYSLIB1103.severity = error # Configuration binding source gen dotnet_diagnostic.SYSLIB1104.severity = error # Configuration binding source generator: language version is too low ################### -# Microsoft .NET Style Rules (IDExxxx) - Language Rules +# Microsoft .NET Code Style Analyzers (IDE) ################### +# Language rules # EnforceCodeStyleInBuild=true (set in Directory.Build.props) promotes these # IDE rules into `dotnet build` so they fire at compile time, not just in the # IDE. We enable the ones that are unambiguous wins and skip the rules that @@ -718,8 +699,8 @@ dotnet_diagnostic.SYSLIB1104.severity = error # Configuration binding source gen # etc.) so we don't double-report. # Bug catchers — always error. -dotnet_diagnostic.IDE0035.severity = error # Remove unreachable code -dotnet_diagnostic.IDE0043.severity = error # Format string contains invalid placeholder +dotnet_diagnostic.IDE0035.severity = none # Remove unreachable code — covered by SST1453 +dotnet_diagnostic.IDE0043.severity = none # Format string contains invalid placeholder — covered by SST1454 dotnet_diagnostic.IDE0052.severity = none # Remove unread private member — covered by SST1441 # Simplification / cleanup. @@ -733,18 +714,18 @@ dotnet_diagnostic.IDE0038.severity = none # Use pattern matching ('is' check wit dotnet_diagnostic.IDE0041.severity = none # Use 'is null' check — covered by SST1149/SST2231/SST2282 dotnet_diagnostic.IDE0042.severity = none # Deconstruct variable declaration — covered by SST2214 dotnet_diagnostic.IDE0044.severity = none # Add readonly modifier — covered by SST1424 -dotnet_diagnostic.IDE0047.severity = error # Remove unnecessary parentheses +dotnet_diagnostic.IDE0047.severity = none # Remove unnecessary parentheses — covered by SST1459 dotnet_diagnostic.IDE0049.severity = none # Use language keywords instead of framework type names for type references — covered by SST1121 dotnet_diagnostic.IDE0057.severity = none # Use range operator — covered by SST2204 dotnet_diagnostic.IDE0059.severity = none # Remove unnecessary value assignment — covered by SST2222 -dotnet_diagnostic.IDE0064.severity = error # Make struct fields writable — flag readonly-but-mutable struct fields where intent diverges from declaration +dotnet_diagnostic.IDE0064.severity = none # Make struct fields writable — flag readonly-but-mutable struct fields where intent diverges from declaration dotnet_diagnostic.IDE0066.severity = none # Use switch expression — covered by SST2201 dotnet_diagnostic.IDE0075.severity = none # Simplify conditional expression — covered by SST1182 dotnet_diagnostic.IDE0078.severity = none # Use pattern matching — covered by SST2006/SST2231 -dotnet_diagnostic.IDE0084.severity = error # Use pattern matching ('IsNot' operator) -dotnet_diagnostic.IDE0120.severity = none # Simplify LINQ expression — covered by SST2229/SST2233 +dotnet_diagnostic.IDE0084.severity = none # Use pattern matching ('IsNot' operator) +dotnet_diagnostic.IDE0120.severity = none # Simplify LINQ expression — covered by PSH1100/PSH1101 dotnet_diagnostic.IDE0221.severity = none # Add explicit cast — covered by SST2226 -dotnet_diagnostic.IDE0250.severity = error # Make struct 'readonly' +dotnet_diagnostic.IDE0250.severity = none # Make struct 'readonly' — covered by PSH1014 dotnet_diagnostic.IDE0260.severity = none # Use pattern matching — covered by SST2006/SST2231 # Disabled — conflict with an existing SA/CA rule or project convention. @@ -769,15 +750,77 @@ dotnet_diagnostic.IDE0210.severity = none # Convert to top-level statements — dotnet_diagnostic.IDE0211.severity = none # Convert to 'Program.Main' style — we use Main style dotnet_diagnostic.IDE0300.severity = none # Use collection expression for array — covered by SST2101 dotnet_diagnostic.IDE0306.severity = none # Use collection expression for new — covered by SST2101 -dotnet_diagnostic.IDE0320.severity = error # Make anonymous function static — eliminates the closure-capture display class allocation +dotnet_diagnostic.IDE0320.severity = none # Make anonymous function static — covered by PSH1000 dotnet_diagnostic.IDE0050.severity = none # Convert anonymous type to tuple — covered by SST2224 dotnet_diagnostic.IDE0310.severity = none # Convert lambda expression to method group — handled by RCS1207 dotnet_diagnostic.IDE0360.severity = none # Simplify property accessor — covered by SST2219 dotnet_diagnostic.IDE0370.severity = none # Remove unnecessary suppression (null-forgiving operator) — disabled for the same reason as RCS1249: multi-TFM nullability annotations can differ per platform -################### -# Microsoft .NET Style Rules (IDE1xxx / IDE3xxx) - Naming & Miscellaneous -################### +# Language and unnecessary code rules. +dotnet_diagnostic.IDE0001.severity = none # Simplify name +dotnet_diagnostic.IDE0003.severity = none # Name can be simplified +dotnet_diagnostic.IDE0005.severity = none # Remove unnecessary import +dotnet_diagnostic.IDE0010.severity = none # Add missing cases to switch statement +dotnet_diagnostic.IDE0011.severity = none # Add braces +dotnet_diagnostic.IDE0017.severity = none # Use object initializers +dotnet_diagnostic.IDE0018.severity = none # Inline variable declaration +dotnet_diagnostic.IDE0020.severity = none # Use pattern matching to avoid is check followed by a cast (with variable) +dotnet_diagnostic.IDE0027.severity = none # Use expression body for accessors +dotnet_diagnostic.IDE0029.severity = none # Null check can be simplified +dotnet_diagnostic.IDE0030.severity = none # Null check can be simplified +dotnet_diagnostic.IDE0032.severity = none # Use auto property +dotnet_diagnostic.IDE0033.severity = none # Use explicitly provided tuple name +dotnet_diagnostic.IDE0034.severity = none # Simplify default expression +dotnet_diagnostic.IDE0036.severity = none # Order modifiers +dotnet_diagnostic.IDE0037.severity = none # Use inferred member name +dotnet_diagnostic.IDE0039.severity = none # Use local function instead of lambda +dotnet_diagnostic.IDE0040.severity = none # Add accessibility modifiers +dotnet_diagnostic.IDE0045.severity = none # Use conditional expression for assignment +dotnet_diagnostic.IDE0046.severity = none # Use conditional expression for return +dotnet_diagnostic.IDE0051.severity = none # Remove unused private member +dotnet_diagnostic.IDE0053.severity = none # Use expression body for lambdas +dotnet_diagnostic.IDE0054.severity = none # Use compound assignment +dotnet_diagnostic.IDE0056.severity = none # Use index operator +dotnet_diagnostic.IDE0062.severity = none # Make local function static +dotnet_diagnostic.IDE0063.severity = none # Use simple using statement +dotnet_diagnostic.IDE0065.severity = none # Using directive placement +dotnet_diagnostic.IDE0070.severity = none # Use System.HashCode.Combine +dotnet_diagnostic.IDE0071.severity = none # Simplify interpolation +dotnet_diagnostic.IDE0072.severity = none # Add missing cases to switch expression +dotnet_diagnostic.IDE0073.severity = none # Use file header +dotnet_diagnostic.IDE0074.severity = none # Use coalesce compound assignment +dotnet_diagnostic.IDE0076.severity = none # Remove invalid global SuppressMessageAttribute +dotnet_diagnostic.IDE0077.severity = none # Avoid legacy format target in global SuppressMessageAttribute +dotnet_diagnostic.IDE0080.severity = none # Remove unnecessary suppression operator +dotnet_diagnostic.IDE0082.severity = none # Convert typeof to nameof +dotnet_diagnostic.IDE0083.severity = none # Use pattern matching (not operator) +dotnet_diagnostic.IDE0090.severity = none # Simplify new expression +dotnet_diagnostic.IDE0100.severity = none # Remove unnecessary equality operator +dotnet_diagnostic.IDE0110.severity = none # Remove unnecessary discard +dotnet_diagnostic.IDE0150.severity = none # Prefer null check over type check +dotnet_diagnostic.IDE0161.severity = none # Use file-scoped namespace +dotnet_diagnostic.IDE0170.severity = none # Simplify property pattern +dotnet_diagnostic.IDE0180.severity = none # Use tuple to swap values +dotnet_diagnostic.IDE0200.severity = none # Remove unnecessary lambda expression +dotnet_diagnostic.IDE0220.severity = none # Add explicit cast in foreach loop +dotnet_diagnostic.IDE0230.severity = none # Use UTF-8 string literal +dotnet_diagnostic.IDE0240.severity = none # Nullable directive is redundant +dotnet_diagnostic.IDE0241.severity = none # Nullable directive is unnecessary +dotnet_diagnostic.IDE0251.severity = none # Member can be made readonly +dotnet_diagnostic.IDE0270.severity = none # Null check can be simplified +dotnet_diagnostic.IDE0280.severity = none # Use nameof +dotnet_diagnostic.IDE0290.severity = none # Use primary constructor +dotnet_diagnostic.IDE0301.severity = none # Use collection expression for empty +dotnet_diagnostic.IDE0302.severity = none # Use collection expression for stackalloc +dotnet_diagnostic.IDE0303.severity = none # Use collection expression for Create() +dotnet_diagnostic.IDE0304.severity = none # Use collection expression for builder +dotnet_diagnostic.IDE0305.severity = none # Use collection expression for fluent +dotnet_diagnostic.IDE0340.severity = none # Use unbound generic type +dotnet_diagnostic.IDE0350.severity = none # Use implicitly typed lambda +dotnet_diagnostic.IDE0380.severity = none # Remove unnecessary unsafe modifier +dotnet_diagnostic.IDE1005.severity = none # Use conditional delegate call + +# Naming and miscellaneous # Naming conventions — SA1300 family already enforces PascalCase / interface # prefix / field casing (with our _underscore convention on SA1306/1309/1311 # deliberately disabled). Leaving IDE1006 off because configuring @@ -787,37 +830,41 @@ dotnet_diagnostic.IDE1006.severity = none # Naming rule violation — SA1300 fam dotnet_diagnostic.IDE3000.severity = none # Disabled per project convention — not enforced ################### -# Roslynator Analyzers (RCS1xxx) - Code Simplification +# Roslynator.CSharp.Analyzers (RCS) ################### -dotnet_diagnostic.RCS1001.severity = error # Add braces (when expression spans over multiple lines) -dotnet_diagnostic.RCS1003.severity = error # Add braces to if-else (when expression spans over multiple lines) +# Code simplification +dotnet_diagnostic.RCS1001.severity = none # Add braces (when expression spans over multiple lines) — covered by SST1519 +dotnet_diagnostic.RCS1003.severity = none # Add braces to if-else (when expression spans over multiple lines) — covered by SST1519 dotnet_diagnostic.RCS1005.severity = error # Simplify nested using statement -dotnet_diagnostic.RCS1006.severity = error # Merge 'else' with nested 'if' +dotnet_diagnostic.RCS1006.severity = none # Merge 'else' with nested 'if' — covered by SST1465 dotnet_diagnostic.RCS1007.severity = error # Add braces dotnet_diagnostic.RCS1031.severity = none # Remove unnecessary braces in switch section -- we don't mind braces in switch statements dotnet_diagnostic.RCS1032.severity = error # Remove redundant parentheses -dotnet_diagnostic.RCS1033.severity = error # Remove redundant boolean literal -dotnet_diagnostic.RCS1039.severity = error # Remove argument list from attribute +dotnet_diagnostic.RCS1033.severity = none # Remove redundant boolean literal — covered by SST1143 +dotnet_diagnostic.RCS1039.severity = none # Remove argument list from attribute — covered by SST1411 +dotnet_diagnostic.RCS1040.severity = none # Remove empty statement — covered by SST1180 dotnet_diagnostic.RCS1042.severity = none # Remove enum default underlying type — covered by SST1177 dotnet_diagnostic.RCS1043.severity = error # Remove 'partial' modifier from type with a single part -dotnet_diagnostic.RCS1049.severity = error # Simplify boolean comparison +dotnet_diagnostic.RCS1049.severity = none # Simplify boolean comparison — covered by SST1143 dotnet_diagnostic.RCS1058.severity = none # Use compound assignment — covered by SST1185 -dotnet_diagnostic.RCS1061.severity = error # Merge 'if' with nested 'if' +dotnet_diagnostic.RCS1061.severity = none # Merge 'if' with nested 'if' — covered by SST2013 dotnet_diagnostic.RCS1068.severity = none # Simplify logical negation — covered by SST1172/SST2006 -dotnet_diagnostic.RCS1069.severity = error # Remove unnecessary case label +dotnet_diagnostic.RCS1069.severity = none # Remove unnecessary case label — covered by SST1466 dotnet_diagnostic.RCS1070.severity = none # Remove redundant default switch section — covered by SST1179 dotnet_diagnostic.RCS1071.severity = none # Remove redundant base constructor call — covered by SST1178 -dotnet_diagnostic.RCS1073.severity = error # Convert 'if' to 'return' statement +dotnet_diagnostic.RCS1072.severity = none # Remove empty namespace declaration — covered by SST1435 +dotnet_diagnostic.RCS1073.severity = none # Convert 'if' to 'return' statement — covered by SST1197 dotnet_diagnostic.RCS1074.severity = none # Remove redundant constructor — covered by SST1433 -dotnet_diagnostic.RCS1078.severity = error # Use "" or 'string.Empty' -dotnet_diagnostic.RCS1084.severity = error # Use coalesce expression instead of conditional expression -dotnet_diagnostic.RCS1085.severity = error # Use auto-implemented property +dotnet_diagnostic.RCS1078.severity = none # Use "" or 'string.Empty' — conflicts with SST1122, which owns the string.Empty direction +dotnet_diagnostic.RCS1084.severity = none # Use coalesce expression instead of conditional expression — covered by SST1195 +dotnet_diagnostic.RCS1085.severity = none # Use auto-implemented property — covered by SST1420 dotnet_diagnostic.RCS1089.severity = error # Use --/++ operator instead of assignment dotnet_diagnostic.RCS1097.severity = error # Remove redundant 'ToString' call dotnet_diagnostic.RCS1103.severity = error # Convert 'if' to assignment dotnet_diagnostic.RCS1104.severity = none # Simplify conditional expression — covered by SST1182 dotnet_diagnostic.RCS1105.severity = error # Unnecessary interpolation -dotnet_diagnostic.RCS1107.severity = error # Remove redundant 'ToCharArray' call +dotnet_diagnostic.RCS1106.severity = none # Remove empty destructor — covered by PSH1002 +dotnet_diagnostic.RCS1107.severity = none # Remove redundant 'ToCharArray' call — covered by PSH1217 dotnet_diagnostic.RCS1114.severity = error # Remove redundant delegate creation dotnet_diagnostic.RCS1124.severity = error # Inline local variable dotnet_diagnostic.RCS1126.severity = error # Add braces to if-else @@ -825,144 +872,138 @@ dotnet_diagnostic.RCS1128.severity = error # Use coalesce expression dotnet_diagnostic.RCS1129.severity = none # Remove redundant field initialization — covered by SST1176 dotnet_diagnostic.RCS1132.severity = none # Remove redundant overriding member — covered by SST1181 dotnet_diagnostic.RCS1133.severity = error # Remove redundant Dispose/Close call -dotnet_diagnostic.RCS1134.severity = error # Remove redundant statement +dotnet_diagnostic.RCS1134.severity = none # Remove redundant statement — covered by SST1174 dotnet_diagnostic.RCS1143.severity = error # Simplify coalesce expression dotnet_diagnostic.RCS1145.severity = error # Remove redundant 'as' operator dotnet_diagnostic.RCS1146.severity = error # Use conditional access dotnet_diagnostic.RCS1151.severity = none # Remove redundant cast — covered by SST1175 dotnet_diagnostic.RCS1171.severity = error # Simplify lazy initialization dotnet_diagnostic.RCS1173.severity = error # Use coalesce expression instead of 'if' -dotnet_diagnostic.RCS1174.severity = error # Remove redundant async/await +dotnet_diagnostic.RCS1174.severity = none # Remove redundant async/await — covered by PSH1311 dotnet_diagnostic.RCS1179.severity = error # Unnecessary assignment dotnet_diagnostic.RCS1180.severity = error # Inline lazy initialization dotnet_diagnostic.RCS1188.severity = none # Remove redundant auto-property initialization — covered by SST1176 dotnet_diagnostic.RCS1192.severity = none # Unnecessary usage of verbatim string literal — covered by SST1184 dotnet_diagnostic.RCS1199.severity = error # Unnecessary null check dotnet_diagnostic.RCS1206.severity = error # Use conditional access instead of conditional expression -dotnet_diagnostic.RCS1207.severity = error # Use anonymous function or method group -dotnet_diagnostic.RCS1211.severity = error # Remove unnecessary 'else' +dotnet_diagnostic.RCS1207.severity = none # Use anonymous function or method group — conflicts with SST2239, which owns the method-group direction +dotnet_diagnostic.RCS1211.severity = none # Remove unnecessary 'else' — covered by SST1464 dotnet_diagnostic.RCS1212.severity = error # Remove redundant assignment dotnet_diagnostic.RCS1214.severity = none # Unnecessary interpolated string — covered by SST1183 dotnet_diagnostic.RCS1216.severity = error # Unnecessary unsafe context -dotnet_diagnostic.RCS1217.severity = error # Convert interpolated string to concatenation +dotnet_diagnostic.RCS1217.severity = none # Convert interpolated string to concatenation — reverses SST2249, which owns the concatenation-to-interpolation direction dotnet_diagnostic.RCS1218.severity = error # Simplify code branching -dotnet_diagnostic.RCS1220.severity = error # Use pattern matching instead of combination of 'is' and cast -dotnet_diagnostic.RCS1221.severity = none # Use pattern matching instead of combination of 'as' and null check - covered by SST2274 -dotnet_diagnostic.RCS1238.severity = error # Avoid nested ?: operators -dotnet_diagnostic.RCS1244.severity = error # Simplify 'default' expression +dotnet_diagnostic.RCS1220.severity = none # Use pattern matching instead of combination of 'is' and cast — covered by SST2007 +dotnet_diagnostic.RCS1221.severity = error # Use pattern matching instead of combination of 'as' and null check +dotnet_diagnostic.RCS1238.severity = none # Avoid nested ?: operators — covered by SST1147 +dotnet_diagnostic.RCS1244.severity = none # Simplify 'default' expression — covered by SST1188 dotnet_diagnostic.RCS1249.severity = none # Unnecessary null-forgiving operator — disabled because multi-TFM nullability annotations can differ per platform, leading to false positives dotnet_diagnostic.RCS1251.severity = error # Remove unnecessary braces from record declaration dotnet_diagnostic.RCS1259.severity = error # Remove empty syntax (replaces RCS1066) dotnet_diagnostic.RCS1262.severity = error # Unnecessary raw string literal -dotnet_diagnostic.RCS1265.severity = error # Remove redundant catch block +dotnet_diagnostic.RCS1265.severity = none # Remove redundant catch block — covered by SST1470 dotnet_diagnostic.RCS1268.severity = error # Simplify numeric comparison -################### -# Roslynator Analyzers (RCS1xxx) - Code Quality -################### -dotnet_diagnostic.RCS1013.severity = error # Use predefined type +# Code quality +dotnet_diagnostic.RCS1013.severity = none # Use predefined type — covered by SST1121 dotnet_diagnostic.RCS1014.severity = error # Use explicitly/implicitly typed array dotnet_diagnostic.RCS1015.severity = error # Use nameof operator -dotnet_diagnostic.RCS1016.severity = none # Use block body or expression body - covered by SST2275-2281 -dotnet_diagnostic.RCS1020.severity = error # Simplify Nullable to T? -dotnet_diagnostic.RCS1021.severity = none # Convert lambda expression body to expression body — covered by SST2257/SST2275 +dotnet_diagnostic.RCS1016.severity = none # Use block body or expression body — conflicts with SST2219, which owns the expression-bodied accessor direction +dotnet_diagnostic.RCS1020.severity = none # Covered by SST2234 (canonical) +dotnet_diagnostic.RCS1021.severity = error # Convert lambda expression body to expression body dotnet_diagnostic.RCS1044.severity = none # Remove original exception from throw statement — covered by SST1430 dotnet_diagnostic.RCS1046.severity = none # Asynchronous method name should end with 'Async' — TUnit test method naming convention doesn't follow the Async suffix — covered by SST1317 dotnet_diagnostic.RCS1047.severity = error # Non-asynchronous method name should not end with 'Async' -dotnet_diagnostic.RCS1048.severity = error # Use lambda expression instead of anonymous method +dotnet_diagnostic.RCS1048.severity = none # Use lambda expression instead of anonymous method — covered by SST1130 dotnet_diagnostic.RCS1050.severity = error # Include/omit parentheses when creating new object -dotnet_diagnostic.RCS1051.severity = error # Add/remove parentheses from condition in conditional operator +dotnet_diagnostic.RCS1051.severity = none # Add/remove parentheses from condition in conditional operator — conflicts with SST1459, which owns the non-grouping-parenthesis removal direction dotnet_diagnostic.RCS1056.severity = none # Avoid usage of using alias directive - used to avoid conflicts -dotnet_diagnostic.RCS1059.severity = error # Avoid locking on publicly accessible instance +dotnet_diagnostic.RCS1059.severity = none # Avoid locking on publicly accessible instance — covered by SST1901 dotnet_diagnostic.RCS1075.severity = none # Avoid empty catch clause that catches System.Exception — covered by SST1429 dotnet_diagnostic.RCS1079.severity = error # Throwing of new NotImplementedException dotnet_diagnostic.RCS1081.severity = error # Split variable declaration dotnet_diagnostic.RCS1093.severity = error # File contains no code -dotnet_diagnostic.RCS1094.severity = error # Declare using directive on top level -dotnet_diagnostic.RCS1096.severity = error # Use 'HasFlag' method or bitwise operator +dotnet_diagnostic.RCS1094.severity = none # Declare using directive on top level — covered by SST1200 +dotnet_diagnostic.RCS1096.severity = none # Use 'HasFlag' method or bitwise operator — covered by PSH1016 dotnet_diagnostic.RCS1098.severity = none # Constant values should be placed on right side of comparisons — covered by SST1186 -dotnet_diagnostic.RCS1099.severity = error # Default label should be the last label in a switch section +dotnet_diagnostic.RCS1099.severity = none # Default label should be the last label in a switch section — covered by SST1466 dotnet_diagnostic.RCS1102.severity = none # Make class static — covered by SST1432 dotnet_diagnostic.RCS1108.severity = error # Add 'static' modifier to all partial class declarations dotnet_diagnostic.RCS1111.severity = error # Add braces to switch section with multiple statements dotnet_diagnostic.RCS1113.severity = error # Use 'string.IsNullOrEmpty' method -dotnet_diagnostic.RCS1118.severity = error # Mark local variable as const -dotnet_diagnostic.RCS1123.severity = error # Add parentheses when necessary -dotnet_diagnostic.RCS1130.severity = error # Bitwise operation on enum without Flags attribute +dotnet_diagnostic.RCS1118.severity = none # Mark local variable as const — covered by PSH1402 +dotnet_diagnostic.RCS1123.severity = none # Add parentheses when necessary — covered by SST1407 +dotnet_diagnostic.RCS1130.severity = none # Bitwise operation on enum without Flags attribute — covered by SST2458 dotnet_diagnostic.RCS1135.severity = error # Declare enum member with zero value (when enum has FlagsAttribute) -dotnet_diagnostic.RCS1136.severity = error # Merge switch sections with equivalent content +dotnet_diagnostic.RCS1136.severity = none # Merge switch sections with equivalent content — covered by SST2414 dotnet_diagnostic.RCS1154.severity = error # Sort enum members -dotnet_diagnostic.RCS1155.severity = error # Use StringComparison when comparing strings -dotnet_diagnostic.RCS1156.severity = error # Use string.Length instead of comparison with empty string -dotnet_diagnostic.RCS1157.severity = error # Composite enum value contains undefined flag -dotnet_diagnostic.RCS1159.severity = none # Use EventHandler - superseded by SST2304 (Roslynator twin of the disabled S3908) +dotnet_diagnostic.RCS1155.severity = none # Use StringComparison when comparing strings — covered by PSH1207 +dotnet_diagnostic.RCS1156.severity = none # Use string.Length instead of comparison with empty string — covered by PSH1204 +dotnet_diagnostic.RCS1157.severity = none # Composite enum value contains undefined flag — covered by SST2303 +dotnet_diagnostic.RCS1159.severity = error # Use EventHandler dotnet_diagnostic.RCS1160.severity = none # Abstract type should not have public constructors — covered by SST1428 dotnet_diagnostic.RCS1161.severity = none # Enum should declare explicit values - do not need explicit values dotnet_diagnostic.RCS1162.severity = none # Avoid chain of assignments — covered by SST1187 -dotnet_diagnostic.RCS1166.severity = error # Value type object is never equal to null +dotnet_diagnostic.RCS1166.severity = none # Value type object is never equal to null — covered by SST1469 dotnet_diagnostic.RCS1168.severity = none # Parameter name differs from base name — covered by SST1318 dotnet_diagnostic.RCS1169.severity = error # Make field read-only dotnet_diagnostic.RCS1170.severity = error # Use read-only auto-implemented property dotnet_diagnostic.RCS1172.severity = none # Use 'is' operator instead of 'as' operator — covered by SST2005 -dotnet_diagnostic.RCS1187.severity = error # Use constant instead of field +dotnet_diagnostic.RCS1187.severity = none # Use constant instead of field — covered by PSH1402 dotnet_diagnostic.RCS1191.severity = error # Declare enum value as combination of names -dotnet_diagnostic.RCS1193.severity = error # Overriding member should not change 'params' modifier +dotnet_diagnostic.RCS1193.severity = none # Overriding member should not change 'params' modifier — covered by SST2426 dotnet_diagnostic.RCS1196.severity = error # Call extension method as instance method -dotnet_diagnostic.RCS1200.severity = error # Call 'Enumerable.ThenBy' instead of 'Enumerable.OrderBy' +dotnet_diagnostic.RCS1200.severity = none # Call 'Enumerable.ThenBy' instead of 'Enumerable.OrderBy' — covered by PSH1108 dotnet_diagnostic.RCS1201.severity = error # Use method chaining dotnet_diagnostic.RCS1202.severity = error # Avoid NullReferenceException dotnet_diagnostic.RCS1204.severity = error # Use EventArgs.Empty dotnet_diagnostic.RCS1205.severity = error # Order named arguments according to the order of parameters dotnet_diagnostic.RCS1208.severity = error # Reduce 'if' nesting dotnet_diagnostic.RCS1209.severity = error # Order type parameter constraints -dotnet_diagnostic.RCS1210.severity = error # Return completed task instead of returning null +dotnet_diagnostic.RCS1210.severity = none # Return completed task instead of returning null — covered by PSH1312 dotnet_diagnostic.RCS1215.severity = error # Expression is always equal to true/false dotnet_diagnostic.RCS1222.severity = error # Merge preprocessor directives dotnet_diagnostic.RCS1223.severity = suggestion # Mark publicly visible type with DebuggerDisplay attribute — only data types benefit; the rule is too broad to be an error dotnet_diagnostic.RCS1224.severity = error # Make method an extension method dotnet_diagnostic.RCS1225.severity = error # Make class sealed -dotnet_diagnostic.RCS1227.severity = error # Validate arguments correctly +dotnet_diagnostic.RCS1227.severity = none # Validate arguments correctly — covered by SST2404 dotnet_diagnostic.RCS1229.severity = error # Use async/await when necessary -dotnet_diagnostic.RCS1231.severity = suggestion # Make parameter ref read-only -dotnet_diagnostic.RCS1233.severity = error # Use short-circuiting operator +dotnet_diagnostic.RCS1231.severity = none # Make parameter ref read-only — covered by PSH1007 +dotnet_diagnostic.RCS1233.severity = none # Use short-circuiting operator — covered by SST1468 dotnet_diagnostic.RCS1234.severity = error # Duplicate enum value dotnet_diagnostic.RCS1239.severity = error # Use 'for' statement instead of 'while' statement dotnet_diagnostic.RCS1240.severity = error # Operator is unnecessary -dotnet_diagnostic.RCS1242.severity = error # Do not pass non-read-only struct by read-only reference -dotnet_diagnostic.RCS1243.severity = error # Duplicate word in a comment +dotnet_diagnostic.RCS1242.severity = none # Do not pass non-read-only struct by read-only reference — covered by PSH1003 +dotnet_diagnostic.RCS1243.severity = none # Duplicate word in a comment — covered by SST1658 (documentation comments) dotnet_diagnostic.RCS1247.severity = error # Fix documentation comment tag -dotnet_diagnostic.RCS1248.severity = none # Normalize null check - covered by SST2282 -dotnet_diagnostic.RCS1250.severity = error # Use implicit/explicit object creation +dotnet_diagnostic.RCS1248.severity = none # Normalize null check — conflicts with SST1149, which owns the 'is null' pattern direction +dotnet_diagnostic.RCS1250.severity = none # Use implicit/explicit object creation — conflicts with SST2202, which owns the implicit-target-type direction dotnet_diagnostic.RCS1252.severity = error # Normalize usage of infinite loop dotnet_diagnostic.RCS1254.severity = error # Normalize format of enum flag value dotnet_diagnostic.RCS1255.severity = none # Simplify argument null check — conflicts with our ArgumentExceptionHelper helper pattern dotnet_diagnostic.RCS1257.severity = error # Use enum field explicitly dotnet_diagnostic.RCS1258.severity = error # Unnecessary enum flag -dotnet_diagnostic.RCS1260.severity = error # Add/remove trailing comma -dotnet_diagnostic.RCS1261.severity = error # Resource can be disposed asynchronously +dotnet_diagnostic.RCS1260.severity = none # Add/remove trailing comma — conflicts with SST1413, which owns the trailing-comma direction +dotnet_diagnostic.RCS1261.severity = none # Resource can be disposed asynchronously — covered by PSH1310 dotnet_diagnostic.RCS1264.severity = error # Use 'var' or explicit type (replaces RCS1010, RCS1176, RCS1177) -dotnet_diagnostic.RCS1266.severity = error # Use raw string literal +dotnet_diagnostic.RCS1266.severity = none # Use raw string literal — covered by SST2243 dotnet_diagnostic.RCS1267.severity = error # Use string interpolation instead of 'string.Concat' -################### -# Roslynator Analyzers (RCS1xxx) - Performance -################### -dotnet_diagnostic.RCS1077.severity = error # Optimize LINQ method call -dotnet_diagnostic.RCS1080.severity = error # Use 'Count/Length' property instead of 'Any' method -dotnet_diagnostic.RCS1112.severity = error # Combine 'Enumerable.Where' method chain +# Performance +dotnet_diagnostic.RCS1077.severity = none # Covered by the PSH1101-PSH1111 family (canonical) +dotnet_diagnostic.RCS1080.severity = none # Covered by PSH1106 (canonical) +dotnet_diagnostic.RCS1112.severity = none # Combine 'Enumerable.Where' method chain — covered by PSH1109 dotnet_diagnostic.RCS1186.severity = error # Use Regex instance instead of static method -dotnet_diagnostic.RCS1190.severity = error # Join string expressions +dotnet_diagnostic.RCS1190.severity = none # Join string expressions — conflicts with SST2470, which reports the fused-literal seam this would create dotnet_diagnostic.RCS1195.severity = error # Use ^ operator -dotnet_diagnostic.RCS1197.severity = error # Optimize StringBuilder.Append/AppendLine call +dotnet_diagnostic.RCS1197.severity = none # Optimize StringBuilder.Append/AppendLine call — covered by PSH1203/PSH1214 dotnet_diagnostic.RCS1198.severity = none # Avoid unnecessary boxing of value type — boxing is unavoidable bridging Rx and IEnumerable -dotnet_diagnostic.RCS1230.severity = error # Unnecessary explicit use of enumerator +dotnet_diagnostic.RCS1230.severity = none # Unnecessary explicit use of enumerator — covered by SST1467 dotnet_diagnostic.RCS1235.severity = error # Optimize method call -dotnet_diagnostic.RCS1236.severity = error # Use exception filter -dotnet_diagnostic.RCS1246.severity = error # Use element access +dotnet_diagnostic.RCS1236.severity = none # Use exception filter — covered by SST2009 +dotnet_diagnostic.RCS1246.severity = none # Use element access — covered by PSH1106 -################### -# Roslynator Analyzers (RCS1xxx) - Maintainability -################### +# Maintainability dotnet_diagnostic.RCS1158.severity = none # Static member in generic type should use a type parameter — common factory pattern — covered by SST1431 dotnet_diagnostic.RCS1163.severity = none # Unused parameter — interface implementations and Rx selectors often have unused parameters dotnet_diagnostic.RCS1164.severity = none # Unused type parameter - DUPLICATE IDE0060 (UnusedParameter analyzer 210ms; IDE0060 bundled at lower cost) @@ -972,9 +1013,7 @@ dotnet_diagnostic.RCS1213.severity = none # Remove unused member declaration - D dotnet_diagnostic.RCS1241.severity = error # Implement non-generic counterpart dotnet_diagnostic.RCS1256.severity = none # Invalid argument null check — conflicts with our ArgumentExceptionHelper helper pattern -################### -# Roslynator Analyzers (RCS1xxx) - Documentation -################### +# Documentation dotnet_diagnostic.RCS1181.severity = error # Convert comment to documentation comment dotnet_diagnostic.RCS1189.severity = error # Add or remove region name dotnet_diagnostic.RCS1226.severity = none # Add paragraph to documentation comment — <para> wrapping is subjective and adds noise @@ -983,9 +1022,7 @@ dotnet_diagnostic.RCS1232.severity = error # Order elements in documentation com dotnet_diagnostic.RCS1253.severity = error # Format documentation comment summary dotnet_diagnostic.RCS1263.severity = none # Invalid reference in a documentation comment -################### -# Roslynator Analyzers (RCS1xxx) - Disabled (covered by CA/SA equivalent) -################### +# Disabled dotnet_diagnostic.RCS1018.severity = none # Add/remove accessibility modifiers — covered by SA1400 dotnet_diagnostic.RCS1019.severity = none # Order modifiers — covered by SA1206 / SA1208 dotnet_diagnostic.RCS1037.severity = none # Remove trailing white-space — covered by SA1028 @@ -1003,9 +1040,7 @@ dotnet_diagnostic.RCS1175.severity = none # Unused 'this' parameter — covered dotnet_diagnostic.RCS1194.severity = none # Implement exception constructors — covered by CA1032 dotnet_diagnostic.RCS1203.severity = none # Use AttributeUsageAttribute — covered by CA1018 -################### -# Roslynator Formatting Analyzers (RCS0xxx) - covered by StyleCop SA equivalents -################### +# Formatting dotnet_diagnostic.RCS0001.severity = none # Add blank line after embedded statement — covered by StyleCop layout rules dotnet_diagnostic.RCS0002.severity = none # Add blank line after #region — covered by StyleCop SA1517 family dotnet_diagnostic.RCS0003.severity = none # Add blank line after using directive list — covered by SA1516 @@ -1063,6 +1098,11 @@ dotnet_diagnostic.RCS0063.severity = none # Remove unnecessary blank line — co file_header_template = Copyright (c) 2009-2026 .NET Foundation and Contributors. All rights reserved.\nLicensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.\nSee the LICENSE file in the project root for full license information. stylesharp.summary_single_line_max_length = 120 +# SonarAnalyzer's S4022 only ever flagged storage narrower than int; uint, long and ulong +# passed silently. Match that, so retiring S4022 for SST2313 does not fail a build on an +# enum that was deliberately widened. +stylesharp.SST2313.allowed_enum_storage = int, uint, long, ulong + # Documentation coverage scope (SST1600/SST1601/SST1602/SST1654). # Require documentation on every element, including private members. stylesharp.document_exposed_elements = true @@ -1072,13 +1112,18 @@ stylesharp.document_private_fields = true stylesharp.document_interfaces = all stylesharp.SST1305.allowed_hungarian_prefixes = rx stylesharp.instance_member_qualification = omit_this -stylesharp.avoid_linq_on_hot_path = true stylesharp.max_cyclomatic_complexity = 10 stylesharp.max_cognitive_complexity = 15 -stylesharp.max_line_length = 200 # SST1521 (characters; the 200-column limit this repo has always enforced) -stylesharp.max_file_lines = 1000 # SST1522 (code lines per file; raised from the default 500 to accommodate the high-arity variadic scaffolding) stylesharp.max_property_cognitive_complexity = 3 - +# SST1484 also reports a field that shadows one inherited from a base type. +stylesharp.SST1484.check_base_types = true +stylesharp.max_line_length = 200 # SST1521 (characters; keeps the limit this repo has always enforced) +stylesharp.max_file_lines = 1000 # SST1522 (code lines; blank lines and comments do not count) +# stylesharp.max_member_lines = 60 # SST1523 (code lines) +# stylesharp.max_switch_section_lines = 20 # SST1524 (code lines) +# stylesharp.include_internal = true # SST1499 (set false to report only fields visible outside the assembly) +# stylesharp.require_parameterless = true # SST1488 (set false where every exception must carry a message) +# stylesharp.include_non_public_types = true # SST1488 (set false to check only externally visible exceptions) # Spacing dotnet_diagnostic.SST1000.severity = error # A control-flow keyword is not followed by a space dotnet_diagnostic.SST1001.severity = error # A comma is spaced incorrectly @@ -1112,7 +1157,7 @@ dotnet_diagnostic.SST1028.severity = error # A line ends with trailing whitespac # Readability and maintainability dotnet_diagnostic.SST1100.severity = error # A base. prefix is used where the type does not override the member -dotnet_diagnostic.SST1101.severity = none # An instance member is accessed without a this. prefix — we don't require this. prefixing +dotnet_diagnostic.SST1101.severity = none # see docs/rules/SST1101.md dotnet_diagnostic.SST1102.severity = error # A query clause is separated from the previous clause by a blank line dotnet_diagnostic.SST1103.severity = error # Query clauses mix single-line and multi-line layout dotnet_diagnostic.SST1104.severity = error # A query clause shares the last line of a multi-line previous clause @@ -1128,8 +1173,9 @@ dotnet_diagnostic.SST1115.severity = error # A blank line separates a parameter dotnet_diagnostic.SST1116.severity = error # A qualified name can be shortened without changing the symbol it binds to dotnet_diagnostic.SST1117.severity = error # Instance member access follows the configured this. qualification style dotnet_diagnostic.SST1118.severity = none # A parameter should not span multiple lines +dotnet_diagnostic.SST1119.severity = error # A numeric literal groups its digit separators irregularly dotnet_diagnostic.SST1120.severity = error # A comment contains no text -dotnet_diagnostic.SST1121.severity = none # A framework type name is used instead of its built-in alias — duplicate of RCS1013 +dotnet_diagnostic.SST1121.severity = error # A framework type name is used instead of its built-in alias (opt-in rule, enabled here) dotnet_diagnostic.SST1122.severity = error # An empty string literal is used instead of string.Empty dotnet_diagnostic.SST1123.severity = error # A #region is placed inside a code element body dotnet_diagnostic.SST1124.severity = error # A #region directive is used @@ -1145,6 +1191,7 @@ dotnet_diagnostic.SST1134.severity = error # An attribute shares a line with ano dotnet_diagnostic.SST1135.severity = error # A using directive names a namespace or type that is not fully qualified dotnet_diagnostic.SST1136.severity = error # Several enum members share a line dotnet_diagnostic.SST1137.severity = error # Sibling elements are indented differently from one another +dotnet_diagnostic.SST1138.severity = error # A free-standing block declares nothing dotnet_diagnostic.SST1139.severity = error # A numeric literal is cast where a literal suffix would express the type dotnet_diagnostic.SST1140.severity = error # Wrapped conditional operators should start indented continuation lines dotnet_diagnostic.SST1141.severity = error # An explicit ValueTuple<...> is used where tuple syntax would do @@ -1198,7 +1245,7 @@ dotnet_diagnostic.SST1188.severity = error # Use the 'default' literal instead o dotnet_diagnostic.SST1189.severity = error # Variables should not be self-assigned dotnet_diagnostic.SST1190.severity = error # Doubled negation operators should be removed dotnet_diagnostic.SST1191.severity = error # Long numeric literals should use digit separators -dotnet_diagnostic.SST1192.severity = none # Control characters in string literals should be escaped +dotnet_diagnostic.SST1192.severity = none # Control characters in string literals should be escaped dotnet_diagnostic.SST1193.severity = error # Keep initial member values with construction dotnet_diagnostic.SST1194.severity = error # Keep initial collection values with construction dotnet_diagnostic.SST1195.severity = error # Write null fallback with ?? @@ -1208,7 +1255,7 @@ dotnet_diagnostic.SST1198.severity = error # Collapse assignment-only branches i dotnet_diagnostic.SST1199.severity = error # Prefer compile-time type names # Ordering -dotnet_diagnostic.SST1200.severity = none # Using directives should be placed outside the namespace — usings live outside file-scoped namespaces +dotnet_diagnostic.SST1200.severity = error # Using directives should be placed outside the namespace dotnet_diagnostic.SST1201.severity = error # Members should be ordered by kind dotnet_diagnostic.SST1202.severity = error # Members should be ordered by accessibility dotnet_diagnostic.SST1203.severity = error # Constants should appear before fields @@ -1226,6 +1273,10 @@ dotnet_diagnostic.SST1214.severity = error # Static readonly fields should appea dotnet_diagnostic.SST1215.severity = error # Instance readonly fields should appear before instance non-readonly fields dotnet_diagnostic.SST1216.severity = error # Using static directives should be placed after regular usings and before aliases dotnet_diagnostic.SST1217.severity = error # Using static directives should be ordered alphabetically +dotnet_diagnostic.SST1218.severity = error # Other members separate a method's overloads +dotnet_diagnostic.SST1219.severity = error # A switch default clause is not placed last +dotnet_diagnostic.SST1220.severity = error # An all-named argument list is in a different order than the parameters. Code fix reorders it to declaration order. Info. +dotnet_diagnostic.SST1221.severity = error # `where` constraint clauses are not ordered to match the type-parameter list. Code fix reorders them. Info. # Naming dotnet_diagnostic.SST1300.severity = none # Types and members should be PascalCase — naming duplicates existing analyzers @@ -1246,6 +1297,9 @@ dotnet_diagnostic.SST1315.severity = error # Union member names should match the dotnet_diagnostic.SST1316.severity = none # Tuple element names should use the configured casing — tuple naming is not enforced here dotnet_diagnostic.SST1317.severity = none # Asynchronous method names should end with 'Async' — conflicts with this project's Rx-compatibility and naming mechanism dotnet_diagnostic.SST1318.severity = error # Overriding parameter names should match the base declaration +dotnet_diagnostic.SST1319.severity = error # An enumeration's type name is not PascalCase +dotnet_diagnostic.SST1320.severity = error # A parameter name matches its method's name +dotnet_diagnostic.SST1321.severity = none # Public APIs intentionally use Async to describe asynchronous observable behavior without returning an awaitable. # Maintainability dotnet_diagnostic.SST1400.severity = error # An element does not declare an access modifier @@ -1281,7 +1335,7 @@ dotnet_diagnostic.SST1430.severity = error # Rethrow with 'throw;' to preserve t dotnet_diagnostic.SST1431.severity = error # Static members of a generic type should use a type parameter dotnet_diagnostic.SST1432.severity = error # Classes with only static members should be static dotnet_diagnostic.SST1433.severity = error # Redundant constructors should be removed -dotnet_diagnostic.SST1434.severity = error # Empty finalizers should be removed +dotnet_diagnostic.SST1434.severity = error # see docs/rules/SST1434.md dotnet_diagnostic.SST1435.severity = error # Empty namespace declarations should be removed dotnet_diagnostic.SST1436.severity = error # Empty types should not be declared dotnet_diagnostic.SST1437.severity = error # Empty interfaces should not be declared @@ -1292,7 +1346,61 @@ dotnet_diagnostic.SST1441.severity = error # Private fields assigned but never r dotnet_diagnostic.SST1442.severity = error # A function has too many direct branch points dotnet_diagnostic.SST1443.severity = error # A function has too much nested control flow dotnet_diagnostic.SST1444.severity = error # A loop cannot naturally reach a second iteration +dotnet_diagnostic.SST1445.severity = error # A using directive is unnecessary +dotnet_diagnostic.SST1446.severity = error # An inheritance chain is deeper than the configured maximum +dotnet_diagnostic.SST1447.severity = error # An equality override delegates to object reference semantics +dotnet_diagnostic.SST1448.severity = error # An argument is passed explicitly to a caller-info parameter +dotnet_diagnostic.SST1449.severity = error # Code writes directly to the console dotnet_diagnostic.SST1450.severity = error # Store files as UTF-8 without a byte order mark +dotnet_diagnostic.SST1451.severity = error # A DateTime is created without a DateTimeKind +dotnet_diagnostic.SST1452.severity = error # A generic type parameter is never used +dotnet_diagnostic.SST1453.severity = error # Statements after an unconditional exit should be removed +dotnet_diagnostic.SST1454.severity = error # Composite format placeholders should match the supplied arguments +dotnet_diagnostic.SST1455.severity = error # Unsafe modifiers should be used only when unsafe syntax is present +dotnet_diagnostic.SST1456.severity = error # Readonly fields should not store mutable source-defined structs +dotnet_diagnostic.SST1457.severity = error # Global suppressions should point at real declarations +dotnet_diagnostic.SST1458.severity = error # Global suppression targets should use declaration ids directly +dotnet_diagnostic.SST1459.severity = error # Grouping parentheses should be removed when the parent syntax already isolates the expression +dotnet_diagnostic.SST1460.severity = error # Non-mutating struct members should be readonly +dotnet_diagnostic.SST1461.severity = error # Private parameters that are never read should be removed +dotnet_diagnostic.SST1462.severity = error # Suppressions for diagnostics already disabled by config should be removed +dotnet_diagnostic.SST1463.severity = error # Symbol-name strings should use nameof +dotnet_diagnostic.SST1464.severity = error # An else clause follows a branch that always jumps and can be unwrapped +dotnet_diagnostic.SST1465.severity = error # An else block that only wraps an if can collapse to else-if +dotnet_diagnostic.SST1466.severity = error # A case label sharing a section with default is redundant +dotnet_diagnostic.SST1467.severity = error # A hand-driven enumerator loop can use foreach +dotnet_diagnostic.SST1468.severity = error # Boolean logic should use the short-circuiting && and || operators +dotnet_diagnostic.SST1469.severity = error # A non-nullable value type is compared to null +dotnet_diagnostic.SST1470.severity = error # A trailing catch clause that only rethrows should be removed +dotnet_diagnostic.SST1471.severity = error # Magic numbers should be named constants +dotnet_diagnostic.SST1472.severity = error # Signatures should not declare too many parameters +dotnet_diagnostic.SST1473.severity = error # A floating-point value is compared for exact equality (zero comparison allowed by default) +dotnet_diagnostic.SST1474.severity = error # Both sides of an operator are the same expression +dotnet_diagnostic.SST1475.severity = error # A condition repeats an earlier one in the chain, so its branch cannot run +dotnet_diagnostic.SST1476.severity = error # Every branch of a conditional has the same body +dotnet_diagnostic.SST1477.severity = error # An integer division is widened to floating point after it has already truncated +dotnet_diagnostic.SST1478.severity = error # A shift count is zero, negative, or at least the operand's width +dotnet_diagnostic.SST1479.severity = error # A count or length is compared against a value it can never take +dotnet_diagnostic.SST1480.severity = error # An exception is constructed and then discarded +dotnet_diagnostic.SST1481.severity = error # A bitwise operation has a constant operand that makes it pointless +dotnet_diagnostic.SST1482.severity = error # GetHashCode reads mutable state +dotnet_diagnostic.SST1483.severity = error # A constructor calls an overridable member +dotnet_diagnostic.SST1484.severity = error # A declaration shadows an outer field or property (inherited fields included) +dotnet_diagnostic.SST1485.severity = error # A member that must not throw throws +dotnet_diagnostic.SST1486.severity = error # The same string literal is repeated instead of being named +dotnet_diagnostic.SST1487.severity = error # A collection element is assigned twice with nothing reading it in between +dotnet_diagnostic.SST1488.severity = error # An exception type does not declare the standard constructors (parameterless waivable) +dotnet_diagnostic.SST1489.severity = error # An exception type carries serialization members the target framework has obsoleted +dotnet_diagnostic.SST1490.severity = error # A base list names an interface the rest of the list already implies +dotnet_diagnostic.SST1491.severity = error # A modifier restates the declaration's default +dotnet_diagnostic.SST1492.severity = error # A value is tested against what it is then assigned, so the guard decides nothing +dotnet_diagnostic.SST1493.severity = error # A method's whole body is a constant +dotnet_diagnostic.SST1494.severity = error # A trailing argument repeats the parameter's default +dotnet_diagnostic.SST1495.severity = error # '==' compares references on a type that overrides Equals, so the two disagree +dotnet_diagnostic.SST1496.severity = error # An abstract type declares nothing abstract +dotnet_diagnostic.SST1497.severity = error # A local is declared and never read +dotnet_diagnostic.SST1498.severity = error # Only a nested type uses a private member +dotnet_diagnostic.SST1499.severity = error # A static field visible outside its type can still be changed (internal fields included by default) # Layout dotnet_diagnostic.SST1500.severity = error # A brace in a multi-line construct shares its line with other code @@ -1316,6 +1424,19 @@ dotnet_diagnostic.SST1517.severity = error # The file begins with one or more bl dotnet_diagnostic.SST1518.severity = error # The file does not end with exactly one newline dotnet_diagnostic.SST1519.severity = error # A multi-line child statement of a control-flow keyword omits its braces dotnet_diagnostic.SST1520.severity = error # The clauses of an if/else chain use braces inconsistently +dotnet_diagnostic.SST1521.severity = error # A line is longer than the configured maximum (default 120 characters) +dotnet_diagnostic.SST1522.severity = error # A file has more code lines than the configured maximum (default 500) +dotnet_diagnostic.SST1523.severity = error # A member has more code lines than the configured maximum (default 60) +dotnet_diagnostic.SST1524.severity = error # A switch section has more code lines than the configured maximum (default 20) +dotnet_diagnostic.SST1525.severity = error # A multi-statement `switch` section has no braces; the braces-on policy extends to switch sections. Code fix wraps it. +dotnet_diagnostic.SST1526.severity = error # A wrapped binary expression places the operator inconsistently. Configurable (`before`/`after`, default before). Opt-in. +dotnet_diagnostic.SST1527.severity = error # The `=>` of an expression-bodied member wraps inconsistently. Configurable. Opt-in. +dotnet_diagnostic.SST1528.severity = error # The `=` of a wrapped initializer wraps inconsistently. Configurable. Opt-in. +dotnet_diagnostic.SST1529.severity = error # A wrapped `?.`/`.` call chain places the break inconsistently. Configurable. Opt-in. +dotnet_diagnostic.SST1530.severity = error # A newline sits between a type declaration and its base list. Code fix pulls the base list onto the declaration line. Opt-in. +dotnet_diagnostic.SST1531.severity = error # A short object initializer is split across lines. Code fix collapses it when it fits. Opt-in. +dotnet_diagnostic.SST1532.severity = error # A file mixes line endings. Configurable (`lf`/`crlf`, default lf). Opt-in. +dotnet_diagnostic.SST1533.severity = error # A source file contains no code. Opt-in. # Documentation dotnet_diagnostic.SST1600.severity = error # Externally visible members should be documented @@ -1326,7 +1447,7 @@ dotnet_diagnostic.SST1605.severity = error # Partial element documentation shoul dotnet_diagnostic.SST1606.severity = error # The summary should have text dotnet_diagnostic.SST1607.severity = error # Partial element summary should have text dotnet_diagnostic.SST1608.severity = error # Documentation should not use the default placeholder summary -dotnet_diagnostic.SST1609.severity = none # Property documentation should have a value +dotnet_diagnostic.SST1609.severity = none # Property documentation should have a value dotnet_diagnostic.SST1610.severity = error # Property value documentation should have text dotnet_diagnostic.SST1611.severity = error # Parameters should be documented dotnet_diagnostic.SST1612.severity = error # Parameter documentation should match the parameters @@ -1363,12 +1484,21 @@ dotnet_diagnostic.SST1654.severity = error # Extension blocks should be document dotnet_diagnostic.SST1655.severity = error # Extension block parameters should be documented dotnet_diagnostic.SST1656.severity = error # Extension block type parameters should be documented dotnet_diagnostic.SST1657.severity = error # Extension block documentation should reference a real parameter or type parameter +dotnet_diagnostic.SST1658.severity = error # Documentation text repeats a word +dotnet_diagnostic.SST1659.severity = error # A comment has no text at all +dotnet_diagnostic.SST1660.severity = error # The `` tags are not in parameter order. Code fix reorders them. Info. +dotnet_diagnostic.SST1661.severity = error # A snippet uses ``/`` mismatched to single- vs multi-line content. Code fix swaps the tag. Info. +dotnet_diagnostic.SST1662.severity = none # A thrown exception type has no `` documentation. Code fix adds the skeleton. Opt-in. +dotnet_diagnostic.SST1663.severity = none # A `//` comment before a public member reads like a summary; use `///`. Code fix converts it. Opt-in. +dotnet_diagnostic.SST1664.severity = none # A summary separates paragraphs with blank lines instead of ``. Code fix wraps them. Opt-in. # Concurrency and modernization -dotnet_diagnostic.SST1900.severity = error # A dedicated object lock field should be a System.Threading.Lock +dotnet_diagnostic.SST1900.severity = error # see docs/rules/SST1900.md dotnet_diagnostic.SST1901.severity = error # A lock targets a field or property reachable from outside the declaring type dotnet_diagnostic.SST1902.severity = error # Do not lock on 'this', a Type, or a string dotnet_diagnostic.SST1903.severity = error # Do not lock on a newly-created object +dotnet_diagnostic.SST1904.severity = error # A lock targets a non-readonly field +dotnet_diagnostic.SST1905.severity = error # An async method or converted delegate returns void dotnet_diagnostic.SST2000.severity = suggestion # A null check plus throw should use ArgumentNullException.ThrowIfNull dotnet_diagnostic.SST2001.severity = error # Use ArgumentException.ThrowIfNullOrEmpty dotnet_diagnostic.SST2002.severity = error # Use ArgumentException.ThrowIfNullOrWhiteSpace @@ -1377,6 +1507,17 @@ dotnet_diagnostic.SST2004.severity = suggestion # A range check should use an Ar dotnet_diagnostic.SST2005.severity = error # Use the 'is' type pattern instead of comparing an 'as' cast to null dotnet_diagnostic.SST2006.severity = error # Use the 'is not' pattern instead of negating an 'is' check dotnet_diagnostic.SST2007.severity = error # Use declaration patterns instead of an is check followed by a cast local +dotnet_diagnostic.SST2008.severity = error # Negated pattern tests should use is-not patterns +dotnet_diagnostic.SST2009.severity = error # A catch that tests then rethrows can use a when filter +dotnet_diagnostic.SST2010.severity = error # A type reads the machine clock directly instead of through a TimeProvider +dotnet_diagnostic.SST2011.severity = error # An instant is recorded from the local clock rather than in UTC +dotnet_diagnostic.SST2012.severity = error # A GUID is constructed with the parameterless constructor instead of Guid.Empty +dotnet_diagnostic.SST2013.severity = error # An if whose entire body is another if should be merged +dotnet_diagnostic.SST2014.severity = error # A goto jumps to a label +dotnet_diagnostic.SST2015.severity = error # A ++ or -- is buried inside a larger expression +dotnet_diagnostic.SST2016.severity = error # A DateTime on a visible signature loses its offset at the boundary +dotnet_diagnostic.SST2017.severity = error # A .Date or .TimeOfDay read proves the value is only a date, or only a time of day +dotnet_diagnostic.SST2018.severity = error # A redundant null check sits beside an is type pattern # Modern language and library usage dotnet_diagnostic.SST1700.severity = error # An extension block declares no members @@ -1387,10 +1528,13 @@ dotnet_diagnostic.SST1704.severity = error # A class declaring extension blocks dotnet_diagnostic.SST1705.severity = error # A class mixes classic extension methods with extension blocks dotnet_diagnostic.SST1706.severity = error # An extension block targets a broad receiver type such as object or dynamic dotnet_diagnostic.SST1707.severity = error # Extension blocks should be ordered by receiver type +dotnet_diagnostic.SST1708.severity = error # An extension method never uses its `this` receiver, so it need not be an extension. +dotnet_diagnostic.SST1709.severity = none # A method in a `*Extensions` class whose first parameter lacks `this`. Code fix converts it to an extension block. Opt-in. dotnet_diagnostic.SST1800.severity = error # Record classes should be sealed dotnet_diagnostic.SST1801.severity = error # A positional record parameter does not match the configured casing dotnet_diagnostic.SST1802.severity = error # A record declares a settable rather than init-only instance property dotnet_diagnostic.SST1803.severity = error # A record struct is not declared readonly +dotnet_diagnostic.SST1804.severity = error # A positional record has an empty `{ }` body where `;` would do. Code fix rewrites it. Info. dotnet_diagnostic.SST2100.severity = error # An empty collection creation can use [] dotnet_diagnostic.SST2101.severity = error # An explicit collection creation can use [...] dotnet_diagnostic.SST2102.severity = error # A span-targeted stackalloc initializer can use a collection expression @@ -1406,7 +1550,7 @@ dotnet_diagnostic.SST2205.severity = none # An enum switch statement omits named dotnet_diagnostic.SST2206.severity = error # An enum switch expression omits named enum values dotnet_diagnostic.SST2207.severity = error # A null guard and return can keep the throw in the returned expression dotnet_diagnostic.SST2208.severity = error # An out variable can be declared at the call site -dotnet_diagnostic.SST2209.severity = none # A null-forgiving operator has no local effect +dotnet_diagnostic.SST2209.severity = none # A null-forgiving operator has no local effect dotnet_diagnostic.SST2210.severity = error # A nullable directive repeats the current file-local state dotnet_diagnostic.SST2211.severity = error # A nullable restore directive has no file-local state to restore dotnet_diagnostic.SST2212.severity = error # Literal UTF-8 byte data can use a u8 string literal @@ -1426,23 +1570,455 @@ dotnet_diagnostic.SST2225.severity = error # A foreach loop hides an explicit el dotnet_diagnostic.SST2226.severity = error # A cast hides an inner explicit conversion dotnet_diagnostic.SST2227.severity = error # A post-assignment null fallback can be folded into the assigned expression dotnet_diagnostic.SST2228.severity = error # A delegate local used only as a call target can be a local function -dotnet_diagnostic.SST2229.severity = none # LINQ terminal predicate simplification is reserved for test code; production code should avoid LINQ on hot paths -dotnet_diagnostic.SST2230.severity = none # LINQ type-filter simplification is reserved for test code; production code should avoid LINQ on hot paths +dotnet_diagnostic.SST2229.severity = error # see docs/rules/SST2229.md +dotnet_diagnostic.SST2230.severity = error # see docs/rules/SST2230.md dotnet_diagnostic.SST2231.severity = error # A broad object pattern can use a direct null pattern dotnet_diagnostic.SST2232.severity = error # nameof does not need concrete generic type arguments -dotnet_diagnostic.SST2233.severity = error # Hot-path code should avoid System.Linq.Enumerable calls -dotnet_diagnostic.RCS1040.severity = none # covered by SST1180 +dotnet_diagnostic.SST2233.severity = none # see docs/rules/SST2233.md +dotnet_diagnostic.SST2234.severity = error # Nullable should use the T? shorthand +dotnet_diagnostic.SST2235.severity = error # Capture-free local functions should be static +dotnet_diagnostic.SST2236.severity = error # Tail-position using blocks can use using declarations +dotnet_diagnostic.SST2237.severity = error # Single block-scoped namespaces can use file-scoped syntax +dotnet_diagnostic.SST2238.severity = error # Nested property patterns can use extended property syntax +dotnet_diagnostic.SST2239.severity = error # Forwarding lambdas can use method groups +dotnet_diagnostic.SST2240.severity = error # Delegate null checks can use conditional invocation +dotnet_diagnostic.SST2241.severity = error # Constructors that only store parameters can use primary-constructor storage +dotnet_diagnostic.SST2242.severity = error # Enum switch statement mappings should name every enum value or include a catch-all +dotnet_diagnostic.SST2243.severity = error # A verbatim string with escapes or line breaks can use a raw string literal +dotnet_diagnostic.SST2244.severity = error # A numeric literal's suffix is lower case +dotnet_diagnostic.SST2245.severity = error # A for loop with only a condition should be a while loop +dotnet_diagnostic.SST2246.severity = error # A chain of conditional expressions testing one value against constants can be a switch expression +dotnet_diagnostic.SST2247.severity = error # Consecutive locals copying one value's members in order can be a deconstruction +dotnet_diagnostic.SST2248.severity = error # Two constant comparisons of the same value can fold into one is-pattern +dotnet_diagnostic.SST2249.severity = error # A literal-format string.Format or literal concatenation can be an interpolated string +dotnet_diagnostic.SST2250.severity = error # A bare local assigned once by the next statement can be an initialized declaration +dotnet_diagnostic.SST2251.severity = error # A method call names type arguments that inference would supply +dotnet_diagnostic.SST2252.severity = error # A switch statement is nested inside another switch statement +dotnet_diagnostic.SST2254.severity = none # A target-typed `new()` is written where an explicit type reads more clearly; the code fix restores `new TypeName(...)`. Opt-in — the counterpart to SST2202's target-typed direction, so a team enables at most one. +dotnet_diagnostic.SST2255.severity = error # A hand-written null-or-empty string test. Code fix uses `string.IsNullOrEmpty`. +dotnet_diagnostic.SST2256.severity = error # An extension method called in static form. Code fix rewrites to instance form. Info. +dotnet_diagnostic.SST2257.severity = error # A lambda block body that is a single `return`. Code fix uses an expression body. Info. +dotnet_diagnostic.SST2258.severity = error # A redundant explicit delegate wrapper (`new EventHandler(M)`). Code fix drops it. Info. +dotnet_diagnostic.SST2259.severity = error # A stray `;` after a type declaration. Code fix removes it. Info. +dotnet_diagnostic.SST2260.severity = error # An `as` cast to a type the operand already has. Code fix removes it. Info. +dotnet_diagnostic.SST2261.severity = error # `(x && !y) +dotnet_diagnostic.SST2262.severity = error # A raw string literal whose content needs no raw syntax. Code fix demotes it. Info. +dotnet_diagnostic.SST2263.severity = error # An infinite loop whose body re-derives its stop condition. Code fix hoists the condition into the header. Info. +dotnet_diagnostic.SST2264.severity = error # A numeric literal cast to an enum. Code fix names the member. +dotnet_diagnostic.SST2265.severity = none # Consecutive fluent calls on one receiver can fold into a chain. Opt-in. +dotnet_diagnostic.SST2266.severity = none # A local read exactly once can be inlined into that use. Opt-in. +dotnet_diagnostic.SST2267.severity = none # Infinite loops written in mixed `while(true)`/`for(;;)` styles. Configurable. Opt-in. +dotnet_diagnostic.SST2268.severity = none # Inconsistent `()` on object creation with an initializer. Configurable. Opt-in. +dotnet_diagnostic.SST2269.severity = none # Inconsistent parentheses around a conditional's condition. Configurable. Opt-in. +dotnet_diagnostic.SST2270.severity = none # Inconsistent explicit-vs-implicit array-creation type. Configurable. Opt-in. +dotnet_diagnostic.SST2271.severity = none # `var`-vs-explicit local type per the configured preference. Configurable. Opt-in. +dotnet_diagnostic.SST2272.severity = none # `[Flags]` member values written as mixed decimals and shifts. Configurable. Opt-in. +dotnet_diagnostic.SST2273.severity = none # A function or loop body wraps its work in a trailing `if` that could be an early-exit guard clause. Code fix inverts it. Configurable threshold. Opt-in. +dotnet_diagnostic.SST2274.severity = error # A value assigned with `as` and then null-checked is an `is` declaration pattern in one step. Code fix rewrites it. +dotnet_diagnostic.SST2275.severity = error # A method whose block body is a single statement can use an expression body `=> expr`. Code fix rewrites it. +dotnet_diagnostic.SST2276.severity = none # A constructor whose block body is a single statement can use an expression body. Code fix rewrites it. Opt-in. +dotnet_diagnostic.SST2277.severity = none # An operator whose block body is a single `return` can use an expression body. Code fix rewrites it. Opt-in. +dotnet_diagnostic.SST2278.severity = none # A conversion operator whose block body is a single `return` can use an expression body. Code fix rewrites it. Opt-in. +dotnet_diagnostic.SST2279.severity = error # A get-only property whose getter is a single `return` can use a whole-member expression body. Code fix rewrites it. +dotnet_diagnostic.SST2280.severity = error # A get-only indexer whose getter is a single `return` can use a whole-member expression body. Code fix rewrites it. +dotnet_diagnostic.SST2281.severity = error # A local function whose block body is a single statement can use an expression body. Code fix rewrites it. +dotnet_diagnostic.SST2282.severity = error # A reference-type `ReferenceEquals` check against `null` reads as an `is null` / `is not null` pattern. Code fix rewrites it. +dotnet_diagnostic.SST2283.severity = error # A null guard that throws right before assigning the guarded value can fold into the assignment as `?? throw`. Code fix rewrites it. +# Design +dotnet_diagnostic.SST2300.severity = error # A class implements IDisposable but builds only half of the disposal pattern +dotnet_diagnostic.SST2301.severity = error # A class implementing IEquatable for itself can still be derived from +dotnet_diagnostic.SST2302.severity = error # A type overloads an operator without the rest of the set it belongs to +dotnet_diagnostic.SST2303.severity = error # A [Flags] enum's members are not distinct bit values +dotnet_diagnostic.SST2304.severity = error # An event's delegate does not have the standard (object sender, TEventArgs e) shape +dotnet_diagnostic.SST2305.severity = error # A mutable collection property declares a caller-visible setter +dotnet_diagnostic.SST2306.severity = error # A collection-returning member hands back null +dotnet_diagnostic.SST2307.severity = error # A generic method's type parameter appears in no parameter, so no caller can infer it +dotnet_diagnostic.SST2308.severity = error # An [Obsolete] attribute carries no message +dotnet_diagnostic.SST2309.severity = error # An externally visible member declares an optional parameter, so callers bake in the default +dotnet_diagnostic.SST2310.severity = error # Deprecated code is still here; remove it once its last caller is gone +dotnet_diagnostic.SST2311.severity = error # A visible const is copied into every assembly that reads it +dotnet_diagnostic.SST2312.severity = error # A type is declared outside any namespace +dotnet_diagnostic.SST2313.severity = error # An enum is stored as a type the project does not allow +dotnet_diagnostic.SST2314.severity = none # An [Obsolete] has a message but no DiagnosticId — unusable here: ObsoleteAttribute.DiagnosticId is .NET 5+, and this source is shared with net462 +dotnet_diagnostic.SST2315.severity = error # A type owns a disposable field but does not implement IDisposable +dotnet_diagnostic.SST2316.severity = error # A type declares Dispose or DisposeAsync without implementing IDisposable +dotnet_diagnostic.SST2317.severity = error # A disposable type owns a raw IntPtr without a SafeHandle or finalizer +dotnet_diagnostic.SST2318.severity = error # Two members have token-identical bodies +dotnet_diagnostic.SST2319.severity = error # An overload's optional default can never be used +dotnet_diagnostic.SST2320.severity = error # An interface inherits two interfaces that declare the same member +dotnet_diagnostic.SST2321.severity = error # Environment.Exit or Environment.FailFast is called from library code +dotnet_diagnostic.SST2322.severity = error # A non-private readonly field holds a mutable collection callers can still change +dotnet_diagnostic.SST2323.severity = error # A stateless abstract class declaring only public abstract members should be an interface +dotnet_diagnostic.SST2324.severity = error # A member is declared more accessible than its containing type +dotnet_diagnostic.SST2325.severity = error # An async method checks an argument after its first await +dotnet_diagnostic.SST2326.severity = none # An interface-typed value is narrowed to a concrete implementation — this is a high-performance core library, not strictly SOLID code, and narrowing to a known runtime type is a normal fast-path technique here: foreach over IEnumerable boxes List's struct enumerator (40 bytes per call, measured) where the indexed loop behind the type test allocates nothing +dotnet_diagnostic.SST2327.severity = error # A type tests its own runtime type against a class instead of dispatching through a virtual member +dotnet_diagnostic.SST2328.severity = error # A raw native pointer handle is exposed instead of a SafeHandle +dotnet_diagnostic.SST2329.severity = error # A `[Flags]` enum declares no zero-valued member. Code fix adds `None = 0`. +dotnet_diagnostic.SST2330.severity = error # A `[Flags]` member is a numeric literal equal to a combination of others (`All = 7`). Code fix writes `A +dotnet_diagnostic.SST2331.severity = none # An enum leaves member values implicit, so their numbers depend on declaration order. Opt-in. +dotnet_diagnostic.SST2332.severity = error # An auto-property's `private set` is only written during construction; make it get-only. +dotnet_diagnostic.SST2333.severity = none # A generic comparison/equality contract is implemented without its non-generic counterpart. Opt-in. +dotnet_diagnostic.SST2334.severity = none # A publicly visible type has no `[DebuggerDisplay]`. Opt-in. +dotnet_diagnostic.SST2335.severity = none # Parts of a partial type disagree on the `static` modifier. Opt-in. + +# Correctness +dotnet_diagnostic.SST2400.severity = error # Two arguments name each other's parameters and have been transposed +dotnet_diagnostic.SST2401.severity = error # A catch targets NullReferenceException +dotnet_diagnostic.SST2402.severity = error # An instance constructor assigns a static field of its own type +dotnet_diagnostic.SST2403.severity = error # 'this' escapes from a constructor before the object is fully built +dotnet_diagnostic.SST2404.severity = error # An iterator's argument guard does not run until the first MoveNext +dotnet_diagnostic.SST2405.severity = error # A [DebuggerDisplay] string names a member the type does not have +dotnet_diagnostic.SST2406.severity = error # A loop's stop condition reads only variables the loop never writes +dotnet_diagnostic.SST2407.severity = error # A declared event is never raised +dotnet_diagnostic.SST2408.severity = error # A StringBuilder is filled and never read +dotnet_diagnostic.SST2409.severity = error # A throw constructs a general exception type (Exception/SystemException/ApplicationException) +dotnet_diagnostic.SST2410.severity = error # A created disposable is never disposed and never leaves the method +dotnet_diagnostic.SST2411.severity = error # A for loop declares and tests a counter it never steps +dotnet_diagnostic.SST2412.severity = error # A for loop update moves the counter away from its stop condition +dotnet_diagnostic.SST2413.severity = error # A for loop condition can never be true on the first pass +dotnet_diagnostic.SST2414.severity = error # Two branches of a conditional share the same implementation +dotnet_diagnostic.SST2415.severity = error # A non-short-circuiting & or | evaluates a right operand that does work +dotnet_diagnostic.SST2416.severity = error # A modulus result on a signed type is compared directly to 1 +dotnet_diagnostic.SST2417.severity = error # A compound assignment operator is transposed (=+, =-, =!) +dotnet_diagnostic.SST2418.severity = error # The result of an immutable value's method is discarded +dotnet_diagnostic.SST2419.severity = error # A set or collection operation is performed against itself +dotnet_diagnostic.SST2420.severity = error # An IndexOf result is tested with > 0, skipping index 0 +dotnet_diagnostic.SST2421.severity = error # A write targets a readonly field of an unconstrained type parameter +dotnet_diagnostic.SST2422.severity = error # A property getter returns a different field than its setter writes +dotnet_diagnostic.SST2423.severity = error # A disposable created in a using statement is returned +dotnet_diagnostic.SST2424.severity = error # An override changes a parameter's default value +dotnet_diagnostic.SST2425.severity = error # An override drops an optional argument on its base call +dotnet_diagnostic.SST2426.severity = error # An override adds or removes params on a parameter +dotnet_diagnostic.SST2427.severity = error # A derived overload widens a parameter and hides the base overload +dotnet_diagnostic.SST2428.severity = error # A static initializer reads a static field declared later +dotnet_diagnostic.SST2429.severity = error # A setter, init, add, or remove accessor never reads value +dotnet_diagnostic.SST2430.severity = error # A serialization callback has the wrong signature +dotnet_diagnostic.SST2431.severity = error # A ToString override can return null +dotnet_diagnostic.SST2432.severity = error # GetType is called on a value that is already a System.Type +dotnet_diagnostic.SST2433.severity = error # A caller-info parameter is not last in the list +dotnet_diagnostic.SST2434.severity = error # An array is assigned through a covariant element type +dotnet_diagnostic.SST2435.severity = error # A non-object base's value-equality Equals is used as a reference-equality fast path +dotnet_diagnostic.SST2436.severity = error # An event is raised with a null sender or null args +dotnet_diagnostic.SST2437.severity = error # A generic type inherits from itself recursively +dotnet_diagnostic.SST2438.severity = error # A catch that discards its exception logs at Error or Critical without it +dotnet_diagnostic.SST2439.severity = error # An exception is passed as a log template argument instead of the exception parameter +dotnet_diagnostic.SST2440.severity = error # Log template arguments are transposed +dotnet_diagnostic.SST2441.severity = error # A log template has an empty or non-identifier placeholder +dotnet_diagnostic.SST2442.severity = error # A log template repeats a named placeholder +dotnet_diagnostic.SST2443.severity = error # An ILogger is injected or created with the wrong category type +dotnet_diagnostic.SST2444.severity = error # A regular expression pattern is invalid +dotnet_diagnostic.SST2445.severity = error # A culture-sensitive custom date or time format is used without an invariant culture +dotnet_diagnostic.SST2446.severity = error # A Stream.ReadAsync result is discarded through ConfigureAwait or a local +dotnet_diagnostic.SST2448.severity = error # A combined or opaque delegate is removed with - or -=, which strips only a contiguous run +dotnet_diagnostic.SST2449.severity = error # A lambda or anonymous-method handler is removed with -=, which never matches it +dotnet_diagnostic.SST2450.severity = error # A Debug.Assert condition performs a side effect that a release build compiles out +dotnet_diagnostic.SST2451.severity = error # Every constructor is private and no member ever creates an instance +dotnet_diagnostic.SST2452.severity = error # A [Pure] method returns void, Task, or ValueTask, so it has no observable result +dotnet_diagnostic.SST2456.severity = error # An override or new field-like event gets its own backing delegate field +dotnet_diagnostic.SST2457.severity = error # An integer Sum wrapped in unchecked still throws on overflow +dotnet_diagnostic.SST2458.severity = error # A bitwise operator is applied to an enum not declared [Flags] +dotnet_diagnostic.SST2459.severity = error # [Optional] on a ref or out parameter advertises an optionality no caller can use +dotnet_diagnostic.SST2460.severity = error # [DefaultValue] on a method or record parameter is inert +dotnet_diagnostic.SST2462.severity = error # A new member is less accessible than the inherited member it hides +dotnet_diagnostic.SST2463.severity = error # A field differs from an inherited accessible field only by case +dotnet_diagnostic.SST2464.severity = error # A mutable class declares a value-equality operator ==, so it is lost as a hash key +dotnet_diagnostic.SST2465.severity = error # A for loop body reassigns the counter or the local its condition tests +dotnet_diagnostic.SST2467.severity = error # A params overload is shadowed by a same-arity overload with a more specific last parameter +dotnet_diagnostic.SST2468.severity = error # A classic partial method is declared but never implemented, so its calls are removed +dotnet_diagnostic.SST2470.severity = error # Two string literals concatenate with no space, fusing a SQL keyword into the next token +dotnet_diagnostic.SST2472.severity = error # A type is exported for a contract it neither implements nor inherits +dotnet_diagnostic.SST2473.severity = error # A shared export part is constructed with new, bypassing the container +dotnet_diagnostic.SST2474.severity = error # A part-creation-policy attribute is applied to a type with no [Export] +dotnet_diagnostic.SST2475.severity = error # An entity's primary key is typed DateTime or DateTimeOffset +dotnet_diagnostic.SST2479.severity = error # A loop variable captured by a callback stored beyond the iteration reads its final value +dotnet_diagnostic.SST2481.severity = error # A GetHashCode override folds the base identity hash into a value hash +dotnet_diagnostic.SST2484.severity = error # A handle read through DangerousGetHandle is not reference-counted +dotnet_diagnostic.SST2485.severity = error # A NotImplementedException is left in shipped code +dotnet_diagnostic.SST2486.severity = error # An assembly is loaded by path or partial name instead of Assembly.Load +dotnet_diagnostic.SST2487.severity = error # A [ConstructorArgument] does not name a constructor parameter +dotnet_diagnostic.SST2488.severity = error # An exception is logged and rethrown, duplicating the record +dotnet_diagnostic.SST2489.severity = error # A relational comparison is decided by the operand's type rather than its value +dotnet_diagnostic.SST2490.severity = error # Adjacent try statements with identical handling should be merged +dotnet_diagnostic.SST2491.severity = error # A non-`async` method returns an awaitable from inside `using`/`try-finally`/`lock`, so the resource is torn down before the task completes. Code fix makes it `async`. +dotnet_diagnostic.SST2492.severity = error # A null-guard throws on a parameter the signature declares may be null. +dotnet_diagnostic.SST2493.severity = error # `== null`/`!= null` on an unconstrained generic `T`. Code fix uses `is null`/`is not null`. +dotnet_diagnostic.SST2494.severity = error # A `??` whose left operand is a constant null, so the right is always taken. Code fix folds it. +dotnet_diagnostic.SST2495.severity = error # A `[Flags]` combination includes an operand whose bits another already covers. Code fix removes it. +dotnet_diagnostic.SST2496.severity = error # An explicit `Dispose`/`Close` on a resource an enclosing `using` already disposes. Code fix removes it. Info. + +# Testing +dotnet_diagnostic.SST2500.severity = error # A test method contains no assertion and no expected-exception check +dotnet_diagnostic.SST2501.severity = error # An equality or identity assertion compares an expression with itself +dotnet_diagnostic.SST2502.severity = error # An equality assertion passes the constant as actual and the computed value as expected +dotnet_diagnostic.SST2503.severity = error # An equality assertion compares a value against a boolean literal +dotnet_diagnostic.SST2504.severity = error # A test fixture declares and inherits no test method +dotnet_diagnostic.SST2505.severity = error # A test method declares parameters but no data source +dotnet_diagnostic.SST2506.severity = error # A test method calls Thread.Sleep +dotnet_diagnostic.SST2507.severity = error # A test method declares its expected failure with an expected-exception attribute +dotnet_diagnostic.SST2508.severity = error # A fluent assertion is started but never completed +dotnet_diagnostic.SST2509.severity = error # A test method has a shape the runner cannot execute + +# Logging +dotnet_diagnostic.SST2600.severity = error # Application output is written through legacy Trace instead of a structured logger +dotnet_diagnostic.SST2601.severity = error # A logger field or property does not follow the logger naming convention + +# Frameworks +dotnet_diagnostic.SST2700.severity = error # An MVC route template contains a backslash; route segments are separated by `/`, so the route is unreachable. Code fix replaces `\` with `/`. +dotnet_diagnostic.SST2701.severity = error # A `[JSInvokable]` method is not public, so JavaScript interop cannot call it. Code fix makes it public. +dotnet_diagnostic.SST2702.severity = error # A `[SupplyParameterFromQuery]` property has a type the framework cannot bind from the query string, which throws at runtime. +dotnet_diagnostic.SST2703.severity = error # A routable component's route constraint (`{id:int}`) disagrees with the matching `[Parameter]` CLR type, so the route silently fails to match. +dotnet_diagnostic.SST2704.severity = error # A public action on an `[ApiController]` declares no HTTP-verb attribute, so it answers every verb and can make routing ambiguous. +dotnet_diagnostic.SST2705.severity = none # A bound model member is a non-nullable value type with no required marker, so a request that omits it binds the default with no error. Opt-in. +dotnet_diagnostic.SST2706.severity = error # A Windows Forms entry point carries neither `[STAThread]` nor `[MTAThread]`; without STA, clipboard, drag-and-drop, and common dialogs misbehave. Code fix adds `[STAThread]`. +dotnet_diagnostic.SST2707.severity = none # A fire-and-forget `Task.Run` in a controller captures the request's `HttpContext`, which is disposed when the request ends, so the background work throws `ObjectDisposedException`. Opt-in. +dotnet_diagnostic.SST2708.severity = error # A component subscribes to an event in a lifecycle method but never unsubscribes, so the event source keeps the component alive — a per-session leak on a Server circuit. +dotnet_diagnostic.SST2709.severity = error # `StateHasChanged` is called while the component is being disposed, which the renderer no longer supports and throws. +dotnet_diagnostic.SST2710.severity = error # `StateHasChanged` is called directly from a timer callback, off the renderer's dispatcher; marshal it with `InvokeAsync(StateHasChanged)`. +dotnet_diagnostic.SST2711.severity = error # A synchronous component lifecycle method is overridden as `async void`, which the framework never awaits; override the `…Async` twin returning `Task`. Code fix rewrites the signature. +dotnet_diagnostic.SST2712.severity = error # An `[Inject]`/`[CascadingParameter]` property has no setter, so the framework's reflection-based binding leaves it null. Code fix adds a setter. +dotnet_diagnostic.SST2713.severity = error # A `DotNetObjectReference.Create(this)` is passed inline and never stored, so nothing can dispose it and it leaks on the JavaScript side. ################### -# PublicApiAnalyzers (RSxxxx) - public API surface tracking +# PerformanceSharp Analyzers (PSH) +################### +performancesharp.avoid_linq_on_hot_path = true +# performancesharp.empty_string_style = pattern # PSH1204 (pattern | length | is_null_or_empty; the last two are only offered where the string is provably not null) +# performancesharp.excluded_properties = Items, Keys # PSH1017 (comma-separated; properties allowed to copy on read) +# performancesharp.include_public = false # PSH1411 (set true in an app to seal public types too; a break in a library) +dotnet_diagnostic.PSH1000.severity = error # Anonymous functions without captures should be static +dotnet_diagnostic.PSH1001.severity = error # Avoid allocating zero-length arrays (fix prefers [] on C# 12+, else Array.Empty()) +dotnet_diagnostic.PSH1002.severity = error # Empty finalizers should be removed +dotnet_diagnostic.PSH1003.severity = error # 'in' parameters should use readonly structs +dotnet_diagnostic.PSH1004.severity = error # Constant arrays passed as arguments should be hoisted +dotnet_diagnostic.PSH1005.severity = error # Structs should define equality members to avoid boxing comparisons +dotnet_diagnostic.PSH1006.severity = error # ConcurrentDictionary factories should use the lambda argument +dotnet_diagnostic.PSH1007.severity = error # Pass large readonly structs by 'in' reference (size threshold + exclusions configurable) +dotnet_diagnostic.PSH1008.severity = error # GC.SuppressFinalize does nothing for sealed finalizer-free types +dotnet_diagnostic.PSH1009.severity = error # Bound variable-length stackalloc with a constant guard +dotnet_diagnostic.PSH1010.severity = error # Clear reference-typed arrays when returning them to the pool +dotnet_diagnostic.PSH1011.severity = error # Pass state to callbacks through the state-taking overload +dotnet_diagnostic.PSH1012.severity = error # Compare type parameter values with EqualityComparer.Default +dotnet_diagnostic.PSH1013.severity = error # Expose constant UTF-8 data as a ReadOnlySpan property +dotnet_diagnostic.PSH1014.severity = error # Declare immutable structs as readonly +dotnet_diagnostic.PSH1015.severity = error # Avoid casting value types through object +dotnet_diagnostic.PSH1016.severity = error # Test enum flags with bitwise operators instead of Enum.HasFlag +dotnet_diagnostic.PSH1017.severity = error # A property allocates a copy of a collection on every read (excludable via performancesharp.PSH1017.excluded_properties) +dotnet_diagnostic.PSH1018.severity = error # A hand-written array is passed to a params parameter +dotnet_diagnostic.PSH1019.severity = error # The range indexer on an array allocates a copy; slice with AsSpan/AsMemory +dotnet_diagnostic.PSH1020.severity = error # Prefer a jagged array over a multidimensional one +dotnet_diagnostic.PSH1021.severity = error # An explicit GC.Collect or GC.WaitForPendingFinalizers forces collection the runtime tunes itself +dotnet_diagnostic.PSH1022.severity = error # A parameterless `new EventArgs()` allocates where the shared `EventArgs.Empty` singleton would serve. Code fix uses the singleton. +dotnet_diagnostic.PSH1100.severity = error # Hot-path code should avoid System.Linq.Enumerable calls +dotnet_diagnostic.PSH1101.severity = none # LINQ terminal predicate simplification is reserved for test code; production code should avoid LINQ on hot paths +dotnet_diagnostic.PSH1102.severity = none # LINQ type-filter simplification is reserved for test code; production code should avoid LINQ on hot paths +dotnet_diagnostic.PSH1103.severity = error # Prefer the collection's own count over enumerating +dotnet_diagnostic.PSH1104.severity = error # Use TryGetValue instead of ContainsKey followed by an indexer read +dotnet_diagnostic.PSH1105.severity = error # Avoid double lookups on dictionaries and sets +dotnet_diagnostic.PSH1106.severity = error # Index collections directly instead of using LINQ element access +dotnet_diagnostic.PSH1107.severity = error # Filter sequences before sorting them +dotnet_diagnostic.PSH1108.severity = error # Chain secondary sorts with ThenBy +dotnet_diagnostic.PSH1109.severity = error # Merge consecutive Where calls +dotnet_diagnostic.PSH1110.severity = error # Use the collection's own predicate methods over LINQ +dotnet_diagnostic.PSH1111.severity = error # Use Contains for membership tests +dotnet_diagnostic.PSH1112.severity = error # Seed the collection through its constructor (fix honors performancesharp.prefer_collection_expressions) +dotnet_diagnostic.PSH1113.severity = error # Sort naturally instead of ordering by the element itself +dotnet_diagnostic.PSH1114.severity = none # Freeze static lookup collections that are never mutated. Opt-in. +dotnet_diagnostic.PSH1115.severity = error # Insert-if-absent should probe the dictionary once +dotnet_diagnostic.PSH1116.severity = error # Probe string-keyed collections with a span through GetAlternateLookup +dotnet_diagnostic.PSH1117.severity = error # Ask the collection whether it is empty +dotnet_diagnostic.PSH1118.severity = error # Take the extreme element with Min/Max/MinBy/MaxBy instead of sorting +dotnet_diagnostic.PSH1119.severity = error # Check for elements with Any instead of counting them all +dotnet_diagnostic.PSH1120.severity = error # Do not materialize a sequence with ToList/ToArray just to enumerate it +dotnet_diagnostic.PSH1122.severity = error # Read a sorted set's extreme through its Min/Max property, not the LINQ extension +dotnet_diagnostic.PSH1124.severity = error # Read a linked list's end through its First/Last property, not the LINQ extension +dotnet_diagnostic.PSH1125.severity = error # Do not enumerate the same lazy sequence twice +dotnet_diagnostic.PSH1126.severity = error # Ask whether an async sequence has elements instead of counting them +dotnet_diagnostic.PSH1127.severity = error # Clear an array instead of filling it with its default +dotnet_diagnostic.PSH1200.severity = error # Compare strings without allocating case-converted copies +dotnet_diagnostic.PSH1201.severity = error # Use the char overload for single-character strings +dotnet_diagnostic.PSH1202.severity = error # Append characters as char, not single-character strings +dotnet_diagnostic.PSH1203.severity = error # Let StringBuilder do the formatting work +dotnet_diagnostic.PSH1204.severity = error # Test for empty strings by length +dotnet_diagnostic.PSH1205.severity = error # Remove interpolation that does no work +dotnet_diagnostic.PSH1206.severity = error # Do not build strings by concatenation in loops +dotnet_diagnostic.PSH1207.severity = error # Specify StringComparison for culture-sensitive string operations +dotnet_diagnostic.PSH1208.severity = error # Encode constant strings with u8 literals +dotnet_diagnostic.PSH1209.severity = error # Build transformed strings with string.Create +dotnet_diagnostic.PSH1210.severity = error # Compare UTF-8 bytes without decoding them +dotnet_diagnostic.PSH1211.severity = error # Pass values directly instead of ToString results +dotnet_diagnostic.PSH1212.severity = error # Slice with AsSpan when the call accepts a span +dotnet_diagnostic.PSH1213.severity = error # Probe repeated character sets through SearchValues +dotnet_diagnostic.PSH1214.severity = error # Append the parts of a concatenation separately, not the concatenated whole +dotnet_diagnostic.PSH1215.severity = error # Use string.Concat instead of string.Join with an empty separator +dotnet_diagnostic.PSH1216.severity = error # Use string.Equals instead of comparing string.Compare to zero +dotnet_diagnostic.PSH1217.severity = error # A sequence is copied to an array just to be read straight back +dotnet_diagnostic.PSH1218.severity = error # A substring is allocated only to search it; slice with AsSpan instead +dotnet_diagnostic.PSH1219.severity = error # Ask whether a string is blank without trimming it +dotnet_diagnostic.PSH1220.severity = error # A length argument spells out the run that reaches the end anyway +dotnet_diagnostic.PSH1221.severity = error # An IndexOf compared to 0 scans the whole string to answer a prefix test +dotnet_diagnostic.PSH1222.severity = error # Concatenate slices without materializing them +dotnet_diagnostic.PSH1223.severity = error # A reused composite format string is re-parsed on every call +dotnet_diagnostic.PSH1224.severity = error # Convert bytes to hex in one call, not by building the string twice +dotnet_diagnostic.PSH1225.severity = error # Decode bytes to a string in one call, without a throwaway char[] +dotnet_diagnostic.PSH1226.severity = error # A string's `ToCharArray()` result is only iterated, allocating a throwaway `char[]`; iterate the string directly. Code fix drops the copy. +dotnet_diagnostic.PSH1227.severity = error # A cheaper equivalent exists — `string.CompareOrdinal` over `Compare(…, Ordinal)`, `Debug.Fail` over `Debug.Assert(false, …)`. Info. Code fix rewrites the call. +dotnet_diagnostic.PSH1300.severity = error # Use System.Threading.Lock for a dedicated lock object +dotnet_diagnostic.PSH1301.severity = error # Do not wrap a single task in WhenAll or WaitAll +dotnet_diagnostic.PSH1302.severity = error # TaskCompletionSource should run continuations asynchronously +dotnet_diagnostic.PSH1303.severity = error # Do not block an async method with Thread.Sleep +dotnet_diagnostic.PSH1304.severity = error # Use PeriodicTimer instead of pacing a loop with Task.Delay +dotnet_diagnostic.PSH1305.severity = error # Enumerate a ConcurrentDictionary directly, not its Keys/Values snapshots +dotnet_diagnostic.PSH1306.severity = none # Guard one-time execution with an interlocked latch. Opt-in. +dotnet_diagnostic.PSH1307.severity = error # Access interlocked fields with Volatile +dotnet_diagnostic.PSH1308.severity = error # Return the completed task instead of Task.FromResult +dotnet_diagnostic.PSH1309.severity = none # Register cancellation callbacks without flowing the execution context. Opt-in. +dotnet_diagnostic.PSH1310.severity = error # Dispose IAsyncDisposable resources with await using in async code +dotnet_diagnostic.PSH1311.severity = error # Remove a pass-through async state machine and return the task directly +dotnet_diagnostic.PSH1312.severity = error # Return a completed task instead of null +dotnet_diagnostic.PSH1313.severity = error # A synchronous call where an async overload fits +dotnet_diagnostic.PSH1314.severity = error # Read and write streams through the memory-based overloads +dotnet_diagnostic.PSH1315.severity = error # A blocking wait on an awaitable that may not be done +dotnet_diagnostic.PSH1316.severity = error # A ValueTask is awaited in a loop or awaited after being copied +dotnet_diagnostic.PSH1400.severity = error # Use the static HashData method for one-shot hashing +dotnet_diagnostic.PSH1401.severity = error # Attribute types should be sealed +dotnet_diagnostic.PSH1402.severity = error # Use const for compile-time constants +dotnet_diagnostic.PSH1403.severity = error # Do not initialize fields to their default value +dotnet_diagnostic.PSH1404.severity = error # Get the assembly from typeof instead of a stack walk +dotnet_diagnostic.PSH1405.severity = error # Use the direct Environment APIs +dotnet_diagnostic.PSH1406.severity = error # Ask Regex for the answer directly +dotnet_diagnostic.PSH1407.severity = error # Query the dictionary, not its Keys view +dotnet_diagnostic.PSH1408.severity = error # Measure elapsed time with Stopwatch timestamps +dotnet_diagnostic.PSH1409.severity = error # Use the built-in throw helpers for argument guards +dotnet_diagnostic.PSH1410.severity = none # Mark trivial forwarders for aggressive inlining. Opt-in. +dotnet_diagnostic.PSH1411.severity = error # Seal non-public types nothing derives from so the JIT can devirtualize +dotnet_diagnostic.PSH1412.severity = error # Use Random.Shared instead of allocating a Random +dotnet_diagnostic.PSH1413.severity = error # Read the Unix epoch from the framework, not a hand-built DateTime +dotnet_diagnostic.PSH1414.severity = error # Mark members that do not touch instance state as static +dotnet_diagnostic.PSH1415.severity = error # Hold the concrete type when the concrete type is what you have +dotnet_diagnostic.PSH1416.severity = error # Cache the serializer options instead of building them per call +dotnet_diagnostic.PSH1417.severity = error # Do not compute an expensive argument for an assertion +dotnet_diagnostic.PSH1418.severity = error # An HttpClient is constructed on every call +dotnet_diagnostic.PSH1419.severity = error # A time-zone is resolved with a platform-specific id instead of the cross-platform API +dotnet_diagnostic.PSH1420.severity = error # A shareable client held in an instance field of an Azure Functions worker class is rebuilt on every invocation, leaking sockets and connections; share a static/singleton client or inject `IHttpClientFactory`. + +# ASP.NET Core - inert in this repo (no route handlers or middleware), enabled so the set stays complete +dotnet_diagnostic.PSH1500.severity = error # A minimal API handler returns Results instead of TypedResults, boxing the result +dotnet_diagnostic.PSH1501.severity = error # Middleware uses the legacy nested-delegate Use overload, allocating a per-request closure +dotnet_diagnostic.PSH1502.severity = error # A route handler returns a deferred sequence the serializer enumerates on the request thread +dotnet_diagnostic.PSH1503.severity = error # Response caching is used where server-side output caching applies +dotnet_diagnostic.PSH1505.severity = error # Exceptions are handled in an MVC exception filter instead of an IExceptionHandler +dotnet_diagnostic.PSH1506.severity = error # The HTTP request or response body is read or written synchronously (`ReadToEnd`, `Body.Read`, `Body.Write`), which blocks a thread on Kestrel and buffers the whole payload; use the async overload. Code fix awaits it when the method is already async. + +# Blazor +dotnet_diagnostic.PSH1600.severity = error # A delegate captured per iteration inside a component render loop reallocates on every render (measured ~128 B per row per render) and churns the diff; hoist it to a cached delegate or a precomputed per-item model. +dotnet_diagnostic.PSH1601.severity = error # A JavaScript-interop call is issued once per loop iteration; on Interactive Server each is a separate SignalR round-trip. Batch into a single call over the collection. +dotnet_diagnostic.PSH1602.severity = error # `StateHasChanged` is called unconditionally in `OnAfterRender`/`OnAfterRenderAsync`, scheduling another render every time — a runaway loop. Guard it with `firstRender` or a state flag. +dotnet_diagnostic.PSH1603.severity = error # A non-delegate allocation is used as a component-parameter value inside a render loop, allocating per item and forcing the child to re-render each pass. Sibling of PSH1600. + ################### +# SecuritySharp Analyzers (SES) +################### +# Every rule is raised to error, including the three that ship at suggestion (SES1403, SES1506, +# SES1605). Security rules only ever suggest an API they can resolve in the compilation and report +# local shapes only - there is no interprocedural taint tracking, so the taint-flow CA rules stay on. +# securitysharp.SES1003.iterations = 100000 # minimum accepted PBKDF2 iteration count +# securitysharp.SES1403.maxdepth = 64 # highest accepted System.Text.Json MaxDepth + +# Cryptography +dotnet_diagnostic.SES1001.severity = error # AEAD encryption must not use a constant or reused nonce +dotnet_diagnostic.SES1002.severity = error # Password-based key derivation must not use a constant or predictable salt +dotnet_diagnostic.SES1003.severity = error # Password-based key derivation must use a sufficient iteration count +dotnet_diagnostic.SES1004.severity = error # A secret must not be produced from Guid.NewGuid() +dotnet_diagnostic.SES1005.severity = error # Compare secret values in constant time +dotnet_diagnostic.SES1006.severity = error # A Data Protection key ring is persisted without a ProtectKeysWith call, so keys sit unencrypted at rest +dotnet_diagnostic.SES1007.severity = error # A cryptographic primitive is implemented by hand instead of using a vetted platform algorithm +dotnet_diagnostic.SES1008.severity = error # An XML signature is verified with the no-key CheckSignature overload, trusting the document's own KeyInfo +dotnet_diagnostic.SES1009.severity = error # A password is stored without a slow, salted key-derivation function + +# Transport +dotnet_diagnostic.SES1102.severity = error # Do not accept any server certificate +dotnet_diagnostic.SES1104.severity = error # Certificate-chain validation must not be deliberately weakened +dotnet_diagnostic.SES1105.severity = error # Bearer and OpenID Connect metadata must not be retrieved over plain HTTP outside development +dotnet_diagnostic.SES1106.severity = error # Do not send HttpClient requests to a cleartext http URL +dotnet_diagnostic.SES1107.severity = error # A SQL connection string weakens transport security via TrustServerCertificate or a disabled Encrypt +dotnet_diagnostic.SES1108.severity = error # A custom server-certificate validation callback unconditionally returns true, so any certificate is trusted + +# Secrets +dotnet_diagnostic.SES1201.severity = error # Do not hard-code secrets in source +dotnet_diagnostic.SES1202.severity = error # Do not hard-code a credential value +dotnet_diagnostic.SES1203.severity = error # A connection string names a user but supplies an empty or missing password + +# Injection +dotnet_diagnostic.SES1301.severity = error # Do not build a process command line from non-constant string parts +dotnet_diagnostic.SES1302.severity = error # A shell-executed process must not use a non-constant FileName +dotnet_diagnostic.SES1303.severity = error # Regular-expression pattern must not be built from non-constant data +dotnet_diagnostic.SES1304.severity = error # An archive entry name must not build a write path without a containment check +dotnet_diagnostic.SES1305.severity = error # Do not build a storage path from an uploaded file name +dotnet_diagnostic.SES1306.severity = error # Do not compile or execute non-constant C# via the scripting API +dotnet_diagnostic.SES1307.severity = error # Path.GetTempFileName creates a predictable, world-readable temporary file +dotnet_diagnostic.SES1308.severity = error # A file or directory is created group- or world-writable +dotnet_diagnostic.SES1309.severity = error # An XSLT stylesheet is loaded with embedded script enabled +dotnet_diagnostic.SES1310.severity = error # A directory bind is performed without authenticating + +# Serialization +dotnet_diagnostic.SES1401.severity = error # A type resolved from non-constant data must not be instantiated or deserialized +dotnet_diagnostic.SES1402.severity = error # Do not load an assembly from raw bytes or a non-constant location +dotnet_diagnostic.SES1403.severity = error # JSON deserialization depth limit must stay within a safe ceiling +dotnet_diagnostic.SES1404.severity = error # A type is instantiated by name from a non-constant Activator typeName +dotnet_diagnostic.SES1405.severity = error # MessagePack typeless deserialization reconstructs whatever type the payload names +dotnet_diagnostic.SES1406.severity = warning # Reflection must not reach non-public members via BindingFlags.NonPublic (opt-in; replaces S3011) + +# Web hardening +dotnet_diagnostic.SES1501.severity = error # A CORS policy must not allow credentials together with any origin +dotnet_diagnostic.SES1502.severity = error # A CORS origin predicate must not unconditionally allow every origin +dotnet_diagnostic.SES1503.severity = error # JWT signature verification must not be disabled on TokenValidationParameters +dotnet_diagnostic.SES1504.severity = error # A cookie with SameSite=None must be marked Secure +dotnet_diagnostic.SES1505.severity = error # The request body size limit must not be removed +dotnet_diagnostic.SES1506.severity = error # The developer exception page must be guarded by a development-environment check +dotnet_diagnostic.SES1507.severity = error # AllowAnonymous and Authorize on the same declaration conflict +dotnet_diagnostic.SES1508.severity = error # A validation method must not fail open by returning success from a catch +dotnet_diagnostic.SES1509.severity = error # A backtracking-prone constant regex runs without a match timeout or NonBacktracking +dotnet_diagnostic.SES1510.severity = error # A controller redirects to a non-constant URL, allowing an open redirect +dotnet_diagnostic.SES1511.severity = error # The forwarded-headers trust boundary is cleared, letting proxies spoof the client IP +dotnet_diagnostic.SES1512.severity = error # Sensitive framework diagnostics are enabled without a development-environment guard +dotnet_diagnostic.SES1513.severity = error # An AuthorizeAsync result is discarded, so the guarded operation runs regardless +dotnet_diagnostic.SES1514.severity = error # OpenID Connect protections (PKCE, state, nonce) are disabled +dotnet_diagnostic.SES1515.severity = error # A Content-Security-Policy value disables its own protection + +# AI trust boundaries +dotnet_diagnostic.SES1601.severity = error # An LLM system prompt must be a constant, trusted template +dotnet_diagnostic.SES1602.severity = error # Do not route AI model output into a process, file, or raw SQL sink +dotnet_diagnostic.SES1603.severity = error # An AI tool declared read-only or non-destructive must not call a state-changing API +dotnet_diagnostic.SES1604.severity = error # Prompt-template input encoding must not be disabled +dotnet_diagnostic.SES1605.severity = error # AI instrumentation must not enable sensitive-data capture +dotnet_diagnostic.SES1606.severity = error # Do not fetch model weights over cleartext HTTP + +# Web UI trust boundaries +dotnet_diagnostic.SES1701.severity = error # Raw HTML is rendered from a non-constant value (`MarkupString`/`AddMarkupContent`), bypassing automatic encoding — an XSS risk. Sanitizer allow-list via `securitysharp.SES1701.sanitizers`. +dotnet_diagnostic.SES1702.severity = error # A JavaScript-interop call targets a script-evaluation primitive (`eval`, `Function`, `document.write`), turning interop into a script-injection channel. +dotnet_diagnostic.SES1703.severity = error # `[Authorize]` on a non-routable component enforces nothing — authorization runs as a routing concern. Exempt types via `securitysharp.SES1703.exempt_types`. +dotnet_diagnostic.SES1704.severity = error # `IHttpContextAccessor` or a cascading `HttpContext` is used in an interactively-rendered component, where it is null or frozen at circuit start. +dotnet_diagnostic.SES1705.severity = error # `NavigationManager.NavigateTo` is called with a target that is not a verified relative URL — an open-redirect risk. Validator allow-list via `securitysharp.SES1705.validators`. +dotnet_diagnostic.SES1706.severity = error # An uploaded file is read with an unbounded or client-chosen size limit, letting an attacker fill server memory. Threshold via `securitysharp.SES1706.max_bytes`. +dotnet_diagnostic.SES1707.severity = error # A secret-shaped literal appears in code reachable as WebAssembly, which downloads to the browser in full — guaranteed disclosure. +dotnet_diagnostic.SES1708.severity = error # `CircuitOptions.DetailedErrors` is enabled, shipping server exception detail to every connected client. +dotnet_diagnostic.SES1709.severity = error # `SerializeAllClaims` serializes every claim into client-readable WebAssembly authentication state, exposing internal ids, tokens, and PII. +dotnet_diagnostic.SES1710.severity = error # Antiforgery validation is disabled on a form (`[RequireAntiforgeryToken(required: false)]`), removing CSRF protection. + + +################### +# Microsoft.CodeAnalysis.PublicApiAnalyzers (RS) +################### +# Public API surface tracking dotnet_diagnostic.RS0016.severity = error # public symbol missing from the PublicAPI baseline dotnet_diagnostic.RS0017.severity = error # PublicAPI baseline entry no longer in source ################### -# Trimming Analyzer Warnings (IL2001 - IL2123) -# See: https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trim-warnings/ +# Microsoft.NET.ILLink.Analyzers (IL) ################### +# Trimming +# See: https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trim-warnings/ dotnet_diagnostic.IL2001.severity = error # Type in UnreferencedCode attribute doesn't have matching RequiresUnreferencedCode dotnet_diagnostic.IL2002.severity = error # Method with RequiresUnreferencedCode called from code without that attribute dotnet_diagnostic.IL2003.severity = error # RequiresUnreferencedCode attribute is only supported on methods @@ -1558,10 +2134,8 @@ dotnet_diagnostic.IL2117.severity = error # Methods with DynamicallyAccessedMemb dotnet_diagnostic.IL2122.severity = error # Reflection call to method with UnreferencedCode attribute cannot be statically analyzed dotnet_diagnostic.IL2123.severity = error # DynamicallyAccessedMembers on method or parameter doesn't match overridden member -################### -# AOT Analyzer Warnings (IL3xxx) +# Native AOT # See: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/warnings/ -################### dotnet_diagnostic.IL3050.severity = error # Using member annotated with RequiresDynamicCode dotnet_diagnostic.IL3051.severity = error # RequiresDynamicCode attribute is only supported on methods and constructors dotnet_diagnostic.IL3052.severity = error # RequiresDynamicCode attribute on type is not supported @@ -1571,10 +2145,16 @@ dotnet_diagnostic.IL3055.severity = error # MakeGenericType on non-supported typ dotnet_diagnostic.IL3056.severity = error # MakeGenericMethod on non-supported method requires dynamic code dotnet_diagnostic.IL3057.severity = error # Reflection access to generic parameter requires dynamic code - ################### -# SonarAnalyzer (Sxxxx) - Blocker Bug +# SonarAnalyzer.CSharp (S) ################### +# Repository suppressions +dotnet_diagnostic.S1075.severity = none # Hardcoded URI — canonical SourceLink hosts are the point +dotnet_diagnostic.S2436.severity = none # Too many generic parameters — needed for the projector overload +dotnet_diagnostic.S4036.severity = none # PATH-relative process spawn — benchmark only, trusted env +dotnet_diagnostic.S8969.severity = none # Nullability inference is inconsistent across the repository's target frameworks + +# Blocker bugs dotnet_diagnostic.S1048.severity = none # Finalizers should not throw exceptions — covered by SST1485 dotnet_diagnostic.S2190.severity = none # Loops and recursions should not be infinite dotnet_diagnostic.S2275.severity = none # Composite format strings should not lead to unexpected behavior at runtime - DUPLICATE CA2241 @@ -1586,9 +2166,7 @@ dotnet_diagnostic.S3869.severity = none # "SafeHandle.DangerousGetHandle" should dotnet_diagnostic.S3889.severity = none # "Thread.Resume" and "Thread.Suspend" should not be used -> replaced by obsolete or compiler dotnet_diagnostic.S4159.severity = none # Classes should implement their "ExportAttribute" interfaces — covered by SST2472 -################### -# SonarAnalyzer (Sxxxx) - Critical Bug -################### +# Critical bugs dotnet_diagnostic.S2551.severity = none # Shared resources should not be used for locking — covered by SST1902 dotnet_diagnostic.S2952.severity = none # Classes should "Dispose" of members from the classes' own "Dispose" methods -> replaced by SST2315 dotnet_diagnostic.S3449.severity = none # Right operands of shift operators should be integers -> replaced by SST1478 @@ -1599,9 +2177,7 @@ dotnet_diagnostic.S4586.severity = none # Non-async "Task/Task" methods shoul dotnet_diagnostic.S5856.severity = none # Regular expressions should be syntactically valid — covered by SST2444 dotnet_diagnostic.S6674.severity = none # Log message template should be syntactically correct — covered by SST2441 -################### -# SonarAnalyzer (Sxxxx) - Major Bug -################### +# Major bugs dotnet_diagnostic.S1244.severity = none # Floating point numbers should not be tested for equality — covered by SST1473 dotnet_diagnostic.S1656.severity = none # Variables should not be self-assigned — covered by SST1189 dotnet_diagnostic.S1751.severity = none # Loops with at most one iteration should be refactored - covered by SST1444 @@ -1651,9 +2227,7 @@ dotnet_diagnostic.S6798.severity = none # [JSInvokable] attribute should only be dotnet_diagnostic.S6800.severity = none # Component parameter type should match the route parameter type constraint -> replaced by SST2703 dotnet_diagnostic.S6930.severity = none # Backslash should be avoided in route templates -> replaced by SST2700 -################### -# SonarAnalyzer (Sxxxx) - Minor Bug -################### +# Minor bugs dotnet_diagnostic.S1206.severity = none # "Equals(Object)" and "GetHashCode()" should be overridden in pairs - DUPLICATE CA2218 dotnet_diagnostic.S1226.severity = none # Method parameters, caught exceptions and foreach variables' initial values should not be ignored dotnet_diagnostic.S2183.severity = none # Integral numbers should not be shifted by zero or more than their number of bits-1 — covered by SST1478 @@ -1668,17 +2242,13 @@ dotnet_diagnostic.S3397.severity = none # "base.Equals" should not be used to ch dotnet_diagnostic.S3456.severity = none # "string.ToCharArray()" and "ReadOnlySpan.ToArray()" should not be called redundantly — covered by PSH1217 dotnet_diagnostic.S3887.severity = none # Mutable, non-private fields should not be "readonly" — covered by SST2322 -################### -# SonarAnalyzer (Sxxxx) - Blocker Vulnerability -################### +# Blocker vulnerabilities dotnet_diagnostic.S2115.severity = none # A secure password should be used when connecting to a database -> replaced by SES1203 dotnet_diagnostic.S2755.severity = none # XML parsers should not be vulnerable to XXE attacks -> replaced by CA3075 dotnet_diagnostic.S3884.severity = none # "CoSetProxyBlanket" and "CoInitializeSecurity" should not be used -> replaced by obsolete (COM interop security) dotnet_diagnostic.S6418.severity = none # Secrets should not be hard-coded — covered by SES1201 -################### -# SonarAnalyzer (Sxxxx) - Critical Vulnerability -################### +# Critical vulnerabilities dotnet_diagnostic.S4423.severity = none # Weak SSL/TLS protocols should not be used -> replaced by CA5397/CA5398 dotnet_diagnostic.S4426.severity = none # Cryptographic keys should be robust -> replaced by CA5385 (RSA) / CA5384 (DSA) dotnet_diagnostic.S4433.severity = none # LDAP connections should be authenticated -> replaced by SES1310 @@ -1689,9 +2259,7 @@ dotnet_diagnostic.S5542.severity = none # Encryption algorithms should be used w dotnet_diagnostic.S5547.severity = none # Cipher algorithms should be robust -> replaced by CA5351 dotnet_diagnostic.S5659.severity = none # JWT should be signed and verified with strong cipher algorithms -> replaced by SES1503 -################### -# SonarAnalyzer (Sxxxx) - Major Vulnerability -################### +# Major vulnerabilities dotnet_diagnostic.S2068.severity = none # Credentials should not be hard-coded -> replaced by SES1201 dotnet_diagnostic.S2612.severity = none # File permissions should not be set to world-accessible values -> replaced by SES1308 dotnet_diagnostic.S4211.severity = none # Members should not have conflicting transparency annotations -> replaced by obsolete (Code Access Security) @@ -1699,9 +2267,7 @@ dotnet_diagnostic.S4212.severity = none # Serialization constructors should be s dotnet_diagnostic.S6377.severity = none # XML signatures should be validated securely -> replaced by SES1008 dotnet_diagnostic.S7039.severity = none # Content Security Policies should be restrictive -> replaced by SES1515 -################### -# SonarAnalyzer (Sxxxx) - Blocker Code Smell -################### +# Blocker code smells dotnet_diagnostic.S1147.severity = none # Exit methods should not be called — covered by SST2321 dotnet_diagnostic.S1451.severity = none # Track lack of copyright and license headers dotnet_diagnostic.S2178.severity = none # Short-circuit logic should be used in boolean contexts — covered by SST2415 @@ -1724,9 +2290,7 @@ dotnet_diagnostic.S4462.severity = none # Calls to "async" methods should not be dotnet_diagnostic.S6422.severity = none # Calls to "async" methods should not be blocking in Azure Functions — covered by PSH1315 dotnet_diagnostic.S6424.severity = none # Interfaces for durable entities should satisfy the restrictions -> off: Durable Entity-specific; not used in this library -################### -# SonarAnalyzer (Sxxxx) - Critical Code Smell -################### +# Critical code smells dotnet_diagnostic.S1006.severity = none # Method overrides should not change parameter defaults — covered by SST2424 dotnet_diagnostic.S1067.severity = none # Expressions should not be too complex dotnet_diagnostic.S1163.severity = none # Exceptions should not be thrown in finally blocks -> replaced by CA2219 @@ -1789,9 +2353,7 @@ dotnet_diagnostic.S8380.severity = none # Return types named "partial" should be dotnet_diagnostic.S8381.severity = none # "scoped" should be escaped when used as an identifier or type name in parenthesized lambda parameter lists -> replaced by compiler dotnet_diagnostic.S927.severity = none # Parameter names should match base declaration and other partial definitions - DUPLICATE CA1725 -################### -# SonarAnalyzer (Sxxxx) - Major Code Smell -################### +# Major code smells dotnet_diagnostic.S103.severity = none # Lines should not be too long — covered by SST1521 dotnet_diagnostic.S104.severity = none # Files should not have too many lines of code — covered by SST1522 dotnet_diagnostic.S106.severity = none # Covered by SST1449 (canonical) @@ -1837,555 +2399,6 @@ dotnet_diagnostic.S2933.severity = none # Fields that are only assigned in the c dotnet_diagnostic.S2971.severity = none # LINQ expressions should be simplified — covered by PSH1101/PSH1102 dotnet_diagnostic.S3010.severity = none # Static fields should not be updated in constructors — covered by SST2402 dotnet_diagnostic.S3011.severity = none # Reflection should not be used to increase accessibility of classes, methods, or fields -> replaced by SES1406 -dotnet_diagnostic.SES1406.severity = warning # Reflection must not reach non-public members via BindingFlags.NonPublic (opt-in; replaces S3011) - -# RoslynCommonAnalyzers rules added to reach 3.37.0 (on-by-default enforced; opt-in left off) -dotnet_diagnostic.PSH1000.severity = error # Anonymous functions without captures should be static. -dotnet_diagnostic.PSH1001.severity = error # Avoid allocating zero-length arrays (`[]` on C# 12+, else `Array.Empty()`). -dotnet_diagnostic.PSH1002.severity = error # Empty finalizers should be removed. -dotnet_diagnostic.PSH1003.severity = error # `in` parameters should use readonly structs. -dotnet_diagnostic.PSH1004.severity = error # Constant arrays passed as arguments should be hoisted. -dotnet_diagnostic.PSH1005.severity = error # Structs should define equality members to avoid boxing comparisons. -dotnet_diagnostic.PSH1006.severity = error # `ConcurrentDictionary` factories should use the lambda argument. -dotnet_diagnostic.PSH1007.severity = error # Pass large readonly structs by `in` reference. Configurable size threshold and exclusions. -dotnet_diagnostic.PSH1008.severity = error # GC.SuppressFinalize does nothing for sealed finalizer-free types. Code fix removes it. -dotnet_diagnostic.PSH1009.severity = error # Bound variable-length `stackalloc` with a constant guard. -dotnet_diagnostic.PSH1010.severity = error # Clear reference-typed arrays when returning them to the pool. Code fix adds `clearArray: true`. -dotnet_diagnostic.PSH1011.severity = error # Pass state to callbacks through the state-taking overload. -dotnet_diagnostic.PSH1012.severity = error # Compare type parameter values with `EqualityComparer.Default`. Code fix rewrites the call. -dotnet_diagnostic.PSH1013.severity = error # Expose constant UTF-8 data as a `ReadOnlySpan` property. Code fix converts the field. -dotnet_diagnostic.PSH1014.severity = error # Declare immutable structs as `readonly`. Code fix adds the modifier. -dotnet_diagnostic.PSH1015.severity = error # Avoid casting value types through `object`. Code fix casts directly. -dotnet_diagnostic.PSH1016.severity = error # Test enum flags with bitwise operators instead of `Enum.HasFlag`. -dotnet_diagnostic.PSH1017.severity = error # A property allocates a copy of a collection on every read. -dotnet_diagnostic.PSH1018.severity = error # A hand-written array is passed to a `params` parameter. Code fix passes the elements directly. -dotnet_diagnostic.PSH1019.severity = error # The range indexer on an array allocates a copy where a view would do. Code fix slices in place with `AsSpan` or `AsMemory`. -dotnet_diagnostic.PSH1020.severity = error # A multidimensional array is chosen where a jagged array would index on the CLR's fast path. -dotnet_diagnostic.PSH1021.severity = error # An explicit `GC.Collect` or `GC.WaitForPendingFinalizers` call forces collection the runtime tunes itself. -dotnet_diagnostic.PSH1022.severity = error # A parameterless `new EventArgs()` allocates where the shared `EventArgs.Empty` singleton would serve. Code fix uses the singleton. -dotnet_diagnostic.PSH1100.severity = none # Hot-path code should avoid `System.Linq.Enumerable` calls. Opt-in. -dotnet_diagnostic.PSH1101.severity = error # A LINQ `Where` predicate can move into the terminal call. -dotnet_diagnostic.PSH1102.severity = error # A LINQ type check followed by `Cast` can use one typed filter. -dotnet_diagnostic.PSH1103.severity = error # Prefer the collection's own count over enumerating. -dotnet_diagnostic.PSH1104.severity = error # Use `TryGetValue` instead of `ContainsKey` followed by an indexer read. -dotnet_diagnostic.PSH1105.severity = error # Avoid double lookups on dictionaries and sets. -dotnet_diagnostic.PSH1106.severity = error # Index collections directly instead of using LINQ element access. -dotnet_diagnostic.PSH1107.severity = error # Filter sequences before sorting them. -dotnet_diagnostic.PSH1108.severity = error # Chain secondary sorts with `ThenBy`. -dotnet_diagnostic.PSH1109.severity = error # Merge consecutive `Where` calls. -dotnet_diagnostic.PSH1110.severity = error # Use the collection's own predicate methods over LINQ. -dotnet_diagnostic.PSH1111.severity = error # Use `Contains` for membership tests. -dotnet_diagnostic.PSH1112.severity = error # Seed the collection through its constructor. Code fix emits `[.. source]` or a seeded constructor. -dotnet_diagnostic.PSH1113.severity = error # Sort naturally with `Order()`/`OrderDescending()` instead of an identity selector. -dotnet_diagnostic.PSH1114.severity = none # Freeze static lookup collections that are never mutated. Opt-in. -dotnet_diagnostic.PSH1115.severity = error # Insert-if-absent should probe the dictionary once. Code fix uses `TryAdd`. -dotnet_diagnostic.PSH1116.severity = error # Probe string-keyed collections with a span through `GetAlternateLookup`. -dotnet_diagnostic.PSH1117.severity = error # Ask the collection whether it is empty via `IsEmpty`. Code fix rewrites the comparison. -dotnet_diagnostic.PSH1118.severity = error # Take the extreme element without sorting. -dotnet_diagnostic.PSH1119.severity = error # Check for elements without counting them all. -dotnet_diagnostic.PSH1120.severity = error # Do not materialize a sequence just to enumerate it. -dotnet_diagnostic.PSH1122.severity = error # Read a sorted set's extreme through its `Min`/`Max` property, not the LINQ extension. Code fix uses the property. -dotnet_diagnostic.PSH1124.severity = error # Read a linked list's end through its `First`/`Last` property, not the LINQ extension. Code fix reads the node's `Value`. -dotnet_diagnostic.PSH1125.severity = error # A lazy sequence is enumerated more than once, so whatever produced it runs again. -dotnet_diagnostic.PSH1126.severity = error # An async query counts the whole result set to learn whether it has any rows. Code fix rewrites the comparison to `AnyAsync()`. -dotnet_diagnostic.PSH1127.severity = error # An array is filled with its default value one element at a time. Code fix rewrites the call to `Array.Clear`. -dotnet_diagnostic.PSH1200.severity = error # Compare strings without allocating case-converted copies. -dotnet_diagnostic.PSH1201.severity = error # Use the char overload for single-character strings. -dotnet_diagnostic.PSH1202.severity = error # Append characters as char, not single-character strings. -dotnet_diagnostic.PSH1203.severity = error # Let `StringBuilder` do the formatting work. -dotnet_diagnostic.PSH1204.severity = error # Test for empty strings by length. -dotnet_diagnostic.PSH1205.severity = error # Remove interpolation that does no work. -dotnet_diagnostic.PSH1206.severity = error # Do not build strings by concatenation in loops. -dotnet_diagnostic.PSH1207.severity = error # Specify `StringComparison` for culture-sensitive string operations. -dotnet_diagnostic.PSH1208.severity = error # Encode constant strings with u8 literals. Code fix rewrites the call. -dotnet_diagnostic.PSH1209.severity = error # Build transformed strings with `string.Create`. -dotnet_diagnostic.PSH1210.severity = error # Compare UTF-8 bytes without decoding them. Code fix uses `SequenceEqual`. -dotnet_diagnostic.PSH1211.severity = error # Pass values directly instead of `ToString` results. Code fix drops the call. -dotnet_diagnostic.PSH1212.severity = error # Slice with `AsSpan` when the call accepts a span. Code fix renames the call. -dotnet_diagnostic.PSH1213.severity = error # Probe repeated character sets through `SearchValues`. -dotnet_diagnostic.PSH1214.severity = error # Append the parts, not a concatenated whole. -dotnet_diagnostic.PSH1215.severity = error # Concatenate when there is no separator. -dotnet_diagnostic.PSH1216.severity = error # Ask for equality, not ordering. -dotnet_diagnostic.PSH1217.severity = error # Do not copy a sequence to an array just to read it. Code fix drops the copy. -dotnet_diagnostic.PSH1218.severity = error # Slice with `AsSpan` instead of allocating a substring to search it. Code fix rewrites the slice. -dotnet_diagnostic.PSH1219.severity = error # Ask whether a string is blank without trimming it. Code fix uses `string.IsNullOrWhiteSpace`. -dotnet_diagnostic.PSH1220.severity = error # A length argument spells out the run that reaches the end anyway. Code fix drops the length argument. -dotnet_diagnostic.PSH1221.severity = error # An `IndexOf` result compared to `0` scans the whole string to answer a question about position zero. Code fix rewrites it to `StartsWith`. -dotnet_diagnostic.PSH1222.severity = error # A concatenation materializes its slices before copying them again into the result. Code fix concatenates the spans. -dotnet_diagnostic.PSH1223.severity = error # A reused composite format string is re-parsed on every call. Code fix hoists it into a `static readonly CompositeFormat` field. -dotnet_diagnostic.PSH1224.severity = error # Bytes are converted to hex by building the string twice. Code fix rewrites the pair to `Convert.ToHexString`. -dotnet_diagnostic.PSH1225.severity = error # Bytes are decoded through a throwaway `char[]`. Code fix rewrites the pair to `Encoding.GetString`. -dotnet_diagnostic.PSH1226.severity = error # A string's `ToCharArray()` result is only iterated, allocating a throwaway `char[]`; iterate the string directly. Code fix drops the copy. -dotnet_diagnostic.PSH1227.severity = error # A cheaper equivalent exists — `string.CompareOrdinal` over `Compare(…, Ordinal)`, `Debug.Fail` over `Debug.Assert(false, …)`. Info. Code fix rewrites the call. -dotnet_diagnostic.PSH1300.severity = error # A dedicated object lock field should be a `System.Threading.Lock`. -dotnet_diagnostic.PSH1301.severity = error # Do not wrap a single task in `WhenAll` or `WaitAll`. -dotnet_diagnostic.PSH1302.severity = error # TaskCompletionSource should run continuations asynchronously. Code fix supplies the flag. -dotnet_diagnostic.PSH1303.severity = error # Do not block an async method with `Thread.Sleep`. Code fix awaits `Task.Delay`. -dotnet_diagnostic.PSH1304.severity = error # Use `PeriodicTimer` instead of pacing a loop with `Task.Delay`. -dotnet_diagnostic.PSH1305.severity = error # Enumerate a `ConcurrentDictionary` directly instead of a Keys/Values snapshot. Code fix deconstructs the pair. -dotnet_diagnostic.PSH1306.severity = none # Guard one-time execution with an interlocked latch. Opt-in. -dotnet_diagnostic.PSH1307.severity = error # Access interlocked fields with `Volatile`. Code fix wraps the access. -dotnet_diagnostic.PSH1308.severity = error # Return the completed task instead of `Task.FromResult`. Code fix rewrites the call. -dotnet_diagnostic.PSH1309.severity = none # Register cancellation callbacks without flowing the execution context. Opt-in. -dotnet_diagnostic.PSH1310.severity = error # An `IAsyncDisposable` is disposed by a synchronous `using` inside an async method. Code fix inserts the `await`. -dotnet_diagnostic.PSH1311.severity = error # An `async` method whose body is one tail-position await builds a state machine only to forward a task. Code fix drops `async` and returns the task. -dotnet_diagnostic.PSH1312.severity = error # A `null` is returned where the declared return type is `Task` or `Task`. Code fix returns a completed task. -dotnet_diagnostic.PSH1313.severity = error # An `async` method calls a synchronous method that has a fitting async overload. Code fix awaits the async overload. -dotnet_diagnostic.PSH1314.severity = error # A stream is read or written through the array-based `ReadAsync`/`WriteAsync` overloads. Code fix rewrites the call via `AsMemory`. -dotnet_diagnostic.PSH1315.severity = error # A thread is parked on a task that is not provably complete — `Result`, `Wait()`, `GetAwaiter().GetResult()` on a `Task` or `ValueTask`. The guarded fast path and an awaiter's own `GetResult` are silent. Code fix awaits, where an `await` compiles. -dotnet_diagnostic.PSH1316.severity = error # A `ValueTask` is consumed more than once - awaited across loop iterations, or through a copy - so a later consume reads a recycled pooled token. Code fix hoists the producer into the loop. -dotnet_diagnostic.PSH1400.severity = error # Use the static `HashData` method for one-shot hashing. -dotnet_diagnostic.PSH1401.severity = error # Attribute types should be sealed. -dotnet_diagnostic.PSH1402.severity = error # Use `const` for compile-time constants. -dotnet_diagnostic.PSH1403.severity = error # Do not initialize fields to their default value. -dotnet_diagnostic.PSH1404.severity = error # Get the assembly from `typeof` instead of a stack walk. -dotnet_diagnostic.PSH1405.severity = error # Use the direct `Environment` APIs. -dotnet_diagnostic.PSH1406.severity = error # Ask `Regex` for the answer directly. -dotnet_diagnostic.PSH1407.severity = error # Query the dictionary, not its `Keys` view. -dotnet_diagnostic.PSH1408.severity = error # Measure elapsed time with `Stopwatch.GetTimestamp`/`GetElapsedTime` instead of allocating a Stopwatch. -dotnet_diagnostic.PSH1409.severity = error # Use the built-in throw helpers for argument guards. Code fix rewrites the guard, honoring helper aliases. -dotnet_diagnostic.PSH1410.severity = none # Mark trivial forwarders for aggressive inlining. Opt-in. -dotnet_diagnostic.PSH1411.severity = error # Seal non-public types nothing derives from so the JIT can devirtualize. Code fix adds `sealed`. -dotnet_diagnostic.PSH1412.severity = error # Use `Random.Shared` instead of allocating a `Random`. Code fix takes the shared instance. -dotnet_diagnostic.PSH1413.severity = error # Read the Unix epoch from `DateTime.UnixEpoch`, not a hand-built date. Code fix uses the field. -dotnet_diagnostic.PSH1414.severity = error # A private or internal member never touches instance state, so it still pays for a receiver it does not use; test, benchmark, and serialization-callback members (and members of test-fixture types) are left alone because a framework needs them on an instance. Code fix for a private member adds `static` and repairs `this.`-qualified call sites. -dotnet_diagnostic.PSH1415.severity = error # A local or private field is typed as an interface where only one concrete type is ever assigned. Code fix changes the declared type. -dotnet_diagnostic.PSH1416.severity = error # A fresh `JsonSerializerOptions` per call throws away the serializer's per-type metadata cache. -dotnet_diagnostic.PSH1417.severity = error # An expensive argument is computed for a `Debug.Assert` that release builds compile away. -dotnet_diagnostic.PSH1418.severity = error # A shareable client (`HttpClient` or an Azure SDK service client) is constructed for a single call, so its pooled connections and caches die with it and every call pays the setup cost again. -dotnet_diagnostic.PSH1419.severity = error # A call to the TimeZoneConverter package where the built-in `TimeZoneInfo` now resolves IANA and Windows ids cross-platform (.NET 6+). Code fix rewrites `GetTimeZoneInfo` to `TimeZoneInfo.FindSystemTimeZoneById`. -dotnet_diagnostic.PSH1420.severity = error # A shareable client held in an instance field of an Azure Functions worker class is rebuilt on every invocation, leaking sockets and connections; share a static/singleton client or inject `IHttpClientFactory`. -dotnet_diagnostic.PSH1500.severity = error # A route handler returns `Results.*`; `TypedResults.*` avoids boxing the result and gives the endpoint its response metadata. Code fix rewrites the call. -dotnet_diagnostic.PSH1501.severity = error # Middleware is registered in the legacy `Use(next => context => ...)` nested-delegate form, which allocates a per-request closure; the two-parameter `Use((context, next) => ...)` overload does not. -dotnet_diagnostic.PSH1502.severity = error # A route handler returns a deferred `IEnumerable` (an `IQueryable` or an un-materialized LINQ query), so the response serializer enumerates it synchronously on the request thread. -dotnet_diagnostic.PSH1503.severity = error # The legacy response-caching middleware only honors HTTP cache-control headers; output caching (.NET 7+) caches on the server under keys you control and can be invalidated. Info. -dotnet_diagnostic.PSH1505.severity = error # A class implements an MVC exception filter (`IExceptionFilter`/`IAsyncExceptionFilter`); centralized error handling belongs in an `IExceptionHandler` the pipeline runs once. Info. -dotnet_diagnostic.PSH1506.severity = error # The HTTP request or response body is read or written synchronously (`ReadToEnd`, `Body.Read`, `Body.Write`), which blocks a thread on Kestrel and buffers the whole payload; use the async overload. Code fix awaits it when the method is already async. -dotnet_diagnostic.PSH1600.severity = error # A delegate captured per iteration inside a component render loop reallocates on every render (measured ~128 B per row per render) and churns the diff; hoist it to a cached delegate or a precomputed per-item model. -dotnet_diagnostic.PSH1601.severity = error # A JavaScript-interop call is issued once per loop iteration; on Interactive Server each is a separate SignalR round-trip. Batch into a single call over the collection. -dotnet_diagnostic.PSH1602.severity = error # `StateHasChanged` is called unconditionally in `OnAfterRender`/`OnAfterRenderAsync`, scheduling another render every time — a runaway loop. Guard it with `firstRender` or a state flag. -dotnet_diagnostic.PSH1603.severity = error # A non-delegate allocation is used as a component-parameter value inside a render loop, allocating per item and forcing the child to re-render each pass. Sibling of PSH1600. -dotnet_diagnostic.SES1001.severity = error # AEAD encryption (`AesGcm`/`AesCcm`/`ChaCha20Poly1305`) uses a constant or reused nonce, which is catastrophic under a fixed key. -dotnet_diagnostic.SES1002.severity = error # Password-based key derivation (`Rfc2898DeriveBytes`/`Pbkdf2`) is given a constant or predictable salt, letting an attacker precompute rainbow tables and defeating per-secret salting. -dotnet_diagnostic.SES1003.severity = error # A `Rfc2898DeriveBytes.Pbkdf2` one-shot derives a key with a constant iteration count below the configured floor (default 100000), leaving offline password cracking cheap. -dotnet_diagnostic.SES1004.severity = error # A secret (token, key, password, nonce, salt, session id, OTP, reset token) is minted from `Guid.NewGuid()`; a GUID is an identifier, not a cryptographically strong secret. -dotnet_diagnostic.SES1005.severity = error # A secret (HMAC, signature, tag, token, or hash) is compared with a non-constant-time equality (`==`, `.Equals`, `SequenceEqual`), leaking it a byte at a time through timing. Code fix rewrites a byte-buffer comparison to `CryptographicOperations.FixedTimeEquals`. -dotnet_diagnostic.SES1006.severity = error # A Data Protection key ring is persisted to an explicit repository (`PersistKeysToFileSystem`/`DbContext`/`AzureBlobStorage`/`StackExchangeRedis`/`Registry`) with no `ProtectKeysWith...` call in the same chain, so the keys are stored unencrypted at rest. -dotnet_diagnostic.SES1007.severity = error # A type derives from an abstract cryptographic primitive base (`HashAlgorithm`/`KeyedHashAlgorithm`/`HMAC`/`SymmetricAlgorithm`/`AsymmetricAlgorithm`/`DeriveBytes`) and implements the algorithm by hand; use a vetted platform implementation. Subclassing a concrete algorithm to configure it is not reported. -dotnet_diagnostic.SES1008.severity = error # An XML signature is verified with the no-key `SignedXml.CheckSignature()` overload, which trusts the key embedded in the document's `KeyInfo`, so an attacker can re-sign tampered XML with their own key and still pass; pass a known key or certificate instead. -dotnet_diagnostic.SES1009.severity = error # A password is hashed with a fast general-purpose hash (`MD5`/`SHA-1`/`SHA-256`/`SHA-384`/`SHA-512`) via `HashData`/`ComputeHash` instead of a slow, salted password KDF; a fast hash is cheap to brute-force even when salted. -dotnet_diagnostic.SES1102.severity = error # A read of `HttpClientHandler.DangerousAcceptAnyServerCertificateValidator` disables TLS server-certificate validation, so the client trusts any certificate and the connection is open to man-in-the-middle attacks. -dotnet_diagnostic.SES1104.severity = error # X509 certificate-chain validation is deliberately weakened: `RevocationMode` set to `NoCheck`, or `VerificationFlags` set to a value naming `AllowUnknownCertificateAuthority` or `AllFlags` (alone or OR-combined), so revoked or untrusted certificates are accepted. -dotnet_diagnostic.SES1105.severity = error # Bearer/OpenID Connect metadata is fetched over plain HTTP because `RequireHttpsMetadata` is set to false outside a development-environment guard, exposing token validation to a network attacker. -dotnet_diagnostic.SES1106.severity = error # An `HttpClient` request targets a cleartext `http://` URL literal (a string overload, a `new Uri(...)` argument, or a `BaseAddress` assignment); non-loopback hosts only. -dotnet_diagnostic.SES1107.severity = error # A SQL connection weakens transport security: `TrustServerCertificate=true`, `Encrypt=false`, or `Encrypt=Optional` in a literal connection string or a `SqlConnectionStringBuilder`, bypassing server-certificate validation or transport encryption. -dotnet_diagnostic.SES1108.severity = error # A custom `HttpClientHandler.ServerCertificateCustomValidationCallback` always returns `true` (an expression/block lambda, an anonymous method, or a method group to a source method of that shape), disabling TLS server authentication so the client trusts any certificate. -dotnet_diagnostic.SES1201.severity = error # A string literal hard-codes a recognizable credential (API key, token, private key, or connection-string password), which is committed to source and must be treated as leaked. -dotnet_diagnostic.SES1202.severity = error # A non-empty string literal is hard-coded where a credential is expected (a credential-named parameter or a credential-type constructor), even when its text is not a recognizable secret pattern. -dotnet_diagnostic.SES1203.severity = error # A database connection-string literal names a user but supplies an empty or missing password, a zero-strength credential that lets anyone who can reach the server authenticate as that account. -dotnet_diagnostic.SES1301.severity = error # A process command line is composed from a non-constant interpolated or concatenated string via `ProcessStartInfo.Arguments` (assignment or object initializer) or `Process.Start(fileName, arguments)`; use `ArgumentList` so each argument is escaped. -dotnet_diagnostic.SES1302.severity = error # A `ProcessStartInfo` with `UseShellExecute = true` names a non-constant `FileName` (from the initializer or the constructor argument), so the OS shell resolves a data-derived program: a command-injection and unexpected-program risk. -dotnet_diagnostic.SES1303.severity = error # A regular-expression pattern is built from non-constant data, letting an attacker inject regex metacharacters (alternation, catastrophic backtracking, capture rewriting); reports the pattern argument of the `Regex` constructor and the static `Regex.IsMatch`/`Match`/`Matches`/`Replace`/`Split` overloads. -dotnet_diagnostic.SES1304.severity = error # An archive entry name (`ZipArchiveEntry.FullName` / `TarEntry.Name`) is joined via `Path.Combine` or `+` straight into a file-writing sink with no inline containment check, letting a crafted `../` or absolute entry escape the target directory (zip slip / path traversal). -dotnet_diagnostic.SES1305.severity = error # An uploaded file name (`IFormFile.FileName`) is used to build a storage path -- a `Path.Combine` argument, a `+` path concatenation, or a file-creating call (`File.Create`/`OpenWrite`/`WriteAllBytes`/`Copy`, `new FileStream`) -- enabling path traversal; sanitize with `Path.GetFileName` or use a server-generated name. -dotnet_diagnostic.SES1306.severity = error # Non-constant C# source is compiled and executed via the scripting API (`CSharpScript.EvaluateAsync`/`RunAsync`/`Create`), which is arbitrary code execution; the code channel must be a constant, trusted template rather than runtime data. -dotnet_diagnostic.SES1307.severity = error # `Path.GetTempFileName()` creates a predictable, world-readable temporary file open to a time-of-check/time-of-use race and a 65535-file limit (CWE-377); use `Path.GetRandomFileName()` for an unpredictable name, or `Directory.CreateTempSubdirectory()` (.NET 7+) for an isolated directory. -dotnet_diagnostic.SES1308.severity = error # A file or directory is created group- or world-writable (a `UnixFileMode` including `GroupWrite`/`OtherWrite`, CWE-732), letting other local users tamper with it. -dotnet_diagnostic.SES1309.severity = error # An XSLT stylesheet is loaded via `XslCompiledTransform.Load` with `XsltSettings` that enable embedded script (`EnableScript = true`, a constant `enableScript` constructor argument, or `XsltSettings.TrustedXslt`), letting a stylesheet run arbitrary code in the host process (CWE-95). -dotnet_diagnostic.SES1310.severity = error # A `DirectoryEntry` binds to the directory without proving identity — `AuthenticationTypes.Anonymous`, or an `LDAP://` path bound with an explicitly empty/`null` username and password (CWE-287). -dotnet_diagnostic.SES1401.severity = error # A type resolved from non-constant data via `Type.GetType` is passed inline to `Activator.CreateInstance` or a `Deserialize(Type, ...)` call, letting untrusted input choose which type is instantiated. -dotnet_diagnostic.SES1402.severity = error # An assembly is loaded from raw bytes (`Assembly.Load(byte[])` / `AssemblyLoadContext.LoadFromStream`) or from a non-constant `LoadFrom`/`LoadFile`/`UnsafeLoadFrom` path, running unverifiable code with full process trust. -dotnet_diagnostic.SES1403.severity = error # A constant `System.Text.Json` `MaxDepth` (on `JsonSerializerOptions`/`JsonReaderOptions`/`JsonDocumentOptions`) is raised above a configurable ceiling (default 64), re-opening the deep-nesting stack-exhaustion denial-of-service that the default limit guards against. -dotnet_diagnostic.SES1404.severity = error # A type is instantiated by name through the string overloads of `Activator.CreateInstance`/`Activator.CreateInstanceFrom` from a non-constant `typeName`, letting untrusted input choose which type is constructed (CWE-470). -dotnet_diagnostic.SES1405.severity = error # MessagePack typeless deserialization (`MessagePackSerializer.Typeless`, or a serializer built on `TypelessObjectResolver`/`TypelessContractlessStandardResolver`) reconstructs whatever .NET type the payload names, letting untrusted input instantiate arbitrary types (CWE-502). -dotnet_diagnostic.SES1501.severity = error # A single CORS policy calls both `AllowAnyOrigin()` and `AllowCredentials()` on `CorsPolicyBuilder`; a wildcard origin combined with credentials is rejected by browsers and throws when the policy is applied. -dotnet_diagnostic.SES1502.severity = error # A CORS origin predicate passed to `CorsPolicyBuilder.SetIsOriginAllowed` unconditionally returns true (`_ => true`), allowing every origin -- equivalent to `AllowAnyOrigin` and dangerous with credentials. -dotnet_diagnostic.SES1503.severity = error # JWT signature verification is turned off on `TokenValidationParameters` because `RequireSignedTokens` or `ValidateIssuerSigningKey` is set to false, so a forged or unsigned token passes validation. -dotnet_diagnostic.SES1504.severity = error # A cookie initializer (`CookieOptions`/`CookieBuilder`) sets `SameSite=None` without securing the cookie in the same initializer (`Secure = true`, or a non-`None` `SecurePolicy`), so the browser drops it or it travels over plain HTTP. -dotnet_diagnostic.SES1505.severity = error # The request body size limit is removed -- `[DisableRequestSizeLimit]` on a controller or action, or `MaxRequestBodySize` set to null on `KestrelServerLimits`/`IHttpMaxRequestBodySizeFeature` -- letting a client stream an unbounded upload and exhaust server memory or disk. -dotnet_diagnostic.SES1506.severity = error # The developer exception page (`UseDeveloperExceptionPage`) is enabled without a development-environment guard, so in production it renders full exception detail and stack traces to the client. -dotnet_diagnostic.SES1507.severity = error # A single method or type declaration carries both `[AllowAnonymous]` and `[Authorize]`; the anonymous marker wins at runtime, so the co-located `[Authorize]` is dead and the endpoint is unauthenticated. -dotnet_diagnostic.SES1508.severity = error # A validation/verification method (`bool`/`Task` named `Validate`/`Verify`/`Authenticate`/`Authorize`/`Check`/`IsValid`/`IsAuthentic`/`Ensure`) fails open: a `catch` swallows a broad or security-relevant exception and returns success. -dotnet_diagnostic.SES1509.severity = error # A constant, backtracking-prone regular expression (an unbounded quantifier over a group that itself repeats or alternates, as in `(a+)+` or `(a -dotnet_diagnostic.SES1510.severity = error # A controller (`ControllerBase`) redirects to a non-constant URL via `Redirect`/`RedirectPermanent`/`RedirectPreserveMethod`/`RedirectPermanentPreserveMethod`; an attacker-controlled target is an open redirect (CWE-601) to a phishing site — validate the URL is local (e.g. `LocalRedirect`). -dotnet_diagnostic.SES1511.severity = error # The forwarded-headers trust boundary is removed — `.Clear()` on `KnownProxies`/`KnownNetworks`/`KnownIPNetworks`, or `ForwardLimit` set to null — so untrusted proxies can spoof the client IP, host, and scheme via `X-Forwarded-*` headers (CWE-348). -dotnet_diagnostic.SES1512.severity = error # Sensitive framework diagnostics — EF Core `EnableSensitiveDataLogging()`, or `IdentityModelEventSource.ShowPII`/`LogCompleteSecurityArtifact = true` — are enabled without a development-environment guard, so parameter values, PII, and full tokens land in production logs (CWE-215/532). -dotnet_diagnostic.SES1513.severity = error # An `IAuthorizationService.AuthorizeAsync` call discards its `AuthorizationResult` (a bare await or `_ =`), so nothing reads `Succeeded` and the guarded operation runs whether or not authorization passed (CWE-863). -dotnet_diagnostic.SES1514.severity = error # OpenID Connect protocol protections are disabled — `UsePkce`, `RequireState`, `RequireStateValidation`, or `RequireNonce` set to false — weakening the authorization-code flow against CSRF and replay (CWE-352/294). -dotnet_diagnostic.SES1515.severity = error # A `Content-Security-Policy` value carries `'unsafe-inline'`, `'unsafe-eval'`, or a bare `*` source on a `default-src`/`script-src`/`style-src`/`object-src`/`base-uri` directive, re-permitting injected inline scripts and defeating the header's XSS protection (CWE-1021/79). -dotnet_diagnostic.SES1601.severity = error # An LLM system-role message (`Microsoft.Extensions.AI` `ChatMessage(ChatRole.System, ...)`, or Semantic Kernel `ChatHistory.AddSystemMessage`/`AddMessage(AuthorRole.System, ...)`/`ChatMessageContent(AuthorRole.System, ...)`) is given non-constant content; runtime or user data in the instruction channel is a prompt-injection risk. -dotnet_diagnostic.SES1602.severity = error # AI model output (`ChatResponse`/`ChatMessage` `.Text`) flows inline into a dangerous sink (a process start, a scripting call, a raw SQL command, or a `File` path); executing or evaluating model output is a prompt-injection-to-code-execution path. -dotnet_diagnostic.SES1603.severity = error # A model-facing tool declared read-only (`ReadOnly = true`) or non-destructive (`Destructive = false`) via `[McpServerTool]` calls a state-changing API in its body (a file delete or overwrite, a directory delete, a process start, an ADO.NET non-query, an EF bulk mutation, or `SaveChanges`), so a host may auto-invoke it and cause irreversible damage. -dotnet_diagnostic.SES1604.severity = error # A Semantic Kernel prompt template disables the default encoding of substituted input by setting `AllowDangerouslySetContent = true` on `PromptTemplateConfig`/`InputVariable`/a template factory, re-opening prompt injection through template variables. -dotnet_diagnostic.SES1605.severity = error # Sensitive AI telemetry capture is enabled (`EnableSensitiveData = true`) on a `Microsoft.Extensions.AI` OpenTelemetry instrumentation client, shipping raw prompts and model responses -- which routinely carry secrets and PII -- verbatim to the telemetry backend. -dotnet_diagnostic.SES1606.severity = error # A string literal targets a model-weights file (`.onnx`, `.gguf`, `.safetensors`, `.pt`, `.pth`, `.ckpt`) over a cleartext `http://` URL, letting a network attacker swap in a tampered or backdoored model; non-loopback hosts only, and the `HttpClient`-sink case is left to SES1106. -dotnet_diagnostic.SES1701.severity = error # Raw HTML is rendered from a non-constant value (`MarkupString`/`AddMarkupContent`), bypassing automatic encoding — an XSS risk. Sanitizer allow-list via `securitysharp.SES1701.sanitizers`. -dotnet_diagnostic.SES1702.severity = error # A JavaScript-interop call targets a script-evaluation primitive (`eval`, `Function`, `document.write`), turning interop into a script-injection channel. -dotnet_diagnostic.SES1703.severity = error # `[Authorize]` on a non-routable component enforces nothing — authorization runs as a routing concern. Exempt types via `securitysharp.SES1703.exempt_types`. -dotnet_diagnostic.SES1704.severity = error # `IHttpContextAccessor` or a cascading `HttpContext` is used in an interactively-rendered component, where it is null or frozen at circuit start. -dotnet_diagnostic.SES1705.severity = error # `NavigationManager.NavigateTo` is called with a target that is not a verified relative URL — an open-redirect risk. Validator allow-list via `securitysharp.SES1705.validators`. -dotnet_diagnostic.SES1706.severity = error # An uploaded file is read with an unbounded or client-chosen size limit, letting an attacker fill server memory. Threshold via `securitysharp.SES1706.max_bytes`. -dotnet_diagnostic.SES1707.severity = error # A secret-shaped literal appears in code reachable as WebAssembly, which downloads to the browser in full — guaranteed disclosure. -dotnet_diagnostic.SES1708.severity = error # `CircuitOptions.DetailedErrors` is enabled, shipping server exception detail to every connected client. -dotnet_diagnostic.SES1709.severity = error # `SerializeAllClaims` serializes every claim into client-readable WebAssembly authentication state, exposing internal ids, tokens, and PII. -dotnet_diagnostic.SES1710.severity = error # Antiforgery validation is disabled on a form (`[RequireAntiforgeryToken(required: false)]`), removing CSRF protection. -dotnet_diagnostic.SST1119.severity = error # A numeric literal's digit separators group its digits irregularly. Code fix regroups them evenly. -dotnet_diagnostic.SST1138.severity = error # A free-standing block declares nothing and only nests its statements. Code fix splices them into the enclosing block. -dotnet_diagnostic.SST1218.severity = error # Other members separate a method's overloads. Code fix moves the overload back beside its family. -dotnet_diagnostic.SST1219.severity = error # A `switch` statement's `default` section is not last. Code fix moves it to the end. -dotnet_diagnostic.SST1220.severity = error # An all-named argument list is in a different order than the parameters. Code fix reorders it to declaration order. Info. -dotnet_diagnostic.SST1221.severity = error # `where` constraint clauses are not ordered to match the type-parameter list. Code fix reorders them. Info. -dotnet_diagnostic.SST1319.severity = error # An enumeration's type name holds an underscore or an all-capitals acronym. SST1300 owns its first character. -dotnet_diagnostic.SST1320.severity = error # A method parameter's name is identical to its containing method's name. -dotnet_diagnostic.SST1321.severity = error # A method whose name ends in `Async` returns nothing awaitable — the inverse of SST1317. Code fix (rename) drops the suffix. -dotnet_diagnostic.SST1445.severity = error # A using directive is unnecessary. Code fix removes it. -dotnet_diagnostic.SST1446.severity = error # An inheritance chain is deeper than the configured maximum. Configurable depth and external counting. -dotnet_diagnostic.SST1447.severity = error # An equality override delegates to object's reference semantics. -dotnet_diagnostic.SST1448.severity = error # An argument is passed explicitly to a caller-info parameter. Code fix removes it. -dotnet_diagnostic.SST1449.severity = error # Code writes directly to the console. -dotnet_diagnostic.SST1451.severity = error # A DateTime is created without a DateTimeKind. -dotnet_diagnostic.SST1452.severity = error # A generic type parameter is never used. -dotnet_diagnostic.SST1453.severity = error # A statement follows an unconditional exit and cannot run. -dotnet_diagnostic.SST1454.severity = error # A composite format string contains a placeholder that no argument can satisfy. -dotnet_diagnostic.SST1455.severity = error # A declaration is marked `unsafe` but contains no unsafe syntax. -dotnet_diagnostic.SST1456.severity = error # A readonly field stores a mutable source-defined struct. -dotnet_diagnostic.SST1457.severity = error # A global suppression target does not resolve to a declaration in the compilation. -dotnet_diagnostic.SST1458.severity = error # A global suppression target uses a legacy tilde-prefixed target string. -dotnet_diagnostic.SST1459.severity = error # Parentheses wrap a standalone expression in a context where grouping has no effect. -dotnet_diagnostic.SST1460.severity = error # A struct instance member can be marked `readonly` because it does not mutate state. -dotnet_diagnostic.SST1461.severity = error # A private or local-function parameter is never read. -dotnet_diagnostic.SST1462.severity = error # A suppression targets a diagnostic that is disabled in the active analyzer config scope. -dotnet_diagnostic.SST1463.severity = error # A symbol-name string literal can use `nameof`. -dotnet_diagnostic.SST1464.severity = error # Unwrap an `else` that follows a branch which does not fall through. -dotnet_diagnostic.SST1465.severity = error # Collapse an `else` block that only wraps an `if`. -dotnet_diagnostic.SST1466.severity = error # Remove case labels that share a section with `default`. -dotnet_diagnostic.SST1467.severity = error # Enumerate with `foreach` instead of driving the enumerator by hand. -dotnet_diagnostic.SST1468.severity = error # Boolean logic should short-circuit. -dotnet_diagnostic.SST1469.severity = error # Do not compare a value type to null. -dotnet_diagnostic.SST1470.severity = error # Remove a catch clause that only rethrows. -dotnet_diagnostic.SST1471.severity = error # Magic numbers should be named constants. -dotnet_diagnostic.SST1472.severity = error # Signatures should not declare too many parameters. -dotnet_diagnostic.SST1473.severity = error # Floating-point values should not be compared for exact equality. Code fix rewrites NaN tests as `IsNaN`. -dotnet_diagnostic.SST1474.severity = error # Identical expressions appear on both sides of an operator. -dotnet_diagnostic.SST1475.severity = error # A condition repeats one already tested — in a chain or `switch` (its branch cannot run), or in the `if` immediately before it. -dotnet_diagnostic.SST1476.severity = error # Every branch of a conditional has the same body, so the condition decides nothing. -dotnet_diagnostic.SST1477.severity = error # An integer division is widened to a floating-point type after it has already truncated. Code fix casts an operand. -dotnet_diagnostic.SST1478.severity = error # A shift count is zero, negative, or at least the operand's width. -dotnet_diagnostic.SST1479.severity = error # A count or length is compared against a value it can never take. Code fix folds the constant. -dotnet_diagnostic.SST1480.severity = error # An exception is constructed and then discarded. Code fix adds the `throw`. -dotnet_diagnostic.SST1481.severity = error # A bitwise operation has a constant operand that makes it pointless. Code fix removes the operation. -dotnet_diagnostic.SST1482.severity = error # `GetHashCode` reads mutable state, which loses the object in any hash-based collection. -dotnet_diagnostic.SST1483.severity = error # A constructor calls an overridable member, so a derived override sees a half-built object. -dotnet_diagnostic.SST1484.severity = error # A declaration shadows a field or property of an enclosing scope. -dotnet_diagnostic.SST1485.severity = error # A member callers cannot defend against — `Equals`, `Dispose`, an operator — throws. -dotnet_diagnostic.SST1486.severity = error # The same string literal is repeated instead of being named once. -dotnet_diagnostic.SST1487.severity = error # A collection element is assigned twice with nothing reading it in between. -dotnet_diagnostic.SST1488.severity = error # An exception type does not declare the standard constructors. Code fix adds them, documented. -dotnet_diagnostic.SST1489.severity = error # An exception type carries formatter-based serialization members the target framework has obsoleted. Code fix removes them. -dotnet_diagnostic.SST1490.severity = error # A base list names an interface the rest of the list already implies. Code fix removes the entry. -dotnet_diagnostic.SST1491.severity = error # A modifier restates the declaration's default. Code fix removes the modifier. -dotnet_diagnostic.SST1492.severity = error # A value is tested against what it is then assigned, so the guard decides nothing. Code fix keeps the assignment. -dotnet_diagnostic.SST1493.severity = error # A method's whole body is a constant. Code fix exposes it as a get-only property. -dotnet_diagnostic.SST1494.severity = error # A trailing argument repeats the parameter's default. Code fix drops it, and the ones after it. -dotnet_diagnostic.SST1495.severity = error # `==` compares references on a type that overrides `Equals`, so the two disagree. Code fix calls `object.Equals`. -dotnet_diagnostic.SST1496.severity = error # An abstract type declares nothing abstract, so it asks nothing of its derived types. Code fix makes it concrete. -dotnet_diagnostic.SST1497.severity = error # A local is declared and never read. Code fix removes the variable and keeps what computing it did. -dotnet_diagnostic.SST1498.severity = error # Only a nested type uses a private member, so it is declared further out than it needs to be. Code fix moves a static method into the nested type. -dotnet_diagnostic.SST1499.severity = error # A static field visible outside its type can still be changed — it is global mutable state. Code fix adds `readonly` when that is all it takes. -dotnet_diagnostic.SST1521.severity = error # A line is longer than the configured maximum, which defaults to 120 characters. -dotnet_diagnostic.SST1522.severity = error # A file has more code lines than the configured maximum, which defaults to 500. -dotnet_diagnostic.SST1523.severity = error # A member has more code lines than the configured maximum, which defaults to 60. -dotnet_diagnostic.SST1524.severity = error # A switch section has more code lines than the configured maximum, which defaults to 20. -dotnet_diagnostic.SST1525.severity = error # A multi-statement `switch` section has no braces; the braces-on policy extends to switch sections. Code fix wraps it. -dotnet_diagnostic.SST1526.severity = none # A wrapped binary expression places the operator inconsistently. Configurable (`before`/`after`, default before). Opt-in. -dotnet_diagnostic.SST1527.severity = none # The `=>` of an expression-bodied member wraps inconsistently. Configurable. Opt-in. -dotnet_diagnostic.SST1528.severity = none # The `=` of a wrapped initializer wraps inconsistently. Configurable. Opt-in. -dotnet_diagnostic.SST1529.severity = none # A wrapped `?.`/`.` call chain places the break inconsistently. Configurable. Opt-in. -dotnet_diagnostic.SST1530.severity = none # A newline sits between a type declaration and its base list. Code fix pulls the base list onto the declaration line. Opt-in. -dotnet_diagnostic.SST1531.severity = none # A short object initializer is split across lines. Code fix collapses it when it fits. Opt-in. -dotnet_diagnostic.SST1532.severity = none # A file mixes line endings. Configurable (`lf`/`crlf`, default lf). Opt-in. -dotnet_diagnostic.SST1533.severity = none # A source file contains no code. Opt-in. -dotnet_diagnostic.SST1658.severity = error # Documentation prose repeats a word ("the the"). Code fix removes the repeat. -dotnet_diagnostic.SST1659.severity = error # A comment has no text at all. Code fix removes it. -dotnet_diagnostic.SST1660.severity = error # The `` tags are not in parameter order. Code fix reorders them. Info. -dotnet_diagnostic.SST1661.severity = error # A snippet uses ``/`` mismatched to single- vs multi-line content. Code fix swaps the tag. Info. -dotnet_diagnostic.SST1662.severity = none # A thrown exception type has no `` documentation. Code fix adds the skeleton. Opt-in. -dotnet_diagnostic.SST1663.severity = none # A `//` comment before a public member reads like a summary; use `///`. Code fix converts it. Opt-in. -dotnet_diagnostic.SST1664.severity = none # A summary separates paragraphs with blank lines instead of ``. Code fix wraps them. Opt-in. -dotnet_diagnostic.SST1708.severity = error # An extension method never uses its `this` receiver, so it need not be an extension. -dotnet_diagnostic.SST1709.severity = none # A method in a `*Extensions` class whose first parameter lacks `this`. Code fix converts it to an extension block. Opt-in. -dotnet_diagnostic.SST1804.severity = error # A positional record has an empty `{ }` body where `;` would do. Code fix rewrites it. Info. -dotnet_diagnostic.SST1904.severity = error # A lock targets a non-readonly field, which a later assignment can swap out from under a caller. Code fix makes it readonly. -dotnet_diagnostic.SST1905.severity = error # An `async void` method, lambda, or local function that is not a genuine event handler. Code fix returns `Task`. -dotnet_diagnostic.SST2008.severity = error # A negated pattern test should use an `is not` pattern. -dotnet_diagnostic.SST2009.severity = error # A catch block tests a condition and rethrows on the losing branch, which is an exception filter written by hand. Code fix moves the condition into a `when` clause. -dotnet_diagnostic.SST2010.severity = none # A type reads the machine clock directly instead of through a `TimeProvider`. Opt-in. -dotnet_diagnostic.SST2011.severity = error # An instant is recorded from the local clock. Code fix rewrites `.Now` to `.UtcNow`. -dotnet_diagnostic.SST2012.severity = error # A GUID is constructed with the parameterless constructor. Code fix uses `Guid.Empty`. -dotnet_diagnostic.SST2013.severity = error # An `if` whose entire body is another `if`, with no `else` on either. Code fix merges the conditions. -dotnet_diagnostic.SST2014.severity = error # A `goto` jumps to a label. -dotnet_diagnostic.SST2015.severity = error # A `++` or `--` is buried inside a larger expression, so its side effect happens in the middle of something else. -dotnet_diagnostic.SST2016.severity = error # A `DateTime` is the type of an externally visible field, property, parameter or return type, so the offset is lost at the boundary. -dotnet_diagnostic.SST2017.severity = error # A `.Date` or `.TimeOfDay` read proves the value is only a date, or only a time of day: use `DateOnly` / `TimeOnly`. -dotnet_diagnostic.SST2018.severity = error # A null check sits beside an `is` type pattern that already excludes null. Code fix removes the null check. -dotnet_diagnostic.SST2234.severity = error # `Nullable` should use the `T?` shorthand. Code fix rewrites it. -dotnet_diagnostic.SST2235.severity = error # A capture-free local function can be declared `static`. -dotnet_diagnostic.SST2236.severity = error # A tail-position using block can use a using declaration. -dotnet_diagnostic.SST2237.severity = error # A single block-scoped namespace can use file-scoped syntax. -dotnet_diagnostic.SST2238.severity = error # A nested property pattern can use extended property-pattern syntax. -dotnet_diagnostic.SST2239.severity = error # A lambda that only forwards to one method can use a method group. -dotnet_diagnostic.SST2240.severity = error # A delegate null check followed by invocation can use conditional invocation. -dotnet_diagnostic.SST2241.severity = error # A constructor that only stores its parameters can use primary-constructor storage. Code fix moves the parameters and member initializers. -dotnet_diagnostic.SST2242.severity = error # An enum switch statement mapping should name every enum value or include a catch-all. -dotnet_diagnostic.SST2243.severity = error # A verbatim string literal is full of doubled-quote escapes, or spans lines. Code fix rewrites it as a raw string literal. -dotnet_diagnostic.SST2244.severity = error # A numeric literal's suffix is lower case. Code fix upper-cases the suffix, leaving the digits alone. -dotnet_diagnostic.SST2245.severity = error # A `for` loop with only a condition should be a `while` loop. Code fix rewrites it. -dotnet_diagnostic.SST2246.severity = error # A chain of `?:` expressions that tests one value against constants can be a switch expression. Code fix rewrites it. -dotnet_diagnostic.SST2247.severity = error # Consecutive locals that copy one tuple- or `Deconstruct`-able value's members in order should be a deconstruction. Code fix folds them into `var (a, b) = source;`. -dotnet_diagnostic.SST2248.severity = error # Two comparisons of the same value against constants can fold into one `is`-pattern. Code fix rewrites them. -dotnet_diagnostic.SST2249.severity = error # A `string.Format` call with a literal format, or a concatenation of literals with values, reads more clearly as an interpolated string. Code fix rewrites it; a call passing an explicit format provider is left alone so its culture is not dropped. -dotnet_diagnostic.SST2250.severity = error # A bare local declared without a value and assigned once by the next straight-line statement can be joined into an initialized declaration. Code fix joins them. -dotnet_diagnostic.SST2251.severity = error # A method call names type arguments that inference would supply. Code fix removes them. -dotnet_diagnostic.SST2252.severity = error # A `switch` statement nested inside another `switch` statement's section; lift it into a method, a `switch` expression, or a lookup. -dotnet_diagnostic.SST2254.severity = none # A target-typed `new()` is written where an explicit type reads more clearly; the code fix restores `new TypeName(...)`. Opt-in — the counterpart to SST2202's target-typed direction, so a team enables at most one. -dotnet_diagnostic.SST2255.severity = error # A hand-written null-or-empty string test. Code fix uses `string.IsNullOrEmpty`. -dotnet_diagnostic.SST2256.severity = error # An extension method called in static form. Code fix rewrites to instance form. Info. -dotnet_diagnostic.SST2257.severity = error # A lambda block body that is a single `return`. Code fix uses an expression body. Info. -dotnet_diagnostic.SST2258.severity = error # A redundant explicit delegate wrapper (`new EventHandler(M)`). Code fix drops it. Info. -dotnet_diagnostic.SST2259.severity = error # A stray `;` after a type declaration. Code fix removes it. Info. -dotnet_diagnostic.SST2260.severity = error # An `as` cast to a type the operand already has. Code fix removes it. Info. -dotnet_diagnostic.SST2261.severity = error # `(x && !y) -dotnet_diagnostic.SST2262.severity = error # A raw string literal whose content needs no raw syntax. Code fix demotes it. Info. -dotnet_diagnostic.SST2263.severity = error # An infinite loop whose body re-derives its stop condition. Code fix hoists the condition into the header. Info. -dotnet_diagnostic.SST2264.severity = error # A numeric literal cast to an enum. Code fix names the member. -dotnet_diagnostic.SST2265.severity = none # Consecutive fluent calls on one receiver can fold into a chain. Opt-in. -dotnet_diagnostic.SST2266.severity = none # A local read exactly once can be inlined into that use. Opt-in. -dotnet_diagnostic.SST2267.severity = none # Infinite loops written in mixed `while(true)`/`for(;;)` styles. Configurable. Opt-in. -dotnet_diagnostic.SST2268.severity = none # Inconsistent `()` on object creation with an initializer. Configurable. Opt-in. -dotnet_diagnostic.SST2269.severity = none # Inconsistent parentheses around a conditional's condition. Configurable. Opt-in. -dotnet_diagnostic.SST2270.severity = none # Inconsistent explicit-vs-implicit array-creation type. Configurable. Opt-in. -dotnet_diagnostic.SST2271.severity = none # `var`-vs-explicit local type per the configured preference. Configurable. Opt-in. -dotnet_diagnostic.SST2272.severity = none # `[Flags]` member values written as mixed decimals and shifts. Configurable. Opt-in. -dotnet_diagnostic.SST2273.severity = none # A function or loop body wraps its work in a trailing `if` that could be an early-exit guard clause. Code fix inverts it. Configurable threshold. Opt-in. -dotnet_diagnostic.SST2274.severity = error # A value assigned with `as` and then null-checked is an `is` declaration pattern in one step. Code fix rewrites it. -dotnet_diagnostic.SST2275.severity = error # A method whose block body is a single statement can use an expression body `=> expr`. Code fix rewrites it. -dotnet_diagnostic.SST2276.severity = error # A constructor whose block body is a single statement can use an expression body. Code fix rewrites it. -dotnet_diagnostic.SST2277.severity = error # An operator whose block body is a single `return` can use an expression body. Code fix rewrites it. -dotnet_diagnostic.SST2278.severity = error # A conversion operator whose block body is a single `return` can use an expression body. Code fix rewrites it. -dotnet_diagnostic.SST2279.severity = error # A get-only property whose getter is a single `return` can use a whole-member expression body. Code fix rewrites it. -dotnet_diagnostic.SST2280.severity = error # A get-only indexer whose getter is a single `return` can use a whole-member expression body. Code fix rewrites it. -dotnet_diagnostic.SST2281.severity = error # A local function whose block body is a single statement can use an expression body. Code fix rewrites it. -dotnet_diagnostic.SST2282.severity = error # A reference-type `ReferenceEquals` check against `null` reads as an `is null` / `is not null` pattern. Code fix rewrites it. -dotnet_diagnostic.SST2283.severity = error # A null guard that throws right before assigning the guarded value can fold into the assignment as `?? throw`. Code fix rewrites it. -dotnet_diagnostic.SST2300.severity = error # A class implements `IDisposable` but builds only half of the disposal pattern. Code fix adds the two mechanical clauses. -dotnet_diagnostic.SST2301.severity = error # A class implements `IEquatable` for itself and can still be derived from. Code fix seals the type. -dotnet_diagnostic.SST2302.severity = error # A type overloads an operator without the rest of the set that operator belongs to. -dotnet_diagnostic.SST2303.severity = error # An enum is marked `[Flags]` but its members are not distinct bit values. -dotnet_diagnostic.SST2304.severity = error # An event's delegate does not have the standard `void (object sender, TEventArgs e)` shape. -dotnet_diagnostic.SST2305.severity = error # A property whose type is a mutable collection declares a caller-visible setter. Code fix removes the setter. -dotnet_diagnostic.SST2306.severity = error # A member whose declared return type is a collection hands back `null`. Code fix returns the empty collection. -dotnet_diagnostic.SST2307.severity = error # A generic method's type parameter appears in no parameter, so no caller can infer it and every call site names it. -dotnet_diagnostic.SST2308.severity = error # An `[Obsolete]` attribute carries no message, or one that is empty or only whitespace. -dotnet_diagnostic.SST2309.severity = error # An externally visible member declares an optional parameter, so every caller that omits it compiles the default into itself. -dotnet_diagnostic.SST2310.severity = error # Deprecated code is still here. A standing reminder to remove it once its last caller is gone. -dotnet_diagnostic.SST2311.severity = error # A visible `const` is copied into every assembly that reads it, so changing its value never reaches an already-compiled caller. -dotnet_diagnostic.SST2312.severity = error # A type is declared outside any namespace. -dotnet_diagnostic.SST2313.severity = error # An enum is stored as a type the project does not allow. Configurable; defaults to `int`. -dotnet_diagnostic.SST2314.severity = error # An `[Obsolete]` explains itself but carries no `DiagnosticId`, so every caller gets the same CS0618. .NET 5+ only. -dotnet_diagnostic.SST2315.severity = error # A type creates and keeps a disposable but is not `IDisposable` - a static factory field, an auto-property `new`, or a collection of disposables. Code fix implements it. -dotnet_diagnostic.SST2316.severity = error # A type declares a public `Dispose`/`DisposeAsync` but not the matching interface, so owners that dispose through the interface never call it. `ref struct` exempt. Code fix adds the interface. -dotnet_diagnostic.SST2317.severity = error # A disposable owns a raw native handle with no finalizer, so it leaks when `Dispose` is not called. The message promotes a `SafeHandle`. -dotnet_diagnostic.SST2318.severity = none # Two methods in one type have token-identical, non-trivial bodies, usually a copy-paste that was meant to differ. Off by default. -dotnet_diagnostic.SST2319.severity = error # An optional parameter's default can never bind because a same-named overload already takes exactly its required prefix. -dotnet_diagnostic.SST2320.severity = error # An interface inherits the same member from two unrelated base interfaces, so every consumer that accesses it gets an ambiguity error. -dotnet_diagnostic.SST2321.severity = error # A class library calls `Environment.Exit` or `Environment.FailFast`, ending the whole host process instead of throwing. -dotnet_diagnostic.SST2322.severity = error # A non-private instance `readonly` field holds a mutable collection, so any caller can still add, remove, or clear its items; `readonly` freezes the reference, not the contents. -dotnet_diagnostic.SST2323.severity = error # A non-static abstract class that extends only `object` and declares nothing but public abstract members is a stateless contract better written as an interface. -dotnet_diagnostic.SST2324.severity = error # A member is declared more accessible than its containing type, so the wider modifier is dead — the container caps its reach. -dotnet_diagnostic.SST2325.severity = error # An async method checks an argument after its first await, so the guard does not throw at the call site but later, when the returned task is awaited. -dotnet_diagnostic.SST2326.severity = error # An interface-typed value is narrowed to a concrete class that implements it — via a cast, `as`, or `is` test — coupling the code to one implementation. Info. -dotnet_diagnostic.SST2327.severity = error # A type inspects its own runtime type against a specific class (`this is Derived`, `this as Derived`, or `this.GetType() == typeof(Derived)`) instead of dispatching through a virtual member. -dotnet_diagnostic.SST2328.severity = error # A visible instance field or property hands out a raw native pointer (`IntPtr`/`UIntPtr`/`nint`/`nuint`), letting callers read, write, free, or corrupt the native memory the type owns. Keep it private behind a `SafeHandle`. -dotnet_diagnostic.SST2329.severity = error # A `[Flags]` enum declares no zero-valued member. Code fix adds `None = 0`. -dotnet_diagnostic.SST2330.severity = error # A `[Flags]` member is a numeric literal equal to a combination of others (`All = 7`). Code fix writes `A -dotnet_diagnostic.SST2331.severity = none # An enum leaves member values implicit, so their numbers depend on declaration order. Opt-in. -dotnet_diagnostic.SST2332.severity = error # An auto-property's `private set` is only written during construction; make it get-only. -dotnet_diagnostic.SST2333.severity = none # A generic comparison/equality contract is implemented without its non-generic counterpart. Opt-in. -dotnet_diagnostic.SST2334.severity = none # A publicly visible type has no `[DebuggerDisplay]`. Opt-in. -dotnet_diagnostic.SST2335.severity = none # Parts of a partial type disagree on the `static` modifier. Opt-in. -dotnet_diagnostic.SST2400.severity = error # Two arguments name each other's parameters, so they have been transposed. Code fix puts them back in the parameters' order. -dotnet_diagnostic.SST2401.severity = error # A `catch` targets `NullReferenceException`, by naming it or by reaching it through a filter. -dotnet_diagnostic.SST2402.severity = error # An instance constructor assigns a static field of its own type, so the last instance built wins. -dotnet_diagnostic.SST2403.severity = error # `this` escapes a constructor — passed as an argument, stored somewhere that outlives the object, or captured in a closure handed to somebody else. -dotnet_diagnostic.SST2404.severity = error # An iterator's argument guard does not run until the first `MoveNext`. Code fix splits the validating method from the private iterator. -dotnet_diagnostic.SST2405.severity = error # A `[DebuggerDisplay]` string names a member the type neither declares nor inherits. -dotnet_diagnostic.SST2406.severity = error # A `while` or `for` condition reads only variables that nothing in the loop ever writes. -dotnet_diagnostic.SST2407.severity = error # A field-like event is declared, and nothing in the compilation ever raises it. -dotnet_diagnostic.SST2408.severity = error # A local `StringBuilder` is appended to, and its contents are never read. -dotnet_diagnostic.SST2409.severity = error # A `throw` constructs `Exception`, `SystemException`, or `ApplicationException`, which callers cannot catch selectively. -dotnet_diagnostic.SST2410.severity = error # A local is handed a newly created `IDisposable` and never disposes it, and the value never leaves the method. -dotnet_diagnostic.SST2411.severity = error # A `for` loop declares and tests a counter it never advances, so the loop runs forever or not at all. -dotnet_diagnostic.SST2412.severity = error # A `for` loop steps its counter away from the side of its bound. Code fix flips the comparison. -dotnet_diagnostic.SST2413.severity = error # A `for` loop's condition is already false at the counter's constant starting value, so its body never runs. -dotnet_diagnostic.SST2414.severity = error # Two branches of one conditional share an implementation, so one was probably meant to differ. Code fix merges duplicated switch sections. -dotnet_diagnostic.SST2415.severity = error # A non-short-circuiting `&`/` -dotnet_diagnostic.SST2416.severity = error # A remainder test against a non-zero value misses every negative on a signed type. Code fix promotes `IsOddInteger`, or `% 2 != 0`. -dotnet_diagnostic.SST2417.severity = error # An assignment is spaced like a transposed operator (`x =+ 1`). Code fix offers `x += 1` or `x = +1`. -dotnet_diagnostic.SST2418.severity = error # The result of an immutable value's method is discarded, so the call does nothing. -dotnet_diagnostic.SST2419.severity = error # A set or list operation is applied to the collection itself. -dotnet_diagnostic.SST2420.severity = error # An index-of result tested with `> 0` treats a match at the first position as not found. Code fix uses `Contains`, or `>= 0`. -dotnet_diagnostic.SST2421.severity = error # A write through a `readonly` field of an unconstrained type parameter lands on a copy and is lost. -dotnet_diagnostic.SST2422.severity = error # A property's getter reads a different field than its setter writes. Code fix points the getter at the setter's field. -dotnet_diagnostic.SST2423.severity = error # A value owned by a `using` is returned out of the `using` scope, so the caller receives an already-disposed object. Code fix transfers ownership. -dotnet_diagnostic.SST2424.severity = error # An override declares a different parameter default than the base, so the same call means different things through the base and derived types. -dotnet_diagnostic.SST2425.severity = error # An override forwards to the base but drops one of its own optional arguments, so the base substitutes its default and the caller's value is lost. -dotnet_diagnostic.SST2426.severity = error # An override's `params` modifier disagrees with the base and is ignored, so it only misleads readers. Code fix matches the base. -dotnet_diagnostic.SST2427.severity = error # A derived overload takes a base type of a same-named base overload's parameter, so calls through the derived type never reach the base overload. -dotnet_diagnostic.SST2428.severity = error # A static field initializer reads a static field declared later, so it sees that field's default and keeps it. -dotnet_diagnostic.SST2429.severity = error # A `set`, `init`, `add`, or `remove` accessor never reads `value`, so the assignment or subscription is discarded. -dotnet_diagnostic.SST2430.severity = error # A serialization callback's signature does not match the shape the serializer invokes, so it never runs. -dotnet_diagnostic.SST2431.severity = error # An overridden `ToString` can return null, which breaks interpolation, concatenation, and debugger display. Code fix returns `string.Empty`. -dotnet_diagnostic.SST2432.severity = error # `GetType()` is called on a value that is already a `Type`, returning the reflection object's runtime type. Code fix removes the call. -dotnet_diagnostic.SST2433.severity = error # A caller-info parameter is followed by an ordinary parameter, so a positional argument lands in the wrong one, or it has no default. -dotnet_diagnostic.SST2434.severity = error # A reference-type array is widened to an array of its base type, making every element write a runtime-checked store that can throw. -dotnet_diagnostic.SST2435.severity = error # A base class's value-equality `Equals` is used as an early-out fast path, so a derived override skips comparing its own fields. -dotnet_diagnostic.SST2436.severity = error # An instance event is raised with a null sender or null args, so every subscriber that reads them throws. Code fix passes `this` or `EventArgs.Empty`. -dotnet_diagnostic.SST2437.severity = error # A generic type is nested inside its own base's type arguments, which expands without end and throws `TypeLoadException` at load. -dotnet_diagnostic.SST2438.severity = error # A catch logs at error or critical level but never passes the caught exception, so the stack trace is lost. Code fix passes it. Level floor configurable. -dotnet_diagnostic.SST2439.severity = error # An exception is passed as a log message value instead of the exception argument. Code fix hoists it into the exception argument. -dotnet_diagnostic.SST2440.severity = error # Two log values named after the template placeholders sit in each other's slots. Code fix swaps them back. -dotnet_diagnostic.SST2441.severity = error # A message-template placeholder is empty, whitespace, or not a property name, so its value is dropped from the payload. -dotnet_diagnostic.SST2442.severity = error # A message template names the same placeholder twice, so one value silently overwrites the other in a structured sink. -dotnet_diagnostic.SST2443.severity = error # A typed logger's category is a type other than the one that logs, so its level filters and sink routes do nothing. Code fix rewrites the category. -dotnet_diagnostic.SST2444.severity = error # A constant regular-expression pattern does not parse, so it throws on first use. Refactoring converts a valid literal to a source-generated `[GeneratedRegex]` method. -dotnet_diagnostic.SST2445.severity = error # A custom date/time format uses an unquoted `/` or `:` with a culture-sensitive provider, so the separators change with the culture. Code fixes quote the separators or switch to the invariant culture. -dotnet_diagnostic.SST2446.severity = error # A stream read's returned byte count is awaited and discarded through a configured awaiter or a local, so a short read passes unnoticed. Code fix rewrites to `ReadExactlyAsync` where it exists. -dotnet_diagnostic.SST2448.severity = error # A combined or opaque delegate is removed with `-`/`-=`, which strips handlers only as one contiguous run, so the order they were combined in silently decides the result. -dotnet_diagnostic.SST2449.severity = error # An event or delegate handler added as a lambda or anonymous method is removed with `-=`, which never matches it, so the subscription is never removed. -dotnet_diagnostic.SST2450.severity = error # A `Debug.Assert` condition performs a side effect, so a release build compiles the call out and the work never runs. -dotnet_diagnostic.SST2451.severity = error # Every constructor of a non-static, non-abstract class is private, yet no member ever creates an instance, so the type can never exist. -dotnet_diagnostic.SST2452.severity = error # A method marked `[Pure]` returns `void`, a bare `Task`, or a bare `ValueTask`, so it has no observable result — the attribute is wrong or the method is dead. Code fix removes the attribute. -dotnet_diagnostic.SST2456.severity = error # A field-like event declared `override`, or `new` hiding an inherited event, gets its own backing delegate field, so handlers added through one type are invisible to raises through the other. -dotnet_diagnostic.SST2457.severity = error # An integer sequence `Sum` is wrapped in `unchecked`, which does not stop it throwing on overflow. -dotnet_diagnostic.SST2458.severity = error # A bitwise operator is applied to an enum not declared `[Flags]`, producing a value with no defined meaning. -dotnet_diagnostic.SST2459.severity = error # `[Optional]` on a `ref` or `out` parameter advertises an optionality no C# caller can use, while reflection reads `IsOptional` as true. Code fix removes the attribute. -dotnet_diagnostic.SST2460.severity = error # `[DefaultValue]` on a method or record parameter is inert: it does not make the parameter optional and no call site reads it. Code fix swaps it for the interop `[DefaultParameterValue]`. -dotnet_diagnostic.SST2462.severity = error # A member declared with `new` is less accessible than the inherited member it hides, so a base-typed reference still binds to the more accessible member and the reduced accessibility has no effect. -dotnet_diagnostic.SST2463.severity = error # A derived type's instance field differs from an inherited accessible field only by case, so an unqualified reference to either name compiles and silently uses the wrong storage. -dotnet_diagnostic.SST2464.severity = error # A mutable class (a settable field or property) declares a value-equality `operator ==`, so a mutated instance's hash no longer matches the bucket it was stored in and it is lost as a dictionary or hash-set key. -dotnet_diagnostic.SST2465.severity = error # A for loop's body reassigns the counter or the local its condition tests, so the loop runs a different number of times than its header states. -dotnet_diagnostic.SST2467.severity = error # A type declares a `params` overload and a same-arity overload whose last parameter is more specific than the array's element type, so a single argument of that type silently binds to the specific overload instead of the params one. -dotnet_diagnostic.SST2468.severity = error # A classic partial method is declared but never implemented, so the compiler silently removes the declaration and every call to it. -dotnet_diagnostic.SST2470.severity = error # Two string literals concatenate with no space between them, fusing a SQL keyword into the adjacent token so the query changes at runtime. Code fix adds a space to a regular right literal. -dotnet_diagnostic.SST2472.severity = error # A type is exported for a contract (`[Export(typeof(IFoo))]`) it neither implements nor inherits, so the container cannot supply it for that contract. -dotnet_diagnostic.SST2473.severity = error # A `new` expression constructs a type that is itself a shared export part, bypassing the container and its single-instance guarantee. -dotnet_diagnostic.SST2474.severity = error # A part-creation-policy attribute is applied to a type with no `[Export]`, so it governs nothing. -dotnet_diagnostic.SST2475.severity = error # An entity's primary key is typed `DateTime` or `DateTimeOffset`, so keys collide within a tick, are not stable identifiers, cluster the table by insertion time, and round-trip imprecisely across providers. -dotnet_diagnostic.SST2479.severity = error # A for/while/do loop variable captured by a lambda, anonymous method, or local function that is stored beyond the iteration reads its final value on every deferred call. -dotnet_diagnostic.SST2481.severity = error # A `GetHashCode` override folds the base object identity hash into a value hash, so two value-equal instances hash differently and are lost in any hash-based collection. -dotnet_diagnostic.SST2484.severity = error # A raw handle read through `SafeHandle.DangerousGetHandle()` is not reference-counted, so a concurrent dispose or finalize can recycle the value and it is used after free. -dotnet_diagnostic.SST2485.severity = error # A member throws `new NotImplementedException`, a stub that compiles but crashes at runtime on any path that reaches it. `NotSupportedException` is left alone. -dotnet_diagnostic.SST2486.severity = error # An assembly is loaded through `Assembly.LoadFrom`, `LoadFile`, or `LoadWithPartialName` instead of `Assembly.Load` with a full display name; a code fix swaps `LoadWithPartialName` to `Assembly.Load`. -dotnet_diagnostic.SST2487.severity = error # A `[ConstructorArgument]` names no parameter of any constructor of its declaring type, so a markup extension cannot round-trip the property back to a constructor argument. -dotnet_diagnostic.SST2488.severity = error # A catch logs the caught exception and then rethrows it with a bare `throw;`, so the same failure is recorded here and again where it is finally handled. -dotnet_diagnostic.SST2489.severity = error # A relational comparison an integer operand's type already decides — an unsigned value `>= 0` (always true) or `< 0` (always false), or a value at its type's min/max edge such as `b <= 255` for a `byte`. -dotnet_diagnostic.SST2490.severity = error # Two adjacent `try` statements in the same block repeat the same catch/finally handling, so the pair can collapse into one `try` wrapping both bodies. -dotnet_diagnostic.SST2491.severity = error # A non-`async` method returns an awaitable from inside `using`/`try-finally`/`lock`, so the resource is torn down before the task completes. Code fix makes it `async`. -dotnet_diagnostic.SST2492.severity = error # A null-guard throws on a parameter the signature declares may be null. -dotnet_diagnostic.SST2493.severity = error # `== null`/`!= null` on an unconstrained generic `T`. Code fix uses `is null`/`is not null`. -dotnet_diagnostic.SST2494.severity = error # A `??` whose left operand is a constant null, so the right is always taken. Code fix folds it. -dotnet_diagnostic.SST2495.severity = error # A `[Flags]` combination includes an operand whose bits another already covers. Code fix removes it. -dotnet_diagnostic.SST2496.severity = error # An explicit `Dispose`/`Close` on a resource an enclosing `using` already disposes. Code fix removes it. Info. -dotnet_diagnostic.SST2500.severity = error # A test method carrying a test attribute contains no assertion and no expected-exception check, so it always passes without verifying anything. Reported only when every call in the body resolves to a non-verifying platform (BCL) API (or there are none); any user or third-party call keeps it silent. -dotnet_diagnostic.SST2501.severity = error # An equality or identity assertion compares an expression with itself, so a positive assertion always passes and a negated one always fails, verifying nothing. Covers xUnit, NUnit (classic and `Assert.That`), and MSTest. -dotnet_diagnostic.SST2502.severity = error # An equality assertion is passed a constant as its actual argument and a computed value as its expected, so a failure reports them the wrong way round. Code fix swaps the two arguments. -dotnet_diagnostic.SST2503.severity = error # An equality assertion compares a value against a boolean literal (`Assert.Equal(true, x)` / `Assert.AreEqual(true, x)`), obscuring intent and giving a worse failure message. Code fix rewrites it to the framework's boolean assertion. -dotnet_diagnostic.SST2504.severity = error # A concrete class marked as a test fixture (MSTest test-class or NUnit test-fixture) declares no test method of its own and inherits none, so the runner loads it but never runs anything. -dotnet_diagnostic.SST2505.severity = error # A test method declares parameters but no data source, so the runner cannot supply arguments and the test silently never runs. -dotnet_diagnostic.SST2506.severity = error # A test method calls `Thread.Sleep`, spending a fixed real-time delay on every run that slows the suite and races the wall clock, a classic flaky-test source. -dotnet_diagnostic.SST2507.severity = error # A test method declares its expected failure with an expected-exception attribute instead of asserting the specific operation, so any statement in the whole method throwing that type passes the test. -dotnet_diagnostic.SST2508.severity = error # A fluent assertion names its subject with a bare `Should()` statement but chains no check, so it compiles, runs, and passes while verifying nothing. Gated on FluentAssertions/AwesomeAssertions. -dotnet_diagnostic.SST2509.severity = error # A method carrying a test attribute has a signature the runner cannot execute — non-public, a parameterless generic, or a return type other than `void`/`Task`/`ValueTask` — so it is discovered and then silently skipped. -dotnet_diagnostic.SST2600.severity = error # Application output is written through `Trace.Write`/`WriteLine`/`WriteIf`/`WriteLineIf` when a structured logger (`ILogger`) is available, so the message loses its level, category, and named state. Reported only when `ILogger` resolves; `Debug.*` is excluded. -dotnet_diagnostic.SST2601.severity = error # An `ILogger`/`ILogger` field or property is named against the logger convention (`_logger`/`_log` for a private instance one, `Logger` otherwise). Configurable via `stylesharp.SST2601.fieldname`. -dotnet_diagnostic.SST2700.severity = error # An MVC route template contains a backslash; route segments are separated by `/`, so the route is unreachable. Code fix replaces `\` with `/`. -dotnet_diagnostic.SST2701.severity = error # A `[JSInvokable]` method is not public, so JavaScript interop cannot call it. Code fix makes it public. -dotnet_diagnostic.SST2702.severity = error # A `[SupplyParameterFromQuery]` property has a type the framework cannot bind from the query string, which throws at runtime. -dotnet_diagnostic.SST2703.severity = error # A routable component's route constraint (`{id:int}`) disagrees with the matching `[Parameter]` CLR type, so the route silently fails to match. -dotnet_diagnostic.SST2704.severity = error # A public action on an `[ApiController]` declares no HTTP-verb attribute, so it answers every verb and can make routing ambiguous. -dotnet_diagnostic.SST2705.severity = none # A bound model member is a non-nullable value type with no required marker, so a request that omits it binds the default with no error. Opt-in. -dotnet_diagnostic.SST2706.severity = error # A Windows Forms entry point carries neither `[STAThread]` nor `[MTAThread]`; without STA, clipboard, drag-and-drop, and common dialogs misbehave. Code fix adds `[STAThread]`. -dotnet_diagnostic.SST2707.severity = none # A fire-and-forget `Task.Run` in a controller captures the request's `HttpContext`, which is disposed when the request ends, so the background work throws `ObjectDisposedException`. Opt-in. -dotnet_diagnostic.SST2708.severity = error # A component subscribes to an event in a lifecycle method but never unsubscribes, so the event source keeps the component alive — a per-session leak on a Server circuit. -dotnet_diagnostic.SST2709.severity = error # `StateHasChanged` is called while the component is being disposed, which the renderer no longer supports and throws. -dotnet_diagnostic.SST2710.severity = error # `StateHasChanged` is called directly from a timer callback, off the renderer's dispatcher; marshal it with `InvokeAsync(StateHasChanged)`. -dotnet_diagnostic.SST2711.severity = error # A synchronous component lifecycle method is overridden as `async void`, which the framework never awaits; override the `…Async` twin returning `Task`. Code fix rewrites the signature. -dotnet_diagnostic.SST2712.severity = error # An `[Inject]`/`[CascadingParameter]` property has no setter, so the framework's reflection-based binding leaves it null. Code fix adds a setter. -dotnet_diagnostic.SST2713.severity = error # A `DotNetObjectReference.Create(this)` is passed inline and never stored, so nothing can dispose it and it leaks on the JavaScript side. - -# In-box IDE code-style rules disabled where a StyleSharp rule covers the same shape (avoids double-reporting under EnforceCodeStyleInBuild) -dotnet_diagnostic.IDE0001.severity = none # covered by SST1116 -dotnet_diagnostic.IDE0003.severity = none # covered by SST1117 -dotnet_diagnostic.IDE0005.severity = none # covered by SST1445 -dotnet_diagnostic.IDE0010.severity = none # covered by SST2205 -dotnet_diagnostic.IDE0011.severity = none # covered by SST1503 -dotnet_diagnostic.IDE0017.severity = none # covered by SST1193 -dotnet_diagnostic.IDE0018.severity = none # covered by SST2208 -dotnet_diagnostic.IDE0020.severity = none # covered by SST2007 -dotnet_diagnostic.IDE0027.severity = none # covered by SST2219 -dotnet_diagnostic.IDE0029.severity = none # covered by SST1195 -dotnet_diagnostic.IDE0030.severity = none # covered by SST1195 -dotnet_diagnostic.IDE0032.severity = none # covered by SST1420 -dotnet_diagnostic.IDE0033.severity = none # covered by SST1142 -dotnet_diagnostic.IDE0034.severity = none # covered by SST1188 -dotnet_diagnostic.IDE0036.severity = none # covered by SST1206 -dotnet_diagnostic.IDE0037.severity = none # covered by SST2216 -dotnet_diagnostic.IDE0039.severity = none # covered by SST2228 -dotnet_diagnostic.IDE0040.severity = none # covered by SST1400 -dotnet_diagnostic.IDE0045.severity = none # covered by SST1198 -dotnet_diagnostic.IDE0046.severity = none # covered by SST1197 -dotnet_diagnostic.IDE0051.severity = none # covered by SST1440 -dotnet_diagnostic.IDE0053.severity = none # covered by SST2257 -dotnet_diagnostic.IDE0054.severity = none # covered by SST1185 -dotnet_diagnostic.IDE0056.severity = none # covered by SST2203 -dotnet_diagnostic.IDE0062.severity = none # covered by SST2235 -dotnet_diagnostic.IDE0063.severity = none # covered by SST2236 -dotnet_diagnostic.IDE0065.severity = none # covered by SST1200 -dotnet_diagnostic.IDE0070.severity = none # covered by SST2217 -dotnet_diagnostic.IDE0071.severity = none # covered by SST2220 -dotnet_diagnostic.IDE0072.severity = none # covered by SST2206 -dotnet_diagnostic.IDE0073.severity = none # covered by SST1633 -dotnet_diagnostic.IDE0074.severity = none # covered by SST2223 -dotnet_diagnostic.IDE0076.severity = none # covered by SST1457 -dotnet_diagnostic.IDE0077.severity = none # covered by SST1458 -dotnet_diagnostic.IDE0080.severity = none # covered by SST2209 -dotnet_diagnostic.IDE0082.severity = none # covered by SST1199 -dotnet_diagnostic.IDE0083.severity = none # covered by SST2006 -dotnet_diagnostic.IDE0090.severity = none # covered by SST2202 -dotnet_diagnostic.IDE0100.severity = none # covered by SST1143 -dotnet_diagnostic.IDE0110.severity = none # covered by SST2213 -dotnet_diagnostic.IDE0150.severity = none # covered by SST2231 -dotnet_diagnostic.IDE0161.severity = none # covered by SST2237 -dotnet_diagnostic.IDE0170.severity = none # covered by SST2238 -dotnet_diagnostic.IDE0180.severity = none # covered by SST2215 -dotnet_diagnostic.IDE0200.severity = none # covered by SST2239 -dotnet_diagnostic.IDE0220.severity = none # covered by SST2225 -dotnet_diagnostic.IDE0230.severity = none # covered by SST2212 -dotnet_diagnostic.IDE0240.severity = none # covered by SST2210 -dotnet_diagnostic.IDE0241.severity = none # covered by SST2211 -dotnet_diagnostic.IDE0251.severity = none # covered by SST1460 -dotnet_diagnostic.IDE0270.severity = none # covered by SST1195 -dotnet_diagnostic.IDE0280.severity = none # covered by SST1463 -dotnet_diagnostic.IDE0290.severity = none # covered by SST2241 -dotnet_diagnostic.IDE0301.severity = none # covered by SST2100 -dotnet_diagnostic.IDE0302.severity = none # covered by SST2102 -dotnet_diagnostic.IDE0303.severity = none # covered by SST2103 -dotnet_diagnostic.IDE0304.severity = none # covered by SST2104 -dotnet_diagnostic.IDE0305.severity = none # covered by SST2105 -dotnet_diagnostic.IDE0340.severity = none # covered by SST2232 -dotnet_diagnostic.IDE0350.severity = none # covered by SST2218 -dotnet_diagnostic.IDE0380.severity = none # covered by SST1455 -dotnet_diagnostic.IDE1005.severity = none # covered by SST2240 dotnet_diagnostic.S3059.severity = none # Types should not have members with visibility set higher than the type's visibility dotnet_diagnostic.S3063.severity = none # "StringBuilder" data should be used — covered by SST2408 dotnet_diagnostic.S3169.severity = none # Multiple "OrderBy" calls should not be used — covered by PSH1108 @@ -2465,9 +2478,7 @@ dotnet_diagnostic.S6968.severity = none # Actions that return a value should be dotnet_diagnostic.S881.severity = none # Increment (++) and decrement (--) operators should not be used in a method call or mixed with other operators in an expression — covered by SST2015 dotnet_diagnostic.S907.severity = none # "goto" statement should not be used — covered by SST2014 -################### -# SonarAnalyzer (Sxxxx) - Minor Code Smell -################### +# Minor code smells dotnet_diagnostic.S100.severity = none # Methods and properties should be named in PascalCase — covered by SST1300 dotnet_diagnostic.S101.severity = none # Types should be named in PascalCase — covered by SST1300 dotnet_diagnostic.S105.severity = none # Tabulation characters should not be used — covered by SST1027 @@ -2573,6 +2584,7 @@ dotnet_diagnostic.S4663.severity = none # Covered by SST1120 (canonical) dotnet_diagnostic.S6513.severity = none # "ExcludeFromCodeCoverage" attributes should include a justification - not available on net462 and older TFMs dotnet_diagnostic.S6585.severity = none # Don't hardcode the format when turning dates and times to strings — covered by SST2445 dotnet_diagnostic.S6588.severity = none # Use the "UnixEpoch" field instead of creating "DateTime" instances that point to the beginning of the Unix epoch — covered by PSH1413 +dotnet_diagnostic.S6594.severity = none # Covered by PSH1406 (canonical) dotnet_diagnostic.S6602.severity = none # Covered by PSH1110 (canonical) dotnet_diagnostic.S6603.severity = none # Covered by PSH1110 (canonical) dotnet_diagnostic.S6605.severity = none # Covered by PSH1110 (canonical) @@ -2594,16 +2606,12 @@ dotnet_diagnostic.S6675.severity = none # "Trace.WriteLineIf" should not be used dotnet_diagnostic.S6678.severity = none # Use PascalCase for named placeholders -> replaced by CA1727 dotnet_diagnostic.S818.severity = none # Literal suffixes should be upper case — covered by SST2244 -################### -# SonarAnalyzer (Sxxxx) - Info Code Smell -################### +# Informational code smells dotnet_diagnostic.S1133.severity = none # Deprecated code should be removed — covered by SST2310 dotnet_diagnostic.S1135.severity = none # Track uses of "TODO" tags -> off: FIXME comment tracker; not enforced here dotnet_diagnostic.S1309.severity = none # Track uses of in-source issue suppressions -################### -# SonarAnalyzer (Sxxxx) - Uncategorized -################### +# Uncategorized dotnet_diagnostic.S9999-cpd.severity = error # Copy-paste token calculator dotnet_diagnostic.S9999-log.severity = error # Log generator dotnet_diagnostic.S9999-metadata.severity = error # File metadata generator @@ -2614,9 +2622,7 @@ dotnet_diagnostic.S9999-testMethodDeclaration.severity = error # Test method dec dotnet_diagnostic.S9999-token-type.severity = error # Token type calculator dotnet_diagnostic.S9999-warning.severity = error # Analysis Warning generator -################### -# SonarAnalyzer (Sxxxx) - Critical Security Hotspot -################### +# Critical security hotspots dotnet_diagnostic.S2245.severity = none # Using pseudorandom number generators (PRNGs) is security-sensitive - DUPLICATE CA5394 dotnet_diagnostic.S2257.severity = none # Using non-standard cryptographic algorithms is security-sensitive -> replaced by SES1007 dotnet_diagnostic.S4502.severity = none # Disabling CSRF protections is security-sensitive -> replaced by in-box ASP.NET antiforgery analyzer @@ -2626,9 +2632,7 @@ dotnet_diagnostic.S5042.severity = none # Expanding archive files without contro dotnet_diagnostic.S5332.severity = none # Using clear-text protocols is security-sensitive -> replaced by SES1106 dotnet_diagnostic.S5443.severity = none # Using publicly writable directories is security-sensitive -> replaced by SES1308 -################### -# SonarAnalyzer (Sxxxx) - Major Security Hotspot -################### +# Major security hotspots dotnet_diagnostic.S1313.severity = none # Using hardcoded IP addresses is security-sensitive -> off: hardcoded-IP heuristic; too noisy to enforce dotnet_diagnostic.S2077.severity = none # Formatting SQL queries is security-sensitive -> replaced by CA2100 dotnet_diagnostic.S5693.severity = none # Allowing requests with excessive content length is security-sensitive -> replaced by SES1505 @@ -2637,9 +2641,7 @@ dotnet_diagnostic.S5766.severity = none # Creating Serializable objects without dotnet_diagnostic.S6444.severity = none # Not specifying a timeout for regular expressions is security-sensitive -> replaced by SES1509 dotnet_diagnostic.S6640.severity = none # Using unsafe code blocks is security-sensitive -> off: unsafe-code audit; not enforced here -################### -# SonarAnalyzer (Sxxxx) - Minor Security Hotspot -################### +# Minor security hotspots dotnet_diagnostic.S2092.severity = none # Creating cookies without the "secure" flag is security-sensitive -> replaced by CA5382 dotnet_diagnostic.S3330.severity = none # Creating cookies without the "HttpOnly" flag is security-sensitive -> replaced by CA5383 dotnet_diagnostic.S4507.severity = none # Delivering code in production with debug features activated is security-sensitive -> off: debug features in production; partly covered by SES1506, rest not enforced @@ -2826,8 +2828,7 @@ indent_size = 2 end_of_line = lf [*.{cmd, bat}] -end_of_line = crlf - +end_of_line = lf ############################################# # Test projects (TUnit) @@ -2835,11 +2836,3 @@ end_of_line = crlf # TUnit instantiates test classes per test, so they must remain instance classes and # cannot be marked static — even when a partial declaration happens to hold only static # members (the instance [Test] methods live in sibling partial files). -[**/tests/**/*.cs] -stylesharp.avoid_linq_on_hot_path = false -dotnet_diagnostic.SST2229.severity = error # In tests, simplify LINQ Where plus terminal calls instead of banning LINQ -dotnet_diagnostic.SST2230.severity = error # In tests, simplify LINQ type filters instead of banning LINQ -dotnet_diagnostic.SST2233.severity = none # Tests can use LINQ for clarity -dotnet_diagnostic.SST1432.severity = none -dotnet_diagnostic.RCS1072.severity = none # covered by SST1435 -dotnet_diagnostic.RCS1106.severity = none # covered by SST1434 diff --git a/.gitattributes b/.gitattributes index 65c99cd934..caca73818a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,11 +1,11 @@ -# Auto-detect text files and normalise line endings to LF in the repository. -* text=auto +# Auto-detect text files and use LF in both the repository and working tree. +* text=auto eol=lf # Source code *.cs text diff=csharp *.xaml text *.slnx text -*.sln text eol=crlf +*.sln text eol=lf *.csproj text *.props text *.targets text @@ -17,8 +17,8 @@ *.txt text *.sh text eol=lf *.ps1 text -*.cmd text eol=crlf -*.bat text eol=crlf +*.cmd text eol=lf +*.bat text eol=lf *.config text *.editorconfig text diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 0d1ca1c222..e3585ebcda 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -5,9 +5,9 @@ - 20.0.0 + 20.2.0 7.0.0 - 1.61.15 + 1.61.38 3.38.1 @@ -15,17 +15,17 @@ - 10.0.80 - 11.0.0-preview.5.26304.4 + 10.0.90 + 11.0.0-preview.6.26360.8 3.1.32 8.0.29 9.0.18 10.0.10 - 11.0.0-preview.5.26302.115 + 11.0.0-preview.6.26359.118 10.0.10 - 11.0.0-preview.5.26302.115 + 11.0.0-preview.6.26359.118 @@ -88,7 +88,7 @@ - + @@ -100,6 +100,7 @@ + @@ -109,14 +110,14 @@ - + - + diff --git a/src/Polyfills/DynamicallyAccessedMemberTypes.cs b/src/Polyfills/DynamicallyAccessedMemberTypes.cs index ec774e98d7..f2b79bd602 100644 --- a/src/Polyfills/DynamicallyAccessedMemberTypes.cs +++ b/src/Polyfills/DynamicallyAccessedMemberTypes.cs @@ -25,10 +25,6 @@ internal enum DynamicallyAccessedMemberTypes PublicParameterlessConstructor = 0x0001, /// Specifies all public constructors. - [SuppressMessage( - "Roslynator", - "RCS1157:Composite enum value contains undefined flag", - Justification = "Faithful BCL polyfill.")] PublicConstructors = 0x0002 | PublicParameterlessConstructor, /// Specifies all non-public constructors. diff --git a/src/Polyfills/DynamicallyAccessedMembersAttribute.cs b/src/Polyfills/DynamicallyAccessedMembersAttribute.cs index a6d9904774..67f2c9f3ea 100644 --- a/src/Polyfills/DynamicallyAccessedMembersAttribute.cs +++ b/src/Polyfills/DynamicallyAccessedMembersAttribute.cs @@ -12,15 +12,15 @@ namespace System.Diagnostics.CodeAnalysis; [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage( - validOn: Targets.Class | - Targets.Field | - Targets.GenericParameter | - Targets.Interface | - Targets.Method | - Targets.Parameter | - Targets.Property | - Targets.ReturnValue | - Targets.Struct, + validOn: Targets.Class + | Targets.Field + | Targets.GenericParameter + | Targets.Interface + | Targets.Method + | Targets.Parameter + | Targets.Property + | Targets.ReturnValue + | Targets.Struct, Inherited = false)] [SuppressMessage( "Design", diff --git a/src/Polyfills/MemberNotNullAttribute.cs b/src/Polyfills/MemberNotNullAttribute.cs index df98ec9b7e..987a296d3e 100644 --- a/src/Polyfills/MemberNotNullAttribute.cs +++ b/src/Polyfills/MemberNotNullAttribute.cs @@ -12,14 +12,10 @@ [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage( - validOn: Targets.Method | - Targets.Property, + validOn: Targets.Method + | Targets.Property, Inherited = false, AllowMultiple = true)] -[SuppressMessage( - "Design", - "CA1019:Define accessors for attribute arguments", - Justification = "Faithful BCL polyfill.")] [SuppressMessage( "Design", "SST2312:Types should be declared in a named namespace", diff --git a/src/Polyfills/NotNullAttribute.cs b/src/Polyfills/NotNullAttribute.cs index 088f448b16..722091405d 100644 --- a/src/Polyfills/NotNullAttribute.cs +++ b/src/Polyfills/NotNullAttribute.cs @@ -13,9 +13,9 @@ namespace System.Diagnostics.CodeAnalysis; [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage( - validOn: AttributeTargets.Field | - AttributeTargets.Parameter | - AttributeTargets.Property | - AttributeTargets.ReturnValue)] + validOn: AttributeTargets.Field + | AttributeTargets.Parameter + | AttributeTargets.Property + | AttributeTargets.ReturnValue)] internal sealed class NotNullAttribute : Attribute; #endif diff --git a/src/Polyfills/RequiresDynamicCodeAttribute.cs b/src/Polyfills/RequiresDynamicCodeAttribute.cs index 5b5d113bd8..15cd96f9ea 100644 --- a/src/Polyfills/RequiresDynamicCodeAttribute.cs +++ b/src/Polyfills/RequiresDynamicCodeAttribute.cs @@ -14,9 +14,9 @@ namespace System.Diagnostics.CodeAnalysis; [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage( - validOn: Targets.Method | - Targets.Constructor | - Targets.Class, + validOn: Targets.Method + | Targets.Constructor + | Targets.Class, Inherited = false)] [SuppressMessage( "Design", diff --git a/src/Polyfills/RequiresUnreferencedCodeAttribute.cs b/src/Polyfills/RequiresUnreferencedCodeAttribute.cs index c08a757d72..3528f41c2e 100644 --- a/src/Polyfills/RequiresUnreferencedCodeAttribute.cs +++ b/src/Polyfills/RequiresUnreferencedCodeAttribute.cs @@ -16,9 +16,9 @@ namespace System.Diagnostics.CodeAnalysis; [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage( - AttributeTargets.Method | - AttributeTargets.Constructor | - AttributeTargets.Class, + AttributeTargets.Method + | AttributeTargets.Constructor + | AttributeTargets.Class, Inherited = false)] [SuppressMessage( "Design", diff --git a/src/ReactiveUI.AndroidX/ActivityResultAwaiter.cs b/src/ReactiveUI.AndroidX/ActivityResultAwaiter.cs index 5307416870..547d17fdfd 100644 --- a/src/ReactiveUI.AndroidX/ActivityResultAwaiter.cs +++ b/src/ReactiveUI.AndroidX/ActivityResultAwaiter.cs @@ -16,8 +16,7 @@ namespace ReactiveUI.AndroidX; /// allocation-light replacement for Where(...).Select(...).FirstAsync().ToTask(): it is its own observer, /// settles exactly once, and unsubscribes on completion. Shared by the AppCompat and Fragment reactive activities. /// -internal sealed class ActivityResultAwaiter - : IObserver<(int requestCode, Result result, Intent? intent)>, IDisposable +internal sealed class ActivityResultAwaiter : IObserver<(int requestCode, Result result, Intent? intent)>, IDisposable { /// The request code this awaiter is waiting for. private readonly int _requestCode; diff --git a/src/ReactiveUI.Blazor/Internal/ReactiveComponentState.cs b/src/ReactiveUI.Blazor/Internal/ReactiveComponentState.cs index 66376056c7..9816fc940b 100644 --- a/src/ReactiveUI.Blazor/Internal/ReactiveComponentState.cs +++ b/src/ReactiveUI.Blazor/Internal/ReactiveComponentState.cs @@ -3,8 +3,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Diagnostics.CodeAnalysis; - #if REACTIVE_SHIM namespace ReactiveUI.Reactive.Blazor.Internal; #else @@ -68,10 +66,6 @@ internal sealed class ReactiveComponentState : IDisposable /// Use this to register subscriptions that should live for the entire component lifetime. /// All subscriptions added here will be disposed when the component is disposed. /// - [SuppressMessage( - "Style", - "RCS1085:Use auto-implemented property", - Justification = "Explicit field backing provides clarity and follows established pattern in this class.")] internal MultipleDisposable LifetimeDisposables => _lifetimeDisposables; /// Gets or sets the disposable for first-render-only subscriptions. @@ -85,10 +79,6 @@ internal sealed class ReactiveComponentState : IDisposable /// auto-property so it can dispose the previous subscription on assignment. /// /// - [SuppressMessage( - "Style", - "RCS1085:Use auto-implemented property", - Justification = "Intentional wrapper for SerialDisposable.Disposable property to ensure proper disposal semantics.")] internal IDisposable? FirstRenderSubscriptions { get => _firstRenderSubscriptions; diff --git a/src/ReactiveUI.Blazor/ReactiveInjectableComponentBase.cs b/src/ReactiveUI.Blazor/ReactiveInjectableComponentBase.cs index c82a6d9fb2..36ac18636f 100644 --- a/src/ReactiveUI.Blazor/ReactiveInjectableComponentBase.cs +++ b/src/ReactiveUI.Blazor/ReactiveInjectableComponentBase.cs @@ -32,8 +32,7 @@ namespace ReactiveUI.Blazor; /// The is provided via DI using . /// /// -public class ReactiveInjectableComponentBase - : ComponentBase, IViewFor, INotifyPropertyChanged, IDisposable, ICanActivate +public class ReactiveInjectableComponentBase : ComponentBase, IViewFor, INotifyPropertyChanged, IDisposable, ICanActivate where T : class, INotifyPropertyChanged { /// Encapsulates reactive state and lifecycle management for this component. diff --git a/src/ReactiveUI.Blazor/ReactiveLayoutComponentBase.cs b/src/ReactiveUI.Blazor/ReactiveLayoutComponentBase.cs index 52188a7dd2..1202618029 100644 --- a/src/ReactiveUI.Blazor/ReactiveLayoutComponentBase.cs +++ b/src/ReactiveUI.Blazor/ReactiveLayoutComponentBase.cs @@ -31,8 +31,7 @@ namespace ReactiveUI.Blazor; /// /// [SuppressMessage("Usage", "BL0007:Component parameters should be auto properties", Justification = "Needed for design of the properties")] -public class ReactiveLayoutComponentBase - : LayoutComponentBase, IViewFor, INotifyPropertyChanged, IDisposable, ICanActivate +public class ReactiveLayoutComponentBase : LayoutComponentBase, IViewFor, INotifyPropertyChanged, IDisposable, ICanActivate where T : class, INotifyPropertyChanged { /// Encapsulates reactive state and lifecycle management for this component. diff --git a/src/ReactiveUI.Blazor/ReactiveOwningComponentBase.cs b/src/ReactiveUI.Blazor/ReactiveOwningComponentBase.cs index 75f18dcc8c..f3705b9744 100644 --- a/src/ReactiveUI.Blazor/ReactiveOwningComponentBase.cs +++ b/src/ReactiveUI.Blazor/ReactiveOwningComponentBase.cs @@ -35,8 +35,7 @@ namespace ReactiveUI.Blazor; /// /// [SuppressMessage("Usage", "BL0007:Component parameters should be auto properties", Justification = "Needed for design of the properties")] -public class ReactiveOwningComponentBase - : OwningComponentBase, IViewFor, INotifyPropertyChanged, ICanActivate +public class ReactiveOwningComponentBase : OwningComponentBase, IViewFor, INotifyPropertyChanged, ICanActivate where T : class, INotifyPropertyChanged { /// Encapsulates reactive state and lifecycle management for this component. diff --git a/src/ReactiveUI.Core/Bindings/BindingTypeConverterDispatch.cs b/src/ReactiveUI.Core/Bindings/BindingTypeConverterDispatch.cs index 8922064ab4..6f8fc98dcd 100644 --- a/src/ReactiveUI.Core/Bindings/BindingTypeConverterDispatch.cs +++ b/src/ReactiveUI.Core/Bindings/BindingTypeConverterDispatch.cs @@ -108,8 +108,8 @@ internal static bool TryConvert( var runtimeType = from.GetType(); var converterFromType = converter.FromType; - if (converterFromType != runtimeType && - Nullable.GetUnderlyingType(converterFromType) != runtimeType) + if (converterFromType != runtimeType + && Nullable.GetUnderlyingType(converterFromType) != runtimeType) { result = null; return false; diff --git a/src/ReactiveUI.Core/Bindings/Command/CommandBinderImplementationMixins.cs b/src/ReactiveUI.Core/Bindings/Command/CommandBinderImplementationMixins.cs index f564b0cae1..35f3abfcce 100644 --- a/src/ReactiveUI.Core/Bindings/Command/CommandBinderImplementationMixins.cs +++ b/src/ReactiveUI.Core/Bindings/Command/CommandBinderImplementationMixins.cs @@ -45,9 +45,9 @@ internal IReactiveBinding BindCommand< TView, TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl>( TViewModel? viewModel, TView view, diff --git a/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBinding.cs b/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBinding.cs index eb3fb1e6a6..47f78a63e8 100644 --- a/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBinding.cs +++ b/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBinding.cs @@ -27,9 +27,9 @@ public static class CreatesCommandBinding /// Thrown if a suitable command binder cannot be found for the specified target type. [RequiresUnreferencedCode("String/reflection-based event binding may require members removed by trimming.")] public static IDisposable BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl>(ICommand? command, TControl? target, IObservable commandParameter) where TControl : class { @@ -61,9 +61,9 @@ public static IDisposable BindCommandToObject< "SST2307:A generic method's type parameter appears in no parameter, so no caller can infer it", Justification = "Generic type parameter is supplied explicitly by the caller by design; it identifies the target type and cannot be inferred from the method's parameters.")] public static IDisposable BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TEventArgs>( ICommand? command, TControl? target, @@ -83,9 +83,9 @@ public static IDisposable BindCommandToObject< /// An instance of ICreatesCommandBinding that is best suited for the specified target type. /// Thrown if no suitable command binding provider can be found for the specified target type. private static ICreatesCommandBinding GetBinder< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] T>(bool hasEventTarget) { var bestScore = 0; diff --git a/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBindingViaCommandParameter.cs b/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBindingViaCommandParameter.cs index d94db2cd9b..7834f96726 100644 --- a/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBindingViaCommandParameter.cs +++ b/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBindingViaCommandParameter.cs @@ -36,8 +36,8 @@ public sealed class CreatesCommandBindingViaCommandParameter : ICreatesCommandBi /// Otherwise, it returns 5 if the target type exposes the required public instance properties; otherwise it returns 0. /// public int GetAffinityForObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] T>(bool hasEventTarget) { if (hasEventTarget) @@ -66,9 +66,9 @@ public int GetAffinityForObject< /// [RequiresUnreferencedCode("String/reflection-based event binding may require members removed by trimming.")] public IDisposable? BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T>( ICommand? command, T? target, @@ -120,9 +120,9 @@ public IDisposable? BindCommandToObject< /// should be used. This method therefore returns . /// public IDisposable? BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T, TEventArgs>( ICommand? command, T? target, @@ -196,15 +196,15 @@ private static void ResolveProperties( var p = properties[i]; var name = p.Name; - if (command is null && - string.Equals(name, CommandPropertyName, StringComparison.Ordinal)) + if (command is null + && string.Equals(name, CommandPropertyName, StringComparison.Ordinal)) { command = p; continue; } - if (commandParameter is null && - string.Equals(name, CommandParameterPropertyName, StringComparison.Ordinal)) + if (commandParameter is null + && string.Equals(name, CommandParameterPropertyName, StringComparison.Ordinal)) { commandParameter = p; } diff --git a/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBindingViaEvent.cs b/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBindingViaEvent.cs index c7e14c580d..98a0c8fd97 100644 --- a/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBindingViaEvent.cs +++ b/src/ReactiveUI.Core/Bindings/Command/CreatesCommandBindingViaEvent.cs @@ -28,8 +28,8 @@ public sealed class CreatesCommandBindingViaEvent : ICreatesCommandBinding /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public int GetAffinityForObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] T>(bool hasEventTarget) { if (hasEventTarget) @@ -52,9 +52,9 @@ public int GetAffinityForObject< /// [RequiresUnreferencedCode("String/reflection-based event binding may require members removed by trimming.")] public IDisposable? BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T>( ICommand? command, T? target, @@ -149,9 +149,9 @@ public IDisposable? BindCommandToObject< /// Thrown when , , or is . /// public IDisposable BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T, TEventArgs>( ICommand? command, T? target, diff --git a/src/ReactiveUI.Core/Bindings/Command/ICommandBinderImplementation.cs b/src/ReactiveUI.Core/Bindings/Command/ICommandBinderImplementation.cs index cc616219a1..faf8f1b612 100644 --- a/src/ReactiveUI.Core/Bindings/Command/ICommandBinderImplementation.cs +++ b/src/ReactiveUI.Core/Bindings/Command/ICommandBinderImplementation.cs @@ -44,9 +44,9 @@ IReactiveBinding BindCommand< TView, TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, @@ -88,9 +88,9 @@ IReactiveBinding BindCommand< TView, TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, @@ -134,9 +134,9 @@ IReactiveBinding BindCommand< TView, TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, @@ -178,9 +178,9 @@ IReactiveBinding BindCommand< TView, TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, diff --git a/src/ReactiveUI.Core/ChangeSets/ReactiveChange.cs b/src/ReactiveUI.Core/ChangeSets/ReactiveChange.cs index 5b35bdc3b2..8bb0e62959 100644 --- a/src/ReactiveUI.Core/ChangeSets/ReactiveChange.cs +++ b/src/ReactiveUI.Core/ChangeSets/ReactiveChange.cs @@ -57,11 +57,11 @@ public ReactiveChange(ReactiveChangeReason reason, T current, T? previous, int c /// public bool Equals(ReactiveChange other) => - Reason == other.Reason && - EqualityComparer.Default.Equals(Current, other.Current) && - EqualityComparer.Default.Equals(Previous, other.Previous) && - CurrentIndex == other.CurrentIndex && - PreviousIndex == other.PreviousIndex; + Reason == other.Reason + && EqualityComparer.Default.Equals(Current, other.Current) + && EqualityComparer.Default.Equals(Previous, other.Previous) + && CurrentIndex == other.CurrentIndex + && PreviousIndex == other.PreviousIndex; /// public override bool Equals(object? obj) => obj is ReactiveChange other && Equals(other); diff --git a/src/ReactiveUI.Core/Expression/ExpressionRewriter.cs b/src/ReactiveUI.Core/Expression/ExpressionRewriter.cs index 67d21fea4b..b156424fc9 100644 --- a/src/ReactiveUI.Core/Expression/ExpressionRewriter.cs +++ b/src/ReactiveUI.Core/Expression/ExpressionRewriter.cs @@ -224,8 +224,8 @@ private static NotSupportedException CreateUnsupportedNodeException(Expression n /// The resolved indexer property. /// Thrown when no indexer property can be found. private static PropertyInfo GetItemProperty( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.NonPublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type) { var property = type.GetRuntimeProperty("Item"); @@ -237,13 +237,13 @@ private static PropertyInfo GetItemProperty( /// The resolved length property. /// Thrown when no length property can be found. private static PropertyInfo GetLengthProperty( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.NonPublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type) { var property = type.GetRuntimeProperty("Length"); - return property ?? - throw new InvalidOperationException("Could not find valid information for the array length operator."); + return property + ?? throw new InvalidOperationException("Could not find valid information for the array length operator."); } /// Determines whether all expressions in the provided collection are constant expressions. diff --git a/src/ReactiveUI.Core/Interfaces/ICreatesCommandBinding.cs b/src/ReactiveUI.Core/Interfaces/ICreatesCommandBinding.cs index e7b184b3d2..d8ed8fd932 100644 --- a/src/ReactiveUI.Core/Interfaces/ICreatesCommandBinding.cs +++ b/src/ReactiveUI.Core/Interfaces/ICreatesCommandBinding.cs @@ -34,8 +34,8 @@ public interface ICreatesCommandBinding "SST1452:A generic type parameter is never used", Justification = "The type parameter is part of the interface contract and identifies the target type; callers supply it explicitly and implementations consume it via reflection.")] int GetAffinityForObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] T>(bool hasEventTarget); /// @@ -56,9 +56,9 @@ int GetAffinityForObject< /// An IDisposable which will disconnect the binding when disposed, or null if no binding was created. [RequiresUnreferencedCode("String/reflection-based event binding may require members removed by trimming.")] IDisposable? BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T>( ICommand? command, T? target, @@ -110,9 +110,9 @@ int GetAffinityForObject< /// Thrown when , , or is . /// IDisposable? BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T, TEventArgs>( ICommand? command, T? target, diff --git a/src/ReactiveUI.Core/Interfaces/ObservedChange.cs b/src/ReactiveUI.Core/Interfaces/ObservedChange.cs index 7cbf1aa4f9..76367cbd8d 100644 --- a/src/ReactiveUI.Core/Interfaces/ObservedChange.cs +++ b/src/ReactiveUI.Core/Interfaces/ObservedChange.cs @@ -17,8 +17,7 @@ namespace ReactiveUI; /// Expression describing the member. /// The value. [System.Diagnostics.DebuggerDisplay("Value = {Value}, Sender = {Sender}")] -public class ObservedChange(TSender sender, Expression? expression, TValue value) - : IObservedChange +public class ObservedChange(TSender sender, Expression? expression, TValue value) : IObservedChange { /// public TSender Sender { get; } = sender; diff --git a/src/ReactiveUI.Core/Interfaces/ReactivePropertyChangedEventArgs.cs b/src/ReactiveUI.Core/Interfaces/ReactivePropertyChangedEventArgs.cs index 52854d49c3..288c8d40d6 100644 --- a/src/ReactiveUI.Core/Interfaces/ReactivePropertyChangedEventArgs.cs +++ b/src/ReactiveUI.Core/Interfaces/ReactivePropertyChangedEventArgs.cs @@ -15,8 +15,7 @@ namespace ReactiveUI; /// The sender. /// Name of the property. [System.Diagnostics.DebuggerDisplay("PropertyName = {PropertyName}, Sender = {Sender}")] -public class ReactivePropertyChangedEventArgs(TSender sender, string propertyName) - : PropertyChangedEventArgs(propertyName), IReactivePropertyChangedEventArgs +public class ReactivePropertyChangedEventArgs(TSender sender, string propertyName) : PropertyChangedEventArgs(propertyName), IReactivePropertyChangedEventArgs { /// Gets the sender which triggered the property changed event. /// diff --git a/src/ReactiveUI.Core/Interfaces/ReactivePropertyChangingEventArgs.cs b/src/ReactiveUI.Core/Interfaces/ReactivePropertyChangingEventArgs.cs index 9249c40449..8da03158f2 100644 --- a/src/ReactiveUI.Core/Interfaces/ReactivePropertyChangingEventArgs.cs +++ b/src/ReactiveUI.Core/Interfaces/ReactivePropertyChangingEventArgs.cs @@ -15,8 +15,7 @@ namespace ReactiveUI; /// The sender. /// Name of the property. [System.Diagnostics.DebuggerDisplay("PropertyName = {PropertyName}, Sender = {Sender}")] -public class ReactivePropertyChangingEventArgs(TSender sender, string? propertyName) - : PropertyChangingEventArgs(propertyName), IReactivePropertyChangedEventArgs +public class ReactivePropertyChangingEventArgs(TSender sender, string? propertyName) : PropertyChangingEventArgs(propertyName), IReactivePropertyChangedEventArgs { /// Gets the sender which triggered the Reactive property changed event. /// diff --git a/src/ReactiveUI.Core/Mixins/DependencyResolverMixins.cs b/src/ReactiveUI.Core/Mixins/DependencyResolverMixins.cs index 17d3807ab5..f5388ce324 100644 --- a/src/ReactiveUI.Core/Mixins/DependencyResolverMixins.cs +++ b/src/ReactiveUI.Core/Mixins/DependencyResolverMixins.cs @@ -56,8 +56,8 @@ public void RegisterViewsForViewModels(Assembly assembly) /// Thrown if the specified type does not have a public parameterless constructor, or if instantiation fails. /// Internal so the missing-parameterless-constructor guard can be exercised directly in tests. internal static Func TypeFactory( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | - DynamicallyAccessedMemberTypes.NonPublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors + | DynamicallyAccessedMemberTypes.NonPublicConstructors)] TypeInfo typeInfo) { ConstructorInfo? parameterlessConstructor = null; @@ -94,8 +94,8 @@ internal static Func TypeFactory( /// the registration is not associated with a contract. private static void RegisterType( IMutableDependencyResolver resolver, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | - DynamicallyAccessedMemberTypes.NonPublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors + | DynamicallyAccessedMemberTypes.NonPublicConstructors)] TypeInfo ti, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type serviceType, diff --git a/src/ReactiveUI.Core/ObservableForProperty/INPCObservableForProperty.cs b/src/ReactiveUI.Core/ObservableForProperty/INPCObservableForProperty.cs index 5a86981a17..5d2c149e37 100644 --- a/src/ReactiveUI.Core/ObservableForProperty/INPCObservableForProperty.cs +++ b/src/ReactiveUI.Core/ObservableForProperty/INPCObservableForProperty.cs @@ -85,8 +85,8 @@ public int GetAffinityForObject(Type? type, string propertyName, bool beforeChan /// The observed property name. /// if the notification applies to the observed property. private static bool Matches(string? notifiedName, string observedName) => - string.IsNullOrEmpty(notifiedName) || - string.Equals(notifiedName, observedName, StringComparison.InvariantCulture); + string.IsNullOrEmpty(notifiedName) + || string.Equals(notifiedName, observedName, StringComparison.InvariantCulture); /// /// A single-layer observable over : each subscription attaches diff --git a/src/ReactiveUI.Core/ReactiveUI.Core.csproj b/src/ReactiveUI.Core/ReactiveUI.Core.csproj index 59dc3b3ecf..dee932978d 100644 --- a/src/ReactiveUI.Core/ReactiveUI.Core.csproj +++ b/src/ReactiveUI.Core/ReactiveUI.Core.csproj @@ -39,6 +39,15 @@ + + + + + + + + + diff --git a/src/ReactiveUI.Core/View/DefaultViewLocator.cs b/src/ReactiveUI.Core/View/DefaultViewLocator.cs index 01cd51d069..396c3ca352 100644 --- a/src/ReactiveUI.Core/View/DefaultViewLocator.cs +++ b/src/ReactiveUI.Core/View/DefaultViewLocator.cs @@ -96,10 +96,7 @@ public DefaultViewLocator Map(Func factory, string? co lock (_gate) { var current = Volatile.Read(ref _mappings); - Dictionary<(Type, string), Func> newMappings = new(current) - { - [key] = factory - }; + Dictionary<(Type, string), Func> newMappings = new(current) { [key] = factory }; _ = Interlocked.Exchange(ref _mappings, newMappings); } @@ -205,8 +202,8 @@ public DefaultViewLocator Unmap(string? contract) [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public IViewFor? ResolveView(object? instance) => ResolveView(instance, null); @@ -214,8 +211,8 @@ public DefaultViewLocator Unmap(string? contract) [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public IViewFor? ResolveView(object? instance, string? contract) { if (instance is null) diff --git a/src/ReactiveUI.Core/View/ViewLocator.cs b/src/ReactiveUI.Core/View/ViewLocator.cs index 3d1cee4393..f0c483ea7a 100644 --- a/src/ReactiveUI.Core/View/ViewLocator.cs +++ b/src/ReactiveUI.Core/View/ViewLocator.cs @@ -3,7 +3,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Diagnostics.CodeAnalysis; using Splat; namespace ReactiveUI; @@ -34,7 +33,6 @@ public static class ViewLocator /// Thrown when no locator has been registered with the dependency resolver. Ensure ReactiveUI initialization /// has run and required assemblies are referenced. /// - [SuppressMessage("Microsoft.Reliability", "CA1065", Justification = "Exception required to keep interface same.")] public static IViewLocator Current => AppLocator.Current.GetService() ?? throw new ViewLocatorNotFoundException( "Could not find a default ViewLocator. This should never happen, your dependency resolver is broken"); diff --git a/src/ReactiveUI.Core/View/ViewMappingBuilder.cs b/src/ReactiveUI.Core/View/ViewMappingBuilder.cs index 4ff09950c3..4f013d398d 100644 --- a/src/ReactiveUI.Core/View/ViewMappingBuilder.cs +++ b/src/ReactiveUI.Core/View/ViewMappingBuilder.cs @@ -121,8 +121,8 @@ public ViewMappingBuilder MapFromServiceLocator(string? contr where TView : class, IViewFor { _ = _locator.Map( - static () => AppLocator.Current.GetService() ?? - throw new InvalidOperationException($"View {nameof(TView)} not registered in service locator"), + static () => AppLocator.Current.GetService() + ?? throw new InvalidOperationException($"View {nameof(TView)} not registered in service locator"), contract); return this; } diff --git a/src/ReactiveUI.Maui.Reactive/ReactiveUI.Maui.Reactive.csproj b/src/ReactiveUI.Maui.Reactive/ReactiveUI.Maui.Reactive.csproj index 8cd0b6891b..701bcf9f9e 100644 --- a/src/ReactiveUI.Maui.Reactive/ReactiveUI.Maui.Reactive.csproj +++ b/src/ReactiveUI.Maui.Reactive/ReactiveUI.Maui.Reactive.csproj @@ -42,7 +42,7 @@ - + @@ -67,4 +67,9 @@ + + + + + diff --git a/src/ReactiveUI.Maui/ActivationForViewFetcher.cs b/src/ReactiveUI.Maui/ActivationForViewFetcher.cs index eed49e081c..5faee2bd79 100644 --- a/src/ReactiveUI.Maui/ActivationForViewFetcher.cs +++ b/src/ReactiveUI.Maui/ActivationForViewFetcher.cs @@ -44,9 +44,9 @@ public int GetAffinityForView(Type view) typeof(FrameworkElement).GetTypeInfo().IsAssignableFrom(typeInfo); #endif #if IS_MAUI - typeof(Page).GetTypeInfo().IsAssignableFrom(typeInfo) || - typeof(View).GetTypeInfo().IsAssignableFrom(typeInfo) || - typeof(Cell).GetTypeInfo().IsAssignableFrom(typeInfo); + typeof(Page).GetTypeInfo().IsAssignableFrom(typeInfo) + || typeof(View).GetTypeInfo().IsAssignableFrom(typeInfo) + || typeof(Cell).GetTypeInfo().IsAssignableFrom(typeInfo); #endif return isActivatableView ? BindingAffinity.ExactType : 0; } @@ -56,17 +56,16 @@ public IObservable GetActivationForView(IActivatableView view) { // ?? is right-associative, so casting the terminal operand unifies the differently-typed concrete sinks the // helpers return under IObservable. - var activation = - GetActivationFor(view as ICanActivate) ?? + var activation = GetActivationFor(view as ICanActivate) #if IS_WINUI - GetActivationFor(view as FrameworkElement) ?? + ?? GetActivationFor(view as FrameworkElement) #endif #if IS_MAUI - GetActivationFor(view as Page) ?? - GetActivationFor(view as View) ?? - GetActivationFor(view as Cell) ?? + ?? GetActivationFor(view as Page) + ?? GetActivationFor(view as View) + ?? GetActivationFor(view as Cell) #endif - (IObservable)Signal.Silent(); + ?? (IObservable)Signal.Silent(); return activation.DistinctUntilChanged(); } diff --git a/src/ReactiveUI.Maui/Common/AutoDataTemplateBindingHook.cs b/src/ReactiveUI.Maui/Common/AutoDataTemplateBindingHook.cs index 100f9591c1..a752e82ff8 100644 --- a/src/ReactiveUI.Maui/Common/AutoDataTemplateBindingHook.cs +++ b/src/ReactiveUI.Maui/Common/AutoDataTemplateBindingHook.cs @@ -26,12 +26,12 @@ public class AutoDataTemplateBindingHook : IPropertyBindingHook /// Gets the default item template. public static Lazy DefaultItemTemplate { get; } = new(static () => { - const string template = "" + - "" + - ""; + const string template = "" + + "" + + ""; return (DataTemplate)XamlReader.Load(template); }); diff --git a/src/ReactiveUI.Maui/Common/RoutedViewHost.cs b/src/ReactiveUI.Maui/Common/RoutedViewHost.cs index 5e478b383b..811ef7c8fa 100644 --- a/src/ReactiveUI.Maui/Common/RoutedViewHost.cs +++ b/src/ReactiveUI.Maui/Common/RoutedViewHost.cs @@ -66,8 +66,8 @@ public RoutedViewHost() // NB: This used to be an error but WPF design mode can't read // good or do other stuff good. this.Log().Error( - "Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest " + - "version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."); + "Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest " + + "version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."); } else { @@ -176,8 +176,8 @@ public string? ViewContract /// Resolves and hosts the view for the supplied view model/contract pair. /// The view model and contract to resolve a view for. [RequiresUnreferencedCode("This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] - [RequiresDynamicCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + [RequiresDynamicCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] private void ResolveViewForViewModel((IRoutableViewModel? viewModel, string? contract) x) { if (x.viewModel is null) diff --git a/src/ReactiveUI.Maui/Common/RoutedViewHost{TViewModel}.cs b/src/ReactiveUI.Maui/Common/RoutedViewHost{TViewModel}.cs index ef2bb9b5b2..07e6abcd39 100644 --- a/src/ReactiveUI.Maui/Common/RoutedViewHost{TViewModel}.cs +++ b/src/ReactiveUI.Maui/Common/RoutedViewHost{TViewModel}.cs @@ -29,8 +29,7 @@ namespace ReactiveUI; /// /// The type of the view model. Must have a public parameterless constructor and implement IRoutableViewModel. public partial class RoutedViewHost< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TViewModel> - : TransitioningContentControl, IActivatableView, IEnableLogger + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TViewModel> : TransitioningContentControl, IActivatableView, IEnableLogger where TViewModel : class, IRoutableViewModel { /// The router dependency property. @@ -69,8 +68,8 @@ public RoutedViewHost() // NB: This used to be an error but WPF design mode can't read // good or do other stuff good. this.Log().Error( - "Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest " + - "version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."); + "Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest " + + "version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."); } else { diff --git a/src/ReactiveUI.Maui/Common/ViewModelViewHost.cs b/src/ReactiveUI.Maui/Common/ViewModelViewHost.cs index 2c5bf29bc8..632cc0268a 100644 --- a/src/ReactiveUI.Maui/Common/ViewModelViewHost.cs +++ b/src/ReactiveUI.Maui/Common/ViewModelViewHost.cs @@ -66,8 +66,8 @@ public ViewModelViewHost() // NB: This used to be an error but WPF design mode can't read // good or do other stuff good. this.Log().Error( - "Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest " + - "version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."); + "Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest " + + "version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."); } else { @@ -158,8 +158,8 @@ public bool ContractFallbackByPass /// ViewModel. /// Contract used by ViewLocator. [RequiresUnreferencedCode("This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] - [RequiresDynamicCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + [RequiresDynamicCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] protected virtual void ResolveViewForViewModel(object? viewModel, string? contract) { if (viewModel is null) diff --git a/src/ReactiveUI.Maui/Common/ViewModelViewHost{TViewModel}.cs b/src/ReactiveUI.Maui/Common/ViewModelViewHost{TViewModel}.cs index b77893e14f..c2ee3fe631 100644 --- a/src/ReactiveUI.Maui/Common/ViewModelViewHost{TViewModel}.cs +++ b/src/ReactiveUI.Maui/Common/ViewModelViewHost{TViewModel}.cs @@ -28,8 +28,7 @@ namespace ReactiveUI; /// /// The type of the view model. Must have a public parameterless constructor. public partial class ViewModelViewHost< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TViewModel> - : TransitioningContentControl, IViewFor, IEnableLogger + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TViewModel> : TransitioningContentControl, IViewFor, IEnableLogger where TViewModel : class { /// The default content dependency property. @@ -69,8 +68,8 @@ public ViewModelViewHost() // NB: This used to be an error but WPF design mode can't read // good or do other stuff good. this.Log().Error( - "Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest " + - "version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."); + "Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest " + + "version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."); } else { diff --git a/src/ReactiveUI.Maui/Internal/MauiReactiveHelpers.cs b/src/ReactiveUI.Maui/Internal/MauiReactiveHelpers.cs index 9d60f1883e..6034921e57 100644 --- a/src/ReactiveUI.Maui/Internal/MauiReactiveHelpers.cs +++ b/src/ReactiveUI.Maui/Internal/MauiReactiveHelpers.cs @@ -42,8 +42,8 @@ internal static IObservable CreatePropertyChangedPulse(INotifyPropertyCh { void Handler(object? _, PropertyChangedEventArgs e) { - if (!string.IsNullOrEmpty(e.PropertyName) && - !string.Equals(e.PropertyName, propertyName, StringComparison.Ordinal)) + if (!string.IsNullOrEmpty(e.PropertyName) + && !string.Equals(e.PropertyName, propertyName, StringComparison.Ordinal)) { return; } @@ -86,8 +86,8 @@ internal static IObservable CreatePropertyValueObservable( void Handler(object? _, PropertyChangedEventArgs e) { - if (!string.IsNullOrEmpty(e.PropertyName) && - !string.Equals(e.PropertyName, propertyName, StringComparison.Ordinal)) + if (!string.IsNullOrEmpty(e.PropertyName) + && !string.Equals(e.PropertyName, propertyName, StringComparison.Ordinal)) { return; } diff --git a/src/ReactiveUI.Maui/ReactiveImageItemView.cs b/src/ReactiveUI.Maui/ReactiveImageItemView.cs index 3d4d5ac0bd..a2082cf740 100644 --- a/src/ReactiveUI.Maui/ReactiveImageItemView.cs +++ b/src/ReactiveUI.Maui/ReactiveImageItemView.cs @@ -87,26 +87,11 @@ public class ReactiveImageItemView< /// Initializes a new instance of the class. public ReactiveImageItemView() { - _image = new() - { - WidthRequest = ImageSize, - HeightRequest = ImageSize, - VerticalOptions = LayoutOptions.Center, - HorizontalOptions = LayoutOptions.Start - }; + _image = new() { WidthRequest = ImageSize, HeightRequest = ImageSize, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Start }; - _textLabel = new() - { - FontSize = PrimaryFontSize, - VerticalOptions = LayoutOptions.Center - }; + _textLabel = new() { FontSize = PrimaryFontSize, VerticalOptions = LayoutOptions.Center }; - _detailLabel = new() - { - FontSize = DetailFontSize, - VerticalOptions = LayoutOptions.Center, - Opacity = DetailOpacity - }; + _detailLabel = new() { FontSize = DetailFontSize, VerticalOptions = LayoutOptions.Center, Opacity = DetailOpacity }; _image.Source = ImageSource; _textLabel.Text = Text; diff --git a/src/ReactiveUI.Maui/ReactiveMultiPage.cs b/src/ReactiveUI.Maui/ReactiveMultiPage.cs index f417a0692e..b8de2fa68d 100644 --- a/src/ReactiveUI.Maui/ReactiveMultiPage.cs +++ b/src/ReactiveUI.Maui/ReactiveMultiPage.cs @@ -17,9 +17,9 @@ namespace ReactiveUI.Maui; /// /// public abstract class ReactiveMultiPage< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | - DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor + | DynamicallyAccessedMemberTypes.PublicMethods + | DynamicallyAccessedMemberTypes.PublicProperties)] TPage, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TViewModel> : MultiPage, IViewFor diff --git a/src/ReactiveUI.Maui/ReactiveTextItemView.cs b/src/ReactiveUI.Maui/ReactiveTextItemView.cs index c8fad8cad1..eba5a7dcb1 100644 --- a/src/ReactiveUI.Maui/ReactiveTextItemView.cs +++ b/src/ReactiveUI.Maui/ReactiveTextItemView.cs @@ -71,29 +71,14 @@ public class ReactiveTextItemView< /// Initializes a new instance of the class. public ReactiveTextItemView() { - _textLabel = new() - { - FontSize = PrimaryFontSize, - VerticalOptions = LayoutOptions.Center - }; + _textLabel = new() { FontSize = PrimaryFontSize, VerticalOptions = LayoutOptions.Center }; - _detailLabel = new() - { - FontSize = DetailFontSize, - VerticalOptions = LayoutOptions.Center, - Opacity = DetailOpacity - }; + _detailLabel = new() { FontSize = DetailFontSize, VerticalOptions = LayoutOptions.Center, Opacity = DetailOpacity }; _textLabel.Text = Text; _detailLabel.Text = Detail; - Content = new StackLayout - { - Orientation = StackOrientation.Vertical, - VerticalOptions = LayoutOptions.Center, - Padding = ContentPadding, - Children = { _textLabel, _detailLabel } - }; + Content = new StackLayout { Orientation = StackOrientation.Vertical, VerticalOptions = LayoutOptions.Center, Padding = ContentPadding, Children = { _textLabel, _detailLabel } }; } /// Gets or sets the primary text to display. diff --git a/src/ReactiveUI.Maui/ReactiveUI.Maui.csproj b/src/ReactiveUI.Maui/ReactiveUI.Maui.csproj index d0b453fc9b..e0d7c8e530 100644 --- a/src/ReactiveUI.Maui/ReactiveUI.Maui.csproj +++ b/src/ReactiveUI.Maui/ReactiveUI.Maui.csproj @@ -40,7 +40,7 @@ - + @@ -56,4 +56,9 @@ + + + + + diff --git a/src/ReactiveUI.Maui/RoutedViewHost.cs b/src/ReactiveUI.Maui/RoutedViewHost.cs index 77dd46bd42..cea75a11cf 100644 --- a/src/ReactiveUI.Maui/RoutedViewHost.cs +++ b/src/ReactiveUI.Maui/RoutedViewHost.cs @@ -60,8 +60,8 @@ public RoutedViewHost() { // Resolve the Router before wiring the subscriptions: SubscribeToNavigationStackChanges hooks // Router.NavigationStack directly, so Router must already be set or it would dereference null. - var screen = AppLocator.Current.GetService() ?? - throw new InvalidOperationException("You *must* register an IScreen class representing your App's main Screen"); + var screen = AppLocator.Current.GetService() + ?? throw new InvalidOperationException("You *must* register an IScreen class representing your App's main Screen"); Router = screen.Router; // Subscribe directly without WhenActivated @@ -102,8 +102,8 @@ public bool SetTitleOnNavigate [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + + "trimming can't validate that the requirements of those annotations are met.")] protected virtual IObservable PagesForViewModel(IRoutableViewModel? vm) { if (vm is null) @@ -137,8 +137,8 @@ protected virtual IObservable PagesForViewModel(IRoutableViewModel? vm) [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + + "trimming can't validate that the requirements of those annotations are met.")] protected virtual Page PageForViewModel(IRoutableViewModel vm) { ArgumentNullException.ThrowIfNull(vm); @@ -194,8 +194,8 @@ protected void InvalidateCurrentViewModel() [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + + "trimming can't validate that the requirements of those annotations are met.")] protected async Task SyncNavigationStacksAsync() { if (Navigation.NavigationStack.Count == Router.NavigationStack.Count @@ -238,8 +238,8 @@ protected async Task SyncNavigationStacksAsync() [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + + "trimming can't validate that the requirements of those annotations are met.")] private async Task PerformInitialNavigationSyncAsync() { try @@ -256,8 +256,8 @@ private async Task PerformInitialNavigationSyncAsync() [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + + "trimming can't validate that the requirements of those annotations are met.")] private void SubscribeToNavigationStackChanges() => new FromEventObservable(onNext => { @@ -281,8 +281,8 @@ private void SubscribeToNavigationStackChanges() => [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + + "trimming can't validate that the requirements of those annotations are met.")] private void SubscribeToNavigateBack() => Router? .NavigateBack @@ -294,8 +294,8 @@ private void SubscribeToNavigateBack() => [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic arguments), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic arguments), " + + "trimming can't validate that the requirements of those annotations are met.")] private async Task OnNavigateBackAsync() { try @@ -317,8 +317,8 @@ private async Task OnNavigateBackAsync() [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + + "trimming can't validate that the requirements of those annotations are met.")] private void SubscribeToNavigate() => Router? .Navigate @@ -332,8 +332,8 @@ private void SubscribeToNavigate() => [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic arguments), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic arguments), " + + "trimming can't validate that the requirements of those annotations are met.")] private void OnNavigateRequested() { if (!StacksAreDifferent()) @@ -354,8 +354,8 @@ private void OnNavigateRequested() [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic arguments), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic arguments), " + + "trimming can't validate that the requirements of those annotations are met.")] private Page? ResolveCurrentPage() { Page? page = null; @@ -373,8 +373,8 @@ private void OnNavigateRequested() [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic arguments), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic arguments), " + + "trimming can't validate that the requirements of those annotations are met.")] private async Task OnNavigateAsync() { var page = ResolveCurrentPage(); diff --git a/src/ReactiveUI.Maui/RoutedViewHost{TViewModel}.cs b/src/ReactiveUI.Maui/RoutedViewHost{TViewModel}.cs index ba373b5449..48e105afe2 100644 --- a/src/ReactiveUI.Maui/RoutedViewHost{TViewModel}.cs +++ b/src/ReactiveUI.Maui/RoutedViewHost{TViewModel}.cs @@ -38,8 +38,8 @@ public RoutedViewHost() [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + + "trimming can't validate that the requirements of those annotations are met.")] protected override IObservable PagesForViewModel(IRoutableViewModel? vm) { if (vm is null) @@ -74,8 +74,8 @@ protected override IObservable PagesForViewModel(IRoutableViewModel? vm) [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + - "trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), " + + "trimming can't validate that the requirements of those annotations are met.")] protected override Page PageForViewModel(IRoutableViewModel vm) { ArgumentNullException.ThrowIfNull(vm); diff --git a/src/ReactiveUI.Maui/ViewModelViewHost.cs b/src/ReactiveUI.Maui/ViewModelViewHost.cs index 9381cdbf45..ddb1d71e9a 100644 --- a/src/ReactiveUI.Maui/ViewModelViewHost.cs +++ b/src/ReactiveUI.Maui/ViewModelViewHost.cs @@ -23,8 +23,8 @@ namespace ReactiveUI.Maui; [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic " + - "constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic " + + "constraints), trimming can't validate that the requirements of those annotations are met.")] public class ViewModelViewHost : ContentView, IViewFor { /// Identifies the property. @@ -131,8 +131,8 @@ public bool ContractFallbackByPass [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic " + - "constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic " + + "constraints), trimming can't validate that the requirements of those annotations are met.")] protected virtual void ResolveViewForViewModel(object? viewModel, string? contract) { if (viewModel is null) diff --git a/src/ReactiveUI.Maui/ViewModelViewHost{TViewModel}.cs b/src/ReactiveUI.Maui/ViewModelViewHost{TViewModel}.cs index af6d69a1c1..25ca301fce 100644 --- a/src/ReactiveUI.Maui/ViewModelViewHost{TViewModel}.cs +++ b/src/ReactiveUI.Maui/ViewModelViewHost{TViewModel}.cs @@ -26,8 +26,8 @@ namespace ReactiveUI.Maui; [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic " + - "constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic " + + "constraints), trimming can't validate that the requirements of those annotations are met.")] public class ViewModelViewHost< [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes .PublicParameterlessConstructor)] @@ -63,8 +63,8 @@ public class ViewModelViewHost< [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic " + - "constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic " + + "constraints), trimming can't validate that the requirements of those annotations are met.")] protected override void ResolveViewForViewModel(object? viewModel, string? contract) { if (viewModel is not null and not TViewModel) diff --git a/src/ReactiveUI.Shared/Activation/CanActivateViewFetcher.cs b/src/ReactiveUI.Shared/Activation/CanActivateViewFetcher.cs index 575a880390..da0c5c5422 100644 --- a/src/ReactiveUI.Shared/Activation/CanActivateViewFetcher.cs +++ b/src/ReactiveUI.Shared/Activation/CanActivateViewFetcher.cs @@ -46,8 +46,7 @@ view is not ICanActivate canActivate /// /// Emits when the view is activated. /// Emits when the view is deactivated. - private sealed class ActivationStateObservable(IObservable activated, IObservable deactivated) - : IObservable + private sealed class ActivationStateObservable(IObservable activated, IObservable deactivated) : IObservable { /// public IDisposable Subscribe(IObserver observer) diff --git a/src/ReactiveUI.Shared/Bindings/Command/CommandBinderImplementation.cs b/src/ReactiveUI.Shared/Bindings/Command/CommandBinderImplementation.cs index e03601a5ca..da78af3055 100644 --- a/src/ReactiveUI.Shared/Bindings/Command/CommandBinderImplementation.cs +++ b/src/ReactiveUI.Shared/Bindings/Command/CommandBinderImplementation.cs @@ -60,9 +60,9 @@ public IReactiveBinding BindCommand< TView, TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, @@ -130,9 +130,9 @@ public IReactiveBinding BindCommand< TView, TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, @@ -176,9 +176,9 @@ public IReactiveBinding BindCommand< TView, TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, @@ -242,9 +242,9 @@ public IReactiveBinding BindCommand< TView, TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, @@ -256,7 +256,7 @@ public IReactiveBinding BindCommand< where TViewModel : class where TProp : ICommand where TControl : class => - BindCommand(viewModel, view, viewModelProperty, controlProperty, withParameter, null); + BindCommand(viewModel, view, viewModelProperty, controlProperty, (IObservable)withParameter, null); /// /// Binds an observable command to a control property or event on a view, updating the binding when the command or @@ -282,9 +282,9 @@ private static MultipleDisposable BindCommandInternal< TView, TProp, TParam, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl>( IObservable source, TView view, diff --git a/src/ReactiveUI.Shared/Bindings/Command/CommandBinderMixins.cs b/src/ReactiveUI.Shared/Bindings/Command/CommandBinderMixins.cs index a75b01d55a..7b4dcf6e14 100644 --- a/src/ReactiveUI.Shared/Bindings/Command/CommandBinderMixins.cs +++ b/src/ReactiveUI.Shared/Bindings/Command/CommandBinderMixins.cs @@ -32,8 +32,8 @@ public static class CommandBinderMixins /// This static constructor ensures that the command binding implementation is set up before any /// static members of the CommandBinderMixins class are accessed. It attempts to retrieve an ICommandBinderImplementation /// from the application's service locator; if none is available, a default implementation is used. - static CommandBinderMixins() => _binderImplementation = AppLocator.Current.GetService() ?? - new CommandBinderImplementation(); + static CommandBinderMixins() => _binderImplementation = AppLocator.Current.GetService() + ?? new CommandBinderImplementation(); /// Provides command binding extension members for views implementing . /// The type of the view implementing the IViewFor interface. @@ -55,9 +55,9 @@ static CommandBinderMixins() => _binderImplementation = AppLocator.Current.GetSe public IReactiveBinding BindCommand< TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, @@ -100,9 +100,9 @@ public IReactiveBinding BindCommand< public IReactiveBinding BindCommand< TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, @@ -134,9 +134,9 @@ public IReactiveBinding BindCommand< public IReactiveBinding BindCommand< TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl>( TViewModel? viewModel, Expression> propertyName, @@ -168,9 +168,9 @@ public IReactiveBinding BindCommand< public IReactiveBinding BindCommand< TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl>( TViewModel? viewModel, Expression> propertyName, @@ -201,9 +201,9 @@ public IReactiveBinding BindCommand< public IReactiveBinding BindCommand< TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, @@ -246,9 +246,9 @@ public IReactiveBinding BindCommand< public IReactiveBinding BindCommand< TViewModel, TProp, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] TControl, TParam>( TViewModel? viewModel, diff --git a/src/ReactiveUI.Shared/Bindings/Interaction/InteractionBinderImplementation.cs b/src/ReactiveUI.Shared/Bindings/Interaction/InteractionBinderImplementation.cs index 46fed177aa..e4fe13c8c1 100644 --- a/src/ReactiveUI.Shared/Bindings/Interaction/InteractionBinderImplementation.cs +++ b/src/ReactiveUI.Shared/Bindings/Interaction/InteractionBinderImplementation.cs @@ -46,7 +46,7 @@ public IDisposable BindInteraction, IObservable>)handler); return BindInteractionCore( viewModel, diff --git a/src/ReactiveUI.Shared/Bindings/Property/Internal/PropertyBindingExpressionCompiler.cs b/src/ReactiveUI.Shared/Bindings/Property/Internal/PropertyBindingExpressionCompiler.cs index 4cea084102..807f9f866d 100644 --- a/src/ReactiveUI.Shared/Bindings/Property/Internal/PropertyBindingExpressionCompiler.cs +++ b/src/ReactiveUI.Shared/Bindings/Property/Internal/PropertyBindingExpressionCompiler.cs @@ -84,8 +84,8 @@ public bool ShouldReplayOnHostChanges(Expression[]? hostExpressionChain) for (var i = 0; i < hostExpressionChain.Length; i++) { - if (hostExpressionChain[i] is MemberExpression member && - string.Equals(member.Member.Name, nameof(IViewFor.ViewModel), StringComparison.Ordinal)) + if (hostExpressionChain[i] is MemberExpression member + && string.Equals(member.Member.Name, nameof(IViewFor.ViewModel), StringComparison.Ordinal)) { return false; } @@ -152,8 +152,8 @@ public bool ShouldReplayOnHostChanges(Expression[]? hostExpressionChain) var setThenGet = CreateSetThenGet(viewExpression, getter, setter, getSetConverter); var arguments = viewExpression.GetArgumentsArray(); - var hostExpression = viewExpression.GetParent() ?? - throw new InvalidOperationException("Host expression was not found."); + var hostExpression = viewExpression.GetParent() + ?? throw new InvalidOperationException("Host expression was not found."); var hostChanges = new SynchronizeObservable(target.WhenAnyDynamic(hostExpression, static x => x.Value)); var propertyDefaultValue = CreateDefaultValueForType(viewExpression.Type); var shouldReplayOnHostChanges = ShouldReplayOnHostChanges(hostExpressionChain); diff --git a/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.Conversions.cs b/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.Conversions.cs index cbfd952c68..71be4fbb74 100644 --- a/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.Conversions.cs +++ b/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.Conversions.cs @@ -178,20 +178,20 @@ private static (bool isValid, object? view, bool isViewModel) ProjectChange viewToViewModelConverter) where TView : class, IViewFor { - if (!viewModelChainGetter.TryGetValue(view.ViewModel, out var viewModelValue) || - !viewChainGetter.TryGetValue(view, out var viewValue)) + if (!viewModelChainGetter.TryGetValue(view.ViewModel, out var viewModelValue) + || !viewChainGetter.TryGetValue(view, out var viewValue)) { return (false, null, false); } if (isViewModelChange) { - return !viewModelToViewConverter(viewModelValue, out var viewModelAsView) || - EqualityComparer.Default.Equals(viewValue, viewModelAsView) ? (false, null, false) : (true, viewModelAsView, true); + return !viewModelToViewConverter(viewModelValue, out var viewModelAsView) + || EqualityComparer.Default.Equals(viewValue, viewModelAsView) ? (false, null, false) : (true, viewModelAsView, true); } - return !viewToViewModelConverter(viewValue, out var viewAsViewModel) || - EqualityComparer.Default.Equals(viewModelValue, viewAsViewModel) ? (false, null, false) : (true, viewAsViewModel, false); + return !viewToViewModelConverter(viewValue, out var viewAsViewModel) + || EqualityComparer.Default.Equals(viewModelValue, viewAsViewModel) ? (false, null, false) : (true, viewAsViewModel, false); } /// Builds the merged observable that signals when either the view model or the view side changed. diff --git a/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.Internals.cs b/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.Internals.cs index ca0d42a3c4..aa2cc59bdc 100644 --- a/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.Internals.cs +++ b/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.Internals.cs @@ -68,8 +68,8 @@ private static (bool Success, object? Value) ConvertViewModelValue( /// The change-signal source. /// The binder providing the scheduling hook. /// The view participating in the binding. - private sealed class ScheduledChangeObservable(IObservable source, PropertyBinderImplementation owner, TView view) - : IObservable + private sealed class ScheduledChangeObservable(IObservable source, PropertyBinderImplementation owner, TView view) : IObservable where TView : class { /// diff --git a/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.cs b/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.cs index e7edf9906f..4ebbf5a4c4 100644 --- a/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.cs +++ b/src/ReactiveUI.Shared/Bindings/Property/PropertyBinderImplementation.cs @@ -171,8 +171,8 @@ internal PropertyBinderImplementation( var viewToViewModelConverterObj = viewToViewModelConverterOverride ?? GetConverterForTypes(typeof(TViewPropertyType), typeof(TViewModelPropertyType?)); var hasConverters = viewModelToViewConverterObj is not null && viewToViewModelConverterObj is not null; - var typesAreAssignable = typeof(TViewPropertyType).IsAssignableFrom(typeof(TViewModelPropertyType)) || - typeof(TViewModelPropertyType).IsAssignableFrom(typeof(TViewPropertyType)); + var typesAreAssignable = typeof(TViewPropertyType).IsAssignableFrom(typeof(TViewModelPropertyType)) + || typeof(TViewModelPropertyType).IsAssignableFrom(typeof(TViewPropertyType)); if (!hasConverters && !typesAreAssignable) { @@ -425,8 +425,8 @@ public IDisposable BindTo( var viewExpression = Reflection.Rewrite(propertyExpression.Body); - var shouldBind = target is not IViewFor viewFor || - _hookEvaluator.EvaluateBindingHooks( + var shouldBind = target is not IViewFor viewFor + || _hookEvaluator.EvaluateBindingHooks( null, viewFor, null!, diff --git a/src/ReactiveUI.Shared/Builder/ReactiveUIBuilder.cs b/src/ReactiveUI.Shared/Builder/ReactiveUIBuilder.cs index 897d90fe31..0564228de5 100644 --- a/src/ReactiveUI.Shared/Builder/ReactiveUIBuilder.cs +++ b/src/ReactiveUI.Shared/Builder/ReactiveUIBuilder.cs @@ -377,7 +377,7 @@ public IReactiveUIBuilder WithConverter(BindingTypeConverter public IReactiveUIBuilder WithConverter(IBindingTypeConverter converter) { - ArgumentExceptionHelper.ThrowIfNull(converter); + ArgumentExceptionHelper.ThrowIfNull((IBindingTypeConverter)converter); ConverterService.TypedConverters.Register(converter); return this; } @@ -415,7 +415,7 @@ public IReactiveUIBuilder WithConverter(Func public IReactiveUIBuilder WithConverter(Func factory) { - ArgumentExceptionHelper.ThrowIfNull(factory); + ArgumentExceptionHelper.ThrowIfNull((Func)factory); ConverterService.TypedConverters.Register(factory()); return this; } diff --git a/src/ReactiveUI.Shared/Builder/RxAppBuilder.cs b/src/ReactiveUI.Shared/Builder/RxAppBuilder.cs index 70f3230ad7..f4f2439e4d 100644 --- a/src/ReactiveUI.Shared/Builder/RxAppBuilder.cs +++ b/src/ReactiveUI.Shared/Builder/RxAppBuilder.cs @@ -56,13 +56,13 @@ public static void EnsureInitialized() if (_hasBeenInitialized == 0) { throw new InvalidOperationException( - "ReactiveUI has not been initialized. You must initialize ReactiveUI using the builder pattern. " + - "See https://www.reactiveui.net/docs/handbook/rxappbuilder.html for migration guidance.\n\n" + - "Example:\n" + - "RxAppBuilder.CreateReactiveUIBuilder()\n" + - " .WithCoreServices()\n" + - " .WithPlatformServices()\n" + - " .BuildApp();"); + "ReactiveUI has not been initialized. You must initialize ReactiveUI using the builder pattern. " + + "See https://www.reactiveui.net/docs/handbook/rxappbuilder.html for migration guidance.\n\n" + + "Example:\n" + + "RxAppBuilder.CreateReactiveUIBuilder()\n" + + " .WithCoreServices()\n" + + " .WithPlatformServices()\n" + + " .BuildApp();"); } } } diff --git a/src/ReactiveUI.Shared/Expression/Reflection.cs b/src/ReactiveUI.Shared/Expression/Reflection.cs index 6e56363153..202aa527a3 100644 --- a/src/ReactiveUI.Shared/Expression/Reflection.cs +++ b/src/ReactiveUI.Shared/Expression/Reflection.cs @@ -87,8 +87,8 @@ public static string ExpressionToPropertyNames(Expression? expression) switch (exp.NodeType) { case ExpressionType.Index when - exp is IndexExpression indexExpression && - indexExpression.Indexer is not null: + exp is IndexExpression indexExpression + && indexExpression.Indexer is not null: { _ = sb.Append(indexExpression.Indexer.Name).Append('['); @@ -171,8 +171,8 @@ exp is IndexExpression indexExpression && ArgumentExceptionHelper.ThrowIfNull(member); var ret = GetValueFetcherForProperty(member); - return ret ?? - throw new ArgumentException($"Type '{member.DeclaringType}' must have a property '{member.Name}'"); + return ret + ?? throw new ArgumentException($"Type '{member.DeclaringType}' must have a property '{member.Name}'"); } /// Converts a into a delegate which sets the value for the member. Supports fields and properties. @@ -217,8 +217,8 @@ exp is IndexExpression indexExpression && ArgumentExceptionHelper.ThrowIfNull(member); var ret = GetValueSetterForProperty(member); - return ret ?? - throw new ArgumentException($"Type '{member.DeclaringType}' must have a property '{member.Name}'"); + return ret + ?? throw new ArgumentException($"Type '{member.DeclaringType}' must have a property '{member.Name}'"); } /// Based on a list of expressions, attempts to get the value of the last property in the chain. @@ -474,8 +474,8 @@ public static Type GetEventArgsTypeForEvent( throw new InvalidOperationException($"Couldn't find {type.FullName}.{eventName}"); } - var invoke = eventInfo.EventHandlerType.GetMethod("Invoke") ?? - throw new MissingMethodException(eventInfo.EventHandlerType.FullName, "Invoke"); + var invoke = eventInfo.EventHandlerType.GetMethod("Invoke") + ?? throw new MissingMethodException(eventInfo.EventHandlerType.FullName, "Invoke"); var parameters = invoke.GetParameters(); return parameters[1].ParameterType; } @@ -490,8 +490,8 @@ public static Type GetEventArgsTypeForEvent( /// public static void ThrowIfMethodsNotOverloaded( string callingTypeName, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | - DynamicallyAccessedMemberTypes.NonPublicMethods)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods + | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type targetType, params string[] methodsToCheck) { diff --git a/src/ReactiveUI.Shared/Interfaces/ISuspensionDriver.cs b/src/ReactiveUI.Shared/Interfaces/ISuspensionDriver.cs index a1a483d8cd..0a7e2263c3 100644 --- a/src/ReactiveUI.Shared/Interfaces/ISuspensionDriver.cs +++ b/src/ReactiveUI.Shared/Interfaces/ISuspensionDriver.cs @@ -35,11 +35,11 @@ public interface ISuspensionDriver /// trimming or AOT friendly. /// [RequiresUnreferencedCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] + "Implementations commonly use reflection-based serialization. " + + "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] [RequiresDynamicCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] + "Implementations commonly use reflection-based serialization. " + + "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] IObservable SaveState(T state); /// Saves application state to persistent storage using source-generated System.Text.Json metadata. @@ -74,11 +74,11 @@ public interface ISuspensionDriver /// trimming or AOT friendly. /// [RequiresUnreferencedCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] + "Implementations commonly use reflection-based serialization. " + + "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] [RequiresDynamicCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] + "Implementations commonly use reflection-based serialization. " + + "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] IObservable LoadState(); /// Invalidates the persisted application state (for example, by deleting it from disk). diff --git a/src/ReactiveUI.Shared/Internal/ExpressionChainSink.cs b/src/ReactiveUI.Shared/Internal/ExpressionChainSink.cs index 4f86fccfd7..4d03ec86d6 100644 --- a/src/ReactiveUI.Shared/Internal/ExpressionChainSink.cs +++ b/src/ReactiveUI.Shared/Internal/ExpressionChainSink.cs @@ -24,8 +24,7 @@ namespace ReactiveUI.Internal; /// The leaf value type. /// The configuration of the chain to observe. [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] -internal sealed class ExpressionChainSink(ExpressionChainParameters parameters) - : IObservable> +internal sealed class ExpressionChainSink(ExpressionChainParameters parameters) : IObservable> { /// public IDisposable Subscribe(IObserver> observer) diff --git a/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.Metadata.cs b/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.Metadata.cs index bb67d5ed72..e8095bb44d 100644 --- a/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.Metadata.cs +++ b/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.Metadata.cs @@ -32,8 +32,8 @@ public static partial class AutoPersistHelperMixins /// A disposable to disable automatic persistence. public IDisposable AutoPersist( Func> doPersist, - AutoPersistMetadata metadata) - => @this.AutoPersist(doPersist, metadata, interval: null); + AutoPersistMetadata metadata) => + @this.AutoPersist(doPersist, metadata, interval: null); /// AutoPersist overload that performs no runtime reflection and is suitable for trimming/AOT scenarios. /// The asynchronous method to call to save the object to disk. @@ -44,8 +44,8 @@ public IDisposable AutoPersist( public IDisposable AutoPersist( Func> doPersist, AutoPersistMetadata metadata, - TimeSpan? interval) - => @this.AutoPersist(doPersist, Signal.Silent(), metadata, interval); + TimeSpan? interval) => + @this.AutoPersist(doPersist, Signal.Silent(), metadata, interval); /// AutoPersist overload that uses explicit metadata and a manual save signal, performing no runtime reflection. /// The save signal type. @@ -56,8 +56,8 @@ public IDisposable AutoPersist( public IDisposable AutoPersist( Func> doPersist, IObservable manualSaveSignal, - AutoPersistMetadata metadata) - => @this.AutoPersist(doPersist, manualSaveSignal, metadata, interval: null); + AutoPersistMetadata metadata) => + @this.AutoPersist(doPersist, manualSaveSignal, metadata, interval: null); /// AutoPersist overload that performs no runtime reflection and is suitable for trimming/AOT scenarios. /// The save signal type. diff --git a/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.Persistence.cs b/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.Persistence.cs index 7b382798c0..a7422416f1 100644 --- a/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.Persistence.cs +++ b/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.Persistence.cs @@ -36,8 +36,8 @@ public static partial class AutoPersistHelperMixins public IDisposable AutoPersistCollection( Func> doPersist, IObservable manualSaveSignal, - AutoPersistMetadata metadata) - => @this.AutoPersistCollection(doPersist, manualSaveSignal, metadata, interval: null); + AutoPersistMetadata metadata) => + @this.AutoPersistCollection(doPersist, manualSaveSignal, metadata, interval: null); /// /// Apply AutoPersistence to all objects in a collection using explicit persistence metadata. @@ -106,8 +106,8 @@ public IDisposable AutoPersistCollection( public IDisposable AutoPersistCollection( Func> doPersist, IObservable manualSaveSignal, - Func metadataProvider) - => @this.AutoPersistCollection(doPersist, manualSaveSignal, metadataProvider, interval: null); + Func metadataProvider) => + @this.AutoPersistCollection(doPersist, manualSaveSignal, metadataProvider, interval: null); /// /// Apply AutoPersistence to all objects in a collection using a metadata provider. @@ -173,8 +173,8 @@ public IDisposable AutoPersistCollection( [RequiresDynamicCode("AutoPersist may reflect over the runtime type; prefer the AutoPersistMetadata overloads for trimming/AOT.")] public IDisposable AutoPersistCollection( Func> doPersist, - IObservable manualSaveSignal) - => @this.AutoPersistCollection(doPersist, manualSaveSignal, interval: null); + IObservable manualSaveSignal) => + @this.AutoPersistCollection(doPersist, manualSaveSignal, interval: null); /// /// Apply AutoPersistence to all objects in a collection. Items that are @@ -191,13 +191,13 @@ public IDisposable AutoPersistCollection( /// /// A disposable to disable automatic persistence. [RequiresUnreferencedCode( - "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + - "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + - "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] + "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + + "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + + "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] [RequiresDynamicCode( - "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + - "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + - "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] + "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + + "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + + "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] public IDisposable AutoPersistCollection( Func> doPersist, IObservable manualSaveSignal, @@ -276,8 +276,8 @@ public IDisposable ActOnEveryObject( "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "Generic type parameter is supplied explicitly by the caller by design; it identifies the target type and cannot be inferred from the method's parameters.")] public static Func CreateMetadataProvider< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.NonPublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.NonPublicProperties)] TItem>() where TItem : IReactiveObject { @@ -300,11 +300,11 @@ public static Func CreateMetadataProvider< "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "Generic type parameter is supplied explicitly by the caller by design; it identifies the target type and cannot be inferred from the method's parameters.")] public static AutoPersistMetadata CreateMetadata< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.NonPublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() - where T : IReactiveObject - => PersistMetadataHolder.Metadata.Public; + where T : IReactiveObject => + PersistMetadataHolder.Metadata.Public; /// Disposes and removes the tracked auto-persist subscription for an item that left the collection. /// The item type. @@ -379,13 +379,13 @@ private static void ApplyChange(in ReactiveChange change, Action. /// [RequiresUnreferencedCode( - "AutoPersist reflects over the runtime type. In trimmed/AOT builds, required property/attribute metadata may be removed " + - "unless explicitly preserved. Prefer CreateMetadata() and the overloads that accept AutoPersistMetadata.")] + "AutoPersist reflects over the runtime type. In trimmed/AOT builds, required property/attribute metadata may be removed " + + "unless explicitly preserved. Prefer CreateMetadata() and the overloads that accept AutoPersistMetadata.")] [RequiresDynamicCode( - "AutoPersist reflects over the runtime type. In trimmed/AOT builds, required property/attribute metadata may be removed " + - "unless explicitly preserved. Prefer CreateMetadata() and the overloads that accept AutoPersistMetadata.")] - private static PersistMetadata GetMetadataForUnknownRuntimeType(Type runtimeType) - => PersistMetadataByType.GetValue(runtimeType, PersistMetadata.Create); + "AutoPersist reflects over the runtime type. In trimmed/AOT builds, required property/attribute metadata may be removed " + + "unless explicitly preserved. Prefer CreateMetadata() and the overloads that accept AutoPersistMetadata.")] + private static PersistMetadata GetMetadataForUnknownRuntimeType(Type runtimeType) => + PersistMetadataByType.GetValue(runtimeType, PersistMetadata.Create); /// Public-facing persistence metadata for AutoPersist. /// @@ -422,8 +422,8 @@ public AutoPersistMetadata(bool hasDataContract, ISet persistablePropert /// [SuppressMessage("Design", "SST1431:Reference a type parameter, or move the member off the generic type", Justification = "Deliberate per-closed-generic reflection cache.")] private static class PersistMetadataHolder< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.NonPublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.NonPublicProperties)] T> where T : IReactiveObject { diff --git a/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.cs b/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.cs index 077629d5e4..2d810e52f8 100644 --- a/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.cs +++ b/src/ReactiveUI.Shared/Mixins/AutoPersistHelperMixins.cs @@ -84,8 +84,8 @@ public IDisposable ActOnEveryObject( /// A disposable to disable automatic persistence. public IDisposable AutoPersistCollection( Func> doPersist, - AutoPersistMetadata metadata) - => @this.AutoPersistCollection(doPersist, metadata, interval: null); + AutoPersistMetadata metadata) => + @this.AutoPersistCollection(doPersist, metadata, interval: null); /// /// Apply AutoPersistence to all objects in a collection using explicit persistence metadata. @@ -104,8 +104,8 @@ public IDisposable AutoPersistCollection( public IDisposable AutoPersistCollection( Func> doPersist, AutoPersistMetadata metadata, - TimeSpan? interval) - => AutoPersistCollection(@this, doPersist, Signal.Silent(), metadata, interval); + TimeSpan? interval) => + AutoPersistCollection(@this, doPersist, Signal.Silent(), metadata, interval); /// Applies AutoPersistence to all objects in a collection using explicit persistence metadata. /// The manual save signal type. @@ -116,8 +116,8 @@ public IDisposable AutoPersistCollection( public IDisposable AutoPersistCollection( Func> doPersist, IObservable manualSaveSignal, - AutoPersistMetadata metadata) - => @this.AutoPersistCollection(doPersist, manualSaveSignal, metadata, interval: null); + AutoPersistMetadata metadata) => + @this.AutoPersistCollection(doPersist, manualSaveSignal, metadata, interval: null); /// /// Apply AutoPersistence to all objects in a collection using explicit persistence metadata. @@ -136,8 +136,8 @@ public IDisposable AutoPersistCollection( Func> doPersist, IObservable manualSaveSignal, AutoPersistMetadata metadata, - TimeSpan? interval) - => AutoPersistCollection, TDontCare>( + TimeSpan? interval) => + AutoPersistCollection, TDontCare>( @this, doPersist, manualSaveSignal, @@ -150,8 +150,8 @@ public IDisposable AutoPersistCollection( [RequiresUnreferencedCode("AutoPersist may reflect over the runtime type; prefer the AutoPersistMetadata overloads for trimming/AOT.")] [RequiresDynamicCode("AutoPersist may reflect over the runtime type; prefer the AutoPersistMetadata overloads for trimming/AOT.")] public IDisposable AutoPersistCollection( - Func> doPersist) - => @this.AutoPersistCollection(doPersist, interval: null); + Func> doPersist) => + @this.AutoPersistCollection(doPersist, interval: null); /// /// Apply AutoPersistence to all objects in a collection. Items that are @@ -169,17 +169,17 @@ public IDisposable AutoPersistCollection( /// Prefer the overloads that accept (or a metadata provider) to avoid runtime reflection. /// [RequiresUnreferencedCode( - "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + - "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + - "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] + "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + + "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + + "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] [RequiresDynamicCode( - "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + - "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + - "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] + "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + + "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + + "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] public IDisposable AutoPersistCollection( Func> doPersist, - TimeSpan? interval) - => AutoPersistCollection(@this, doPersist, Signal.Silent(), interval); + TimeSpan? interval) => + AutoPersistCollection(@this, doPersist, Signal.Silent(), interval); /// Applies AutoPersistence to all objects in a collection. /// The return signal type. @@ -190,8 +190,8 @@ public IDisposable AutoPersistCollection( [RequiresDynamicCode("AutoPersist may reflect over the runtime type; prefer the AutoPersistMetadata overloads for trimming/AOT.")] public IDisposable AutoPersistCollection( Func> doPersist, - IObservable manualSaveSignal) - => @this.AutoPersistCollection(doPersist, manualSaveSignal, interval: null); + IObservable manualSaveSignal) => + @this.AutoPersistCollection(doPersist, manualSaveSignal, interval: null); /// /// Apply AutoPersistence to all objects in a collection. Items that are @@ -213,18 +213,18 @@ public IDisposable AutoPersistCollection( /// Prefer the overloads that accept (or a metadata provider) to avoid runtime reflection. /// [RequiresUnreferencedCode( - "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + - "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + - "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] + "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + + "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + + "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] [RequiresDynamicCode( - "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + - "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + - "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] + "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + + "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + + "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] public IDisposable AutoPersistCollection( Func> doPersist, IObservable manualSaveSignal, - TimeSpan? interval) - => AutoPersistCollection, TDontCare>( + TimeSpan? interval) => + AutoPersistCollection, TDontCare>( @this, doPersist, manualSaveSignal, @@ -240,8 +240,8 @@ public IDisposable AutoPersistCollection( /// A disposable that deactivates this behavior. public IDisposable ActOnEveryObject( Action onAdd, - Action onRemove) - => ActOnEveryObject>(@this, onAdd, onRemove); + Action onRemove) => + ActOnEveryObject>(@this, onAdd, onRemove); } /// Provides AutoPersistCollection and ActOnEveryObject extension members for read-only observable collections. @@ -259,8 +259,8 @@ public IDisposable ActOnEveryObject( public IDisposable AutoPersistCollection( Func> doPersist, IObservable manualSaveSignal, - AutoPersistMetadata metadata) - => @this.AutoPersistCollection(doPersist, manualSaveSignal, metadata, interval: null); + AutoPersistMetadata metadata) => + @this.AutoPersistCollection(doPersist, manualSaveSignal, metadata, interval: null); /// /// Apply AutoPersistence to all objects in a read-only collection using explicit persistence metadata. @@ -279,8 +279,8 @@ public IDisposable AutoPersistCollection( Func> doPersist, IObservable manualSaveSignal, AutoPersistMetadata metadata, - TimeSpan? interval) - => AutoPersistCollection, TDontCare>( + TimeSpan? interval) => + AutoPersistCollection, TDontCare>( @this, doPersist, manualSaveSignal, @@ -296,8 +296,8 @@ public IDisposable AutoPersistCollection( [RequiresDynamicCode("AutoPersist may reflect over the runtime type; prefer the AutoPersistMetadata overloads for trimming/AOT.")] public IDisposable AutoPersistCollection( Func> doPersist, - IObservable manualSaveSignal) - => @this.AutoPersistCollection(doPersist, manualSaveSignal, interval: null); + IObservable manualSaveSignal) => + @this.AutoPersistCollection(doPersist, manualSaveSignal, interval: null); /// /// Apply AutoPersistence to all objects in a collection. Items that are @@ -319,18 +319,18 @@ public IDisposable AutoPersistCollection( /// Prefer the overloads that accept (or a metadata provider) to avoid runtime reflection. /// [RequiresUnreferencedCode( - "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + - "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + - "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] + "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + + "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + + "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] [RequiresDynamicCode( - "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + - "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + - "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] + "AutoPersistCollection may reflect over runtime item types via AutoPersist when generic type parameters do not match item runtime types. " + + "In trimmed/AOT builds, required property/attribute metadata may be removed unless explicitly preserved. " + + "Prefer the overloads that accept AutoPersistMetadata or a metadata provider to avoid runtime reflection.")] public IDisposable AutoPersistCollection( Func> doPersist, IObservable manualSaveSignal, - TimeSpan? interval) - => AutoPersistCollection, TDontCare>( + TimeSpan? interval) => + AutoPersistCollection, TDontCare>( @this, doPersist, manualSaveSignal, @@ -346,16 +346,16 @@ public IDisposable AutoPersistCollection( /// A disposable that deactivates this behavior. public IDisposable ActOnEveryObject( Action onAdd, - Action onRemove) - => ActOnEveryObject>(@this, onAdd, onRemove); + Action onRemove) => + ActOnEveryObject>(@this, onAdd, onRemove); } /// Provides AutoPersist extension members for reactive objects, reflecting over the runtime type when required. /// The reactive object type. /// The reactive object to watch for changes. extension< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.NonPublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T @this) where T : IReactiveObject { @@ -365,8 +365,8 @@ public IDisposable ActOnEveryObject( [RequiresUnreferencedCode("AutoPersist may reflect over the runtime type; prefer the AutoPersistMetadata overloads for trimming/AOT.")] [RequiresDynamicCode("AutoPersist may reflect over the runtime type; prefer the AutoPersistMetadata overloads for trimming/AOT.")] public IDisposable AutoPersist( - Func> doPersist) - => @this.AutoPersist(doPersist, interval: null); + Func> doPersist) => + @this.AutoPersist(doPersist, interval: null); /// /// AutoPersist allows you to automatically call a method when an object @@ -392,15 +392,15 @@ public IDisposable AutoPersist( /// /// [RequiresUnreferencedCode( - "AutoPersist may reflect over the runtime type when it differs from T. In trimmed/AOT builds, required property/attribute metadata " + - "may be removed unless explicitly preserved. Prefer the overloads that accept AutoPersistMetadata to avoid runtime reflection.")] + "AutoPersist may reflect over the runtime type when it differs from T. In trimmed/AOT builds, required property/attribute metadata " + + "may be removed unless explicitly preserved. Prefer the overloads that accept AutoPersistMetadata to avoid runtime reflection.")] [RequiresDynamicCode( - "AutoPersist may reflect over the runtime type when it differs from T. In trimmed/AOT builds, required property/attribute metadata " + - "may be removed unless explicitly preserved. Prefer the overloads that accept AutoPersistMetadata to avoid runtime reflection.")] + "AutoPersist may reflect over the runtime type when it differs from T. In trimmed/AOT builds, required property/attribute metadata " + + "may be removed unless explicitly preserved. Prefer the overloads that accept AutoPersistMetadata to avoid runtime reflection.")] public IDisposable AutoPersist( Func> doPersist, - TimeSpan? interval) - => @this.AutoPersist(doPersist, Signal.Silent(), interval); + TimeSpan? interval) => + @this.AutoPersist(doPersist, Signal.Silent(), interval); /// AutoPersist automatically calls a method whenever the object changes or a manual save is signalled. /// The save signal type. @@ -411,8 +411,8 @@ public IDisposable AutoPersist( [RequiresDynamicCode("AutoPersist may reflect over the runtime type; prefer the AutoPersistMetadata overloads for trimming/AOT.")] public IDisposable AutoPersist( Func> doPersist, - IObservable manualSaveSignal) - => @this.AutoPersist(doPersist, manualSaveSignal, interval: null); + IObservable manualSaveSignal) => + @this.AutoPersist(doPersist, manualSaveSignal, interval: null); /// /// AutoPersist allows you to automatically call a method when an object @@ -443,11 +443,11 @@ public IDisposable AutoPersist( /// /// [RequiresUnreferencedCode( - "AutoPersist may reflect over the runtime type when it differs from T. In trimmed/AOT builds, required property/attribute metadata " + - "may be removed unless explicitly preserved. Prefer the overloads that accept AutoPersistMetadata to avoid runtime reflection.")] + "AutoPersist may reflect over the runtime type when it differs from T. In trimmed/AOT builds, required property/attribute metadata " + + "may be removed unless explicitly preserved. Prefer the overloads that accept AutoPersistMetadata to avoid runtime reflection.")] [RequiresDynamicCode( - "AutoPersist may reflect over the runtime type when it differs from T. In trimmed/AOT builds, required property/attribute metadata " + - "may be removed unless explicitly preserved. Prefer the overloads that accept AutoPersistMetadata to avoid runtime reflection.")] + "AutoPersist may reflect over the runtime type when it differs from T. In trimmed/AOT builds, required property/attribute metadata " + + "may be removed unless explicitly preserved. Prefer the overloads that accept AutoPersistMetadata to avoid runtime reflection.")] public IDisposable AutoPersist( Func> doPersist, IObservable manualSaveSignal, diff --git a/src/ReactiveUI.Shared/Mixins/BuilderMixins.cs b/src/ReactiveUI.Shared/Mixins/BuilderMixins.cs index a050b79683..a0bf071335 100644 --- a/src/ReactiveUI.Shared/Mixins/BuilderMixins.cs +++ b/src/ReactiveUI.Shared/Mixins/BuilderMixins.cs @@ -78,10 +78,6 @@ public IReactiveUIBuilder BuildApp() /// ]]> /// /// - [SuppressMessage( - "Design", - "SST2326:Interface instances should not be narrowed to concrete types", - Justification = "DefaultViewLocator exposes view-registration APIs not present on IViewLocator; reaching them requires the concrete type.")] public IReactiveUIBuilder RegisterViews( Action configure) { @@ -90,8 +86,8 @@ public IReactiveUIBuilder RegisterViews( var viewLocator = (AppLocator.Current.GetService() as DefaultViewLocator) ?? throw new InvalidOperationException( - "DefaultViewLocator must be registered before calling RegisterViews. " + - "Ensure you've called WithPlatformModule() or manually registered DefaultViewLocator."); + "DefaultViewLocator must be registered before calling RegisterViews. " + + "Ensure you've called WithPlatformModule() or manually registered DefaultViewLocator."); ViewMappingBuilder mappingBuilder = new(viewLocator); configure(mappingBuilder); @@ -125,10 +121,6 @@ public IReactiveUIBuilder RegisterViews( /// ]]> /// /// - [SuppressMessage( - "Design", - "SST2326:Interface instances should not be narrowed to concrete types", - Justification = "DefaultViewLocator exposes view-registration APIs not present on IViewLocator; reaching them requires the concrete type.")] public IReactiveUIBuilder WithViewModule() where TModule : IViewModule, new() { @@ -136,8 +128,8 @@ public IReactiveUIBuilder WithViewModule() var viewLocator = (AppLocator.Current.GetService() as DefaultViewLocator) ?? throw new InvalidOperationException( - "DefaultViewLocator must be registered before calling WithViewModule. " + - "Ensure you've called WithPlatformModule() or manually registered DefaultViewLocator."); + "DefaultViewLocator must be registered before calling WithViewModule. " + + "Ensure you've called WithPlatformModule() or manually registered DefaultViewLocator."); TModule module = new(); module.RegisterViews(viewLocator); diff --git a/src/ReactiveUI.Shared/Mixins/ObservableLoggingMixins.cs b/src/ReactiveUI.Shared/Mixins/ObservableLoggingMixins.cs index 183518f671..5b2e34d2ed 100644 --- a/src/ReactiveUI.Shared/Mixins/ObservableLoggingMixins.cs +++ b/src/ReactiveUI.Shared/Mixins/ObservableLoggingMixins.cs @@ -29,8 +29,7 @@ public static class ObservableLoggingMixins /// An observable sequence that logs each notification using the provided logger. public IObservable Log( TObj logObject) - where TObj : IEnableLogger - => + where TObj : IEnableLogger => Log(@this, logObject, null, null); /// Returns an observable sequence that logs each notification using the specified logger object and message. @@ -41,8 +40,7 @@ public IObservable Log( public IObservable Log( TObj logObject, string? message) - where TObj : IEnableLogger - => + where TObj : IEnableLogger => Log(@this, logObject, message, null); /// Returns an observable sequence that logs each notification using the specified logger object. @@ -192,8 +190,7 @@ public IDisposable Subscribe(IObserver observer) /// Invoked with the error before it is forwarded. /// Invoked on completion before it is forwarded. /// The observer that receives the forwarded notifications. - private sealed class Sink(Action onNext, Action onError, Action onCompleted, IObserver downstream) - : IObserver + private sealed class Sink(Action onNext, Action onError, Action onCompleted, IObserver downstream) : IObserver { /// public void OnNext(T value) @@ -271,8 +268,7 @@ public IDisposable Subscribe(IObserver observer) /// Forwards the source, switching to the handler's continuation on a matching exception. /// Produces the continuation observable for a caught exception. /// The observer that receives the forwarded notifications. - private sealed class Sink(Func> handler, IObserver downstream) - : IObserver, IDisposable + private sealed class Sink(Func> handler, IObserver downstream) : IObserver, IDisposable { /// The source subscription; disposed when switching to the continuation. private readonly OnceDisposable _source = new(); diff --git a/src/ReactiveUI.Shared/Mixins/ObservedChangedMixins.cs b/src/ReactiveUI.Shared/Mixins/ObservedChangedMixins.cs index 8380151ab5..dc9e98d161 100644 --- a/src/ReactiveUI.Shared/Mixins/ObservedChangedMixins.cs +++ b/src/ReactiveUI.Shared/Mixins/ObservedChangedMixins.cs @@ -147,8 +147,7 @@ internal void SetValueToProperty( /// The observed value type. /// The source stream of observed changes. [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] - private sealed class ValueObservable(IObservable> source) - : IObservable + private sealed class ValueObservable(IObservable> source) : IObservable { /// public IDisposable Subscribe(IObserver observer) diff --git a/src/ReactiveUI.Shared/Mixins/ReactiveNotifyPropertyChangedMixins.cs b/src/ReactiveUI.Shared/Mixins/ReactiveNotifyPropertyChangedMixins.cs index 61dc51e311..5239867ebb 100644 --- a/src/ReactiveUI.Shared/Mixins/ReactiveNotifyPropertyChangedMixins.cs +++ b/src/ReactiveUI.Shared/Mixins/ReactiveNotifyPropertyChangedMixins.cs @@ -71,8 +71,8 @@ private static string MissingObservableForPropertyMessage(Type senderType, strin { var prefix = $"Could not find a ICreatesObservableForProperty for {senderType} property {propertyName}."; const string advice = - " This should never happen, your service locator is probably broken. Please make sure you have installed " + - "the latest version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."; + " This should never happen, your service locator is probably broken. Please make sure you have installed " + + "the latest version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."; return prefix + advice; } @@ -156,8 +156,8 @@ static TValue GetCurrentValue(TSender sender, string name) [RequiresUnreferencedCode( "Creating Expressions requires unreferenced code because the members being referenced by the Expression may be trimmed.")] public IObservable> ObservableForProperty( - string propertyName) - => ObservableForProperty( + string propertyName) => + ObservableForProperty( item, propertyName, beforeChange: false, @@ -173,8 +173,8 @@ public IObservable> ObservableForProperty> ObservableForProperty( string propertyName, - bool beforeChange) - => ObservableForProperty( + bool beforeChange) => + ObservableForProperty( item, propertyName, beforeChange: beforeChange, @@ -194,8 +194,8 @@ public IObservable> ObservableForProperty> ObservableForProperty( string propertyName, bool beforeChange, - bool skipInitial) - => ObservableForProperty( + bool skipInitial) => + ObservableForProperty( item, propertyName, beforeChange: beforeChange, @@ -329,8 +329,8 @@ public IObservable> ObservableForPropertyIf we cannot cast from the target value from the specified last property. [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public IObservable> SubscribeToExpressionChain( - Expression? expression) - => SubscribeToExpressionChain(item, expression, false, true, false, true); + Expression? expression) => + SubscribeToExpressionChain(item, expression, false, true, false, true); /// /// Creates a observable which will subscribe to the each property and sub property @@ -347,8 +347,8 @@ public IObservable> SubscribeToExpressionChain< [RequiresUnreferencedCode("Evaluates expression-based member chains via reflection; members may be trimmed.")] public IObservable> SubscribeToExpressionChain( Expression? expression, - bool beforeChange) - => SubscribeToExpressionChain(item, expression, beforeChange, true, false, true); + bool beforeChange) => + SubscribeToExpressionChain(item, expression, beforeChange, true, false, true); /// /// Creates a observable which will subscribe to the each property and sub property @@ -367,8 +367,8 @@ public IObservable> SubscribeToExpressionChain< public IObservable> SubscribeToExpressionChain( Expression? expression, bool beforeChange, - bool skipInitial) - => SubscribeToExpressionChain(item, expression, beforeChange, skipInitial, false, true); + bool skipInitial) => + SubscribeToExpressionChain(item, expression, beforeChange, skipInitial, false, true); /// /// Creates a observable which will subscribe to the each property and sub property @@ -389,8 +389,8 @@ public IObservable> SubscribeToExpressionChain< Expression? expression, bool beforeChange, bool skipInitial, - bool suppressWarnings) - => SubscribeToExpressionChain( + bool suppressWarnings) => + SubscribeToExpressionChain( item, expression, beforeChange, diff --git a/src/ReactiveUI.Shared/Mixins/SwitchSubscribeMixins.cs b/src/ReactiveUI.Shared/Mixins/SwitchSubscribeMixins.cs index ece8756765..2ef59dda73 100644 --- a/src/ReactiveUI.Shared/Mixins/SwitchSubscribeMixins.cs +++ b/src/ReactiveUI.Shared/Mixins/SwitchSubscribeMixins.cs @@ -345,8 +345,7 @@ public IDisposable Subscribe(IObserver observer) /// Subscribes to the source, switching the active inner subscription on each non-null value. /// Projects each non-null source value to an inner observable. /// The observer that receives the forwarded inner notifications. - private sealed class Sink(Func> selector, IObserver downstream) - : IObserver, IDisposable + private sealed class Sink(Func> selector, IObserver downstream) : IObserver, IDisposable { /// Guards the switching state so outer and inner notifications stay consistent. #if NET9_0_OR_GREATER diff --git a/src/ReactiveUI.Shared/ObservableForProperty/OAPHCreationHelperMixins.cs b/src/ReactiveUI.Shared/ObservableForProperty/OAPHCreationHelperMixins.cs index cf9e1f22f9..9e78faf843 100644 --- a/src/ReactiveUI.Shared/ObservableForProperty/OAPHCreationHelperMixins.cs +++ b/src/ReactiveUI.Shared/ObservableForProperty/OAPHCreationHelperMixins.cs @@ -212,8 +212,8 @@ public ObservableAsPropertyHelper ToProperty( TRet initialValue, bool deferSubscription, ISequencer? scheduler) - where TObj : class, IReactiveObject - => ToProperty(target, source, property, () => initialValue, deferSubscription, scheduler); + where TObj : class, IReactiveObject => + ToProperty(target, source, property, () => initialValue, deferSubscription, scheduler); /// /// Converts an Observable to an ObservableAsPropertyHelper and @@ -477,8 +477,8 @@ public ObservableAsPropertyHelper ToProperty( TRet initialValue, bool deferSubscription, ISequencer? scheduler) - where TObj : class, IReactiveObject - => ToProperty(target, source, property, out result, () => initialValue, deferSubscription, scheduler); + where TObj : class, IReactiveObject => + ToProperty(target, source, property, out result, () => initialValue, deferSubscription, scheduler); /// /// Converts an Observable to an ObservableAsPropertyHelper and @@ -662,8 +662,8 @@ public ObservableAsPropertyHelper ToProperty( TRet initialValue, bool deferSubscription, ISequencer? scheduler) - where TObj : class, IReactiveObject - => ToProperty(target, source, property, () => initialValue, deferSubscription, scheduler); + where TObj : class, IReactiveObject => + ToProperty(target, source, property, () => initialValue, deferSubscription, scheduler); /// /// Converts an Observable to an ObservableAsPropertyHelper and @@ -1055,8 +1055,8 @@ internal ObservableAsPropertyHelper ObservableToProperty( var expression = Reflection.Rewrite(property.Body); - var parent = expression.GetParent() ?? - throw new ArgumentException( + var parent = expression.GetParent() + ?? throw new ArgumentException( "The property expression does not have a valid parent.", nameof(property)); if (parent.NodeType != ExpressionType.Parameter) @@ -1064,8 +1064,8 @@ internal ObservableAsPropertyHelper ObservableToProperty( throw new ArgumentException("Property expression must be of the form 'x => x.SomeProperty'"); } - var memberInfo = expression.GetMemberInfo() ?? - throw new ArgumentException( + var memberInfo = expression.GetMemberInfo() + ?? throw new ArgumentException( "The property expression does not point towards a valid member.", nameof(property)); var name = memberInfo.Name; @@ -1113,8 +1113,8 @@ internal ObservableAsPropertyHelper ObservableToProperty( var expression = Reflection.Rewrite(property.Body); - var parent = expression.GetParent() ?? - throw new ArgumentException( + var parent = expression.GetParent() + ?? throw new ArgumentException( "The property expression does not have a valid parent.", nameof(property)); if (parent.NodeType != ExpressionType.Parameter) @@ -1122,8 +1122,8 @@ internal ObservableAsPropertyHelper ObservableToProperty( throw new ArgumentException("Property expression must be of the form 'x => x.SomeProperty'"); } - var memberInfo = expression.GetMemberInfo() ?? - throw new ArgumentException( + var memberInfo = expression.GetMemberInfo() + ?? throw new ArgumentException( "The property expression does not point towards a valid member.", nameof(property)); var name = memberInfo.Name; diff --git a/src/ReactiveUI.Shared/ObservableFuncMixins.cs b/src/ReactiveUI.Shared/ObservableFuncMixins.cs index 61b92d1929..6b47a6004a 100644 --- a/src/ReactiveUI.Shared/ObservableFuncMixins.cs +++ b/src/ReactiveUI.Shared/ObservableFuncMixins.cs @@ -93,8 +93,7 @@ public IDisposable Subscribe(IObserver observer) /// The source stream of observed changes. /// The observer receiving the projected values. [RequiresUnreferencedCode("Dynamic observation uses reflection over members that may be trimmed.")] - private sealed class Sink(IObservable> source, IObserver downstream) - : IObserver>, IDisposable + private sealed class Sink(IObservable> source, IObserver downstream) : IObserver>, IDisposable { /// The current source subscription; reassigned on each retry. private readonly SwapDisposable _subscription = new(); diff --git a/src/ReactiveUI.Shared/ReactiveCommand/ReactiveCommand.cs b/src/ReactiveUI.Shared/ReactiveCommand/ReactiveCommand.cs index bbd18cfc18..e7068e7072 100644 --- a/src/ReactiveUI.Shared/ReactiveCommand/ReactiveCommand.cs +++ b/src/ReactiveUI.Shared/ReactiveCommand/ReactiveCommand.cs @@ -118,7 +118,7 @@ public static ReactiveCommand Create( /// The ReactiveCommand instance. /// execute. public static ReactiveCommand Create(Func execute) => - Create(execute, null, null); + Create((Func)execute, null, null); /// Creates a parameterless reactive command with synchronous execution logic that returns a value of type TResult. /// The type of value returned by command executions. @@ -129,7 +129,7 @@ public static ReactiveCommand Create(Func exe public static ReactiveCommand Create( Func execute, IObservable? canExecute) => - Create(execute, canExecute, null); + Create((Func)execute, canExecute, null); /// Creates a parameterless reactive command with synchronous execution logic that returns a value of type TResult. /// The type of value returned by command executions. @@ -140,7 +140,7 @@ public static ReactiveCommand Create( public static ReactiveCommand Create( Func execute, ISequencer? outputScheduler) => - Create(execute, null, outputScheduler); + Create((Func)execute, null, outputScheduler); /// Creates a parameterless with synchronous execution logic that returns a value of type . /// The type of value returned by command executions. @@ -170,7 +170,7 @@ public static ReactiveCommand Create( /// The ReactiveCommand instance. /// execute. public static ReactiveCommand Create(Action execute) => - Create(execute, null, null); + Create((Action)execute, null, null); /// Creates a reactive command with synchronous execution logic that takes a parameter of type TParam. /// The type of the parameter passed through to command execution. @@ -181,7 +181,7 @@ public static ReactiveCommand Create(Action exec public static ReactiveCommand Create( Action execute, IObservable? canExecute) => - Create(execute, canExecute, null); + Create((Action)execute, canExecute, null); /// Creates a reactive command with synchronous execution logic that takes a parameter of type TParam. /// The type of the parameter passed through to command execution. @@ -192,7 +192,7 @@ public static ReactiveCommand Create( public static ReactiveCommand Create( Action execute, ISequencer? outputScheduler) => - Create(execute, null, outputScheduler); + Create((Action)execute, null, outputScheduler); /// Creates a with synchronous execution logic that takes a parameter of type . /// The type of the parameter passed through to command execution. @@ -231,7 +231,7 @@ public static ReactiveCommand Create( /// The ReactiveCommand instance. /// execute. public static ReactiveCommand Create(Func execute) => - Create(execute, null, null); + Create((Func)execute, null, null); /// /// Creates a reactive command with synchronous execution logic that takes a parameter of type TParam and returns a value of type TResult. @@ -245,7 +245,7 @@ public static ReactiveCommand Create(Func Create( Func execute, IObservable? canExecute) => - Create(execute, canExecute, null); + Create((Func)execute, canExecute, null); /// /// Creates a reactive command with synchronous execution logic that takes a parameter of type TParam and returns a value of type TResult. @@ -259,7 +259,7 @@ public static ReactiveCommand Create( public static ReactiveCommand Create( Func execute, ISequencer? outputScheduler) => - Create(execute, null, outputScheduler); + Create((Func)execute, null, outputScheduler); /// Creates a synchronous from to . /// The type of the parameter passed through to command execution. @@ -362,7 +362,7 @@ public static ReactiveCommand CreateRunInBackground( /// The ReactiveCommand instance. /// execute. public static ReactiveCommand CreateRunInBackground(Func execute) => - CreateRunInBackground(execute, null, null, null); + CreateRunInBackground((Func)execute, null, null, null); /// /// Creates a parameterless reactive command with asynchronous background execution logic that returns a value of type TResult. @@ -375,7 +375,7 @@ public static ReactiveCommand CreateRunInBackground(Fu public static ReactiveCommand CreateRunInBackground( Func execute, IObservable? canExecute) => - CreateRunInBackground(execute, canExecute, null, null); + CreateRunInBackground((Func)execute, canExecute, null, null); /// /// Creates a parameterless reactive command with asynchronous background execution logic that returns a value of type TResult. @@ -390,7 +390,7 @@ public static ReactiveCommand CreateRunInBackground( Func execute, IObservable? canExecute, ISequencer? backgroundScheduler) => - CreateRunInBackground(execute, canExecute, backgroundScheduler, null); + CreateRunInBackground((Func)execute, canExecute, backgroundScheduler, null); /// /// Creates a parameterless reactive command with asynchronous background execution logic that returns a value of type TResult. @@ -405,7 +405,7 @@ public static ReactiveCommand CreateRunInBackground( Func execute, ISequencer? backgroundScheduler, ISequencer? outputScheduler) => - CreateRunInBackground(execute, null, backgroundScheduler, outputScheduler); + CreateRunInBackground((Func)execute, null, backgroundScheduler, outputScheduler); /// Creates a parameterless with asynchronous execution logic that returns a value of type . /// The type of value returned by command executions. @@ -437,7 +437,7 @@ public static ReactiveCommand CreateRunInBackground( /// The ReactiveCommand instance. /// execute. public static ReactiveCommand CreateRunInBackground(Action execute) => - CreateRunInBackground(execute, null, null, null); + CreateRunInBackground((Action)execute, null, null, null); /// Creates a reactive command with asynchronous background execution logic that takes a parameter of type TParam. /// The type of the parameter passed through to command execution. @@ -448,7 +448,7 @@ public static ReactiveCommand CreateRunInBackground(Acti public static ReactiveCommand CreateRunInBackground( Action execute, IObservable? canExecute) => - CreateRunInBackground(execute, canExecute, null, null); + CreateRunInBackground((Action)execute, canExecute, null, null); /// Creates a reactive command with asynchronous background execution logic that takes a parameter of type TParam. /// The type of the parameter passed through to command execution. @@ -461,7 +461,7 @@ public static ReactiveCommand CreateRunInBackground( Action execute, IObservable? canExecute, ISequencer? backgroundScheduler) => - CreateRunInBackground(execute, canExecute, backgroundScheduler, null); + CreateRunInBackground((Action)execute, canExecute, backgroundScheduler, null); /// Creates a reactive command with asynchronous background execution logic that takes a parameter of type TParam. /// The type of the parameter passed through to command execution. @@ -474,7 +474,7 @@ public static ReactiveCommand CreateRunInBackground( Action execute, ISequencer? backgroundScheduler, ISequencer? outputScheduler) => - CreateRunInBackground(execute, null, backgroundScheduler, outputScheduler); + CreateRunInBackground((Action)execute, null, backgroundScheduler, outputScheduler); /// Creates a with asynchronous execution logic that takes a parameter of type . /// The type of the parameter passed through to command execution. @@ -516,7 +516,7 @@ public static ReactiveCommand CreateRunInBackground( /// The ReactiveCommand instance. /// execute. public static ReactiveCommand CreateRunInBackground(Func execute) => - CreateRunInBackground(execute, null, null, null); + CreateRunInBackground((Func)execute, null, null, null); /// /// Creates a reactive command with asynchronous background execution logic that takes a parameter of type TParam and returns a value of type TResult. @@ -530,7 +530,7 @@ public static ReactiveCommand CreateRunInBackground CreateRunInBackground( Func execute, IObservable? canExecute) => - CreateRunInBackground(execute, canExecute, null, null); + CreateRunInBackground((Func)execute, canExecute, null, null); /// /// Creates a reactive command with asynchronous background execution logic that takes a parameter of type TParam and returns a value of type TResult. @@ -546,7 +546,7 @@ public static ReactiveCommand CreateRunInBackground execute, IObservable? canExecute, ISequencer? backgroundScheduler) => - CreateRunInBackground(execute, canExecute, backgroundScheduler, null); + CreateRunInBackground((Func)execute, canExecute, backgroundScheduler, null); /// /// Creates a reactive command with asynchronous background execution logic that takes a parameter of type TParam and returns a value of type TResult. @@ -562,7 +562,7 @@ public static ReactiveCommand CreateRunInBackground execute, ISequencer? backgroundScheduler, ISequencer? outputScheduler) => - CreateRunInBackground(execute, null, backgroundScheduler, outputScheduler); + CreateRunInBackground((Func)execute, null, backgroundScheduler, outputScheduler); /// Creates an asynchronous from to . /// The type of the parameter passed through to command execution. @@ -715,7 +715,7 @@ public static ReactiveCommand CreateFromObservable( /// The ReactiveCommand instance. public static ReactiveCommand CreateFromObservable( Func> execute) => - CreateFromObservable(execute, null, null); + CreateFromObservable((Func>)execute, null, null); /// Creates a reactive command with asynchronous observable execution logic that takes a parameter of type TParam. /// The type of the parameter passed through to command execution. @@ -726,7 +726,7 @@ public static ReactiveCommand CreateFromObservable CreateFromObservable( Func> execute, IObservable? canExecute) => - CreateFromObservable(execute, canExecute, null); + CreateFromObservable((Func>)execute, canExecute, null); /// Creates a reactive command with asynchronous observable execution logic that takes a parameter of type TParam. /// The type of the parameter passed through to command execution. @@ -738,7 +738,7 @@ public static ReactiveCommand CreateFromObservable CreateFromObservable( Func> execute, ISequencer? outputScheduler) => - CreateFromObservable(execute, null, outputScheduler); + CreateFromObservable((Func>)execute, null, outputScheduler); /// Creates a with asynchronous execution logic that takes a parameter of type . /// @@ -833,7 +833,7 @@ public static ReactiveCommand CreateFromTask( /// The ReactiveCommand instance. public static ReactiveCommand CreateFromTask( Func> execute) => - CreateFromTask(execute, null, null); + CreateFromTask((Func>)execute, null, null); /// Creates a parameterless, cancellable reactive command with asynchronous task-based execution logic returning TResult. /// The type of the command's result. @@ -843,7 +843,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func> execute, IObservable? canExecute) => - CreateFromTask(execute, canExecute, null); + CreateFromTask((Func>)execute, canExecute, null); /// Creates a parameterless, cancellable reactive command with asynchronous task-based execution logic returning TResult. /// The type of the command's result. @@ -854,7 +854,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func> execute, ISequencer? outputScheduler) => - CreateFromTask(execute, null, outputScheduler); + CreateFromTask((Func>)execute, null, outputScheduler); /// Creates a parameterless, cancellable with asynchronous execution logic. /// @@ -889,7 +889,7 @@ public static ReactiveCommand CreateFromTask( /// Provides a Task representing the command's asynchronous execution logic. /// The ReactiveCommand instance. public static ReactiveCommand CreateFromTask(Func execute) => - CreateFromTask(execute, null, null); + CreateFromTask((Func)execute, null, null); /// Creates a parameterless reactive command with asynchronous task-based execution logic. /// Provides a Task representing the command's asynchronous execution logic. @@ -898,7 +898,7 @@ public static ReactiveCommand CreateFromTask(Func execute) public static ReactiveCommand CreateFromTask( Func execute, IObservable? canExecute) => - CreateFromTask(execute, canExecute, null); + CreateFromTask((Func)execute, canExecute, null); /// Creates a parameterless reactive command with asynchronous task-based execution logic. /// Provides a Task representing the command's asynchronous execution logic. @@ -908,7 +908,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func execute, ISequencer? outputScheduler) => - CreateFromTask(execute, null, outputScheduler); + CreateFromTask((Func)execute, null, outputScheduler); /// Creates a parameterless with asynchronous execution logic. /// @@ -937,7 +937,7 @@ public static ReactiveCommand CreateFromTask( /// Provides a Task representing the command's asynchronous execution logic. /// The ReactiveCommand instance. public static ReactiveCommand CreateFromTask(Func execute) => - CreateFromTask(execute, null, null); + CreateFromTask((Func)execute, null, null); /// Creates a parameterless, cancellable reactive command with asynchronous task-based execution logic. /// Provides a Task representing the command's asynchronous execution logic. @@ -946,7 +946,7 @@ public static ReactiveCommand CreateFromTask(Func CreateFromTask( Func execute, IObservable? canExecute) => - CreateFromTask(execute, canExecute, null); + CreateFromTask((Func)execute, canExecute, null); /// Creates a parameterless, cancellable reactive command with asynchronous task-based execution logic. /// Provides a Task representing the command's asynchronous execution logic. @@ -956,7 +956,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func execute, ISequencer? outputScheduler) => - CreateFromTask(execute, null, outputScheduler); + CreateFromTask((Func)execute, null, outputScheduler); /// Creates a parameterless, cancellable with asynchronous execution logic. /// @@ -993,7 +993,7 @@ public static ReactiveCommand CreateFromTask( /// The ReactiveCommand instance. public static ReactiveCommand CreateFromTask( Func> execute) => - CreateFromTask(execute, null, null); + CreateFromTask((Func>)execute, null, null); /// /// Creates a reactive command with asynchronous task-based execution logic that takes a parameter of type TParam and returns TResult. @@ -1006,7 +1006,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func> execute, IObservable? canExecute) => - CreateFromTask(execute, canExecute, null); + CreateFromTask((Func>)execute, canExecute, null); /// /// Creates a reactive command with asynchronous task-based execution logic that takes a parameter of type TParam and returns TResult. @@ -1020,7 +1020,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func> execute, ISequencer? outputScheduler) => - CreateFromTask(execute, null, outputScheduler); + CreateFromTask((Func>)execute, null, outputScheduler); /// Creates a with asynchronous execution logic that takes a parameter of type . /// @@ -1063,7 +1063,7 @@ public static ReactiveCommand CreateFromTask( /// The ReactiveCommand instance. public static ReactiveCommand CreateFromTask( Func> execute) => - CreateFromTask(execute, null, null); + CreateFromTask((Func>)execute, null, null); /// /// Creates a reactive command with asynchronous, cancellable task-based execution logic that takes TParam and returns TResult. @@ -1076,7 +1076,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func> execute, IObservable? canExecute) => - CreateFromTask(execute, canExecute, null); + CreateFromTask((Func>)execute, canExecute, null); /// /// Creates a reactive command with asynchronous, cancellable task-based execution logic that takes TParam and returns TResult. @@ -1090,7 +1090,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func> execute, ISequencer? outputScheduler) => - CreateFromTask(execute, null, outputScheduler); + CreateFromTask((Func>)execute, null, outputScheduler); /// Creates a with asynchronous, cancellable execution logic that takes a parameter of type . /// @@ -1130,7 +1130,7 @@ public static ReactiveCommand CreateFromTask( /// The ReactiveCommand instance. public static ReactiveCommand CreateFromTask( Func execute) => - CreateFromTask(execute, null, null); + CreateFromTask((Func)execute, null, null); /// Creates a reactive command with asynchronous task-based execution logic that takes a parameter of type TParam. /// The type of the parameter passed through to command execution. @@ -1140,7 +1140,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func execute, IObservable? canExecute) => - CreateFromTask(execute, canExecute, null); + CreateFromTask((Func)execute, canExecute, null); /// Creates a reactive command with asynchronous task-based execution logic that takes a parameter of type TParam. /// The type of the parameter passed through to command execution. @@ -1151,7 +1151,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func execute, ISequencer? outputScheduler) => - CreateFromTask(execute, null, outputScheduler); + CreateFromTask((Func)execute, null, outputScheduler); /// Creates a with asynchronous execution logic that takes a parameter of type . /// @@ -1190,7 +1190,7 @@ public static ReactiveCommand CreateFromTask( /// The ReactiveCommand instance. public static ReactiveCommand CreateFromTask( Func execute) => - CreateFromTask(execute, null, null); + CreateFromTask((Func)execute, null, null); /// /// Creates a reactive command with asynchronous, cancellable task-based execution logic that takes a parameter of type TParam. @@ -1202,7 +1202,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func execute, IObservable? canExecute) => - CreateFromTask(execute, canExecute, null); + CreateFromTask((Func)execute, canExecute, null); /// /// Creates a reactive command with asynchronous, cancellable task-based execution logic that takes a parameter of type TParam. @@ -1215,7 +1215,7 @@ public static ReactiveCommand CreateFromTask( public static ReactiveCommand CreateFromTask( Func execute, ISequencer? outputScheduler) => - CreateFromTask(execute, null, outputScheduler); + CreateFromTask((Func)execute, null, outputScheduler); /// Creates a with asynchronous, cancellable execution logic that takes a parameter of type . /// @@ -1261,7 +1261,7 @@ internal static ReactiveCommand CreateFromObservableCancellable IObservable? canExecute = null, ISequencer? outputScheduler = null) { - ArgumentExceptionHelper.ThrowIfNull(execute); + ArgumentExceptionHelper.ThrowIfNull((Func Result, Action Cancel)>>)execute); return new( _ => execute(), @@ -1293,7 +1293,7 @@ internal static ReactiveCommand CreateFromObservableCancellable IObservable? canExecute = null, ISequencer? outputScheduler = null) { - ArgumentExceptionHelper.ThrowIfNull(execute); + ArgumentExceptionHelper.ThrowIfNull((Func Result, Action Cancel)>>)execute); return new( execute, diff --git a/src/ReactiveUI.Shared/ReactiveCommand/ReactiveCommand{TParam,TResult}.cs b/src/ReactiveUI.Shared/ReactiveCommand/ReactiveCommand{TParam,TResult}.cs index 40ec39e96b..d913b9ad19 100644 --- a/src/ReactiveUI.Shared/ReactiveCommand/ReactiveCommand{TParam,TResult}.cs +++ b/src/ReactiveUI.Shared/ReactiveCommand/ReactiveCommand{TParam,TResult}.cs @@ -472,8 +472,7 @@ public IDisposable Subscribe(IObserver observer) /// /// The owning command. /// The observer subscribed to this execution. - private sealed class Execution(ReactiveCommand owner, IObserver downstream) - : IObserver<(IObservable Result, Action Cancel)>, IDisposable + private sealed class Execution(ReactiveCommand owner, IObserver downstream) : IObserver<(IObservable Result, Action Cancel)>, IDisposable { /// Subscription to the execution-source observable (the result/cancel tuple producer). private IDisposable? _outer; diff --git a/src/ReactiveUI.Shared/ReactiveObject/IReactiveObjectExtensions.cs b/src/ReactiveUI.Shared/ReactiveObject/IReactiveObjectExtensions.cs index 20ee3e89b4..fe5701e0ec 100644 --- a/src/ReactiveUI.Shared/ReactiveObject/IReactiveObjectExtensions.cs +++ b/src/ReactiveUI.Shared/ReactiveObject/IReactiveObjectExtensions.cs @@ -251,8 +251,7 @@ private static IExtensionState GetState(TSender reacti /// Re-types the change-argument stream from the non-generic form to the caller's . /// The reactive object type observed. /// The source change-argument stream. - private sealed class ChangeArgsCastObservable(IObservable> source) - : IObservable> + private sealed class ChangeArgsCastObservable(IObservable> source) : IObservable> where TSender : IReactiveObject { /// @@ -264,8 +263,7 @@ public IDisposable Subscribe(IObserverRe-types each change-argument value to the caller's sender type. /// The observer receiving re-typed change arguments. - private sealed class Sink(IObserver> downstream) - : IObserver> + private sealed class Sink(IObserver> downstream) : IObserver> { /// public void OnNext(IReactivePropertyChangedEventArgs value) => diff --git a/src/ReactiveUI.Shared/ReactiveObject/ReactiveObject.cs b/src/ReactiveUI.Shared/ReactiveObject/ReactiveObject.cs index 38d034fc3c..4f2c4208eb 100644 --- a/src/ReactiveUI.Shared/ReactiveObject/ReactiveObject.cs +++ b/src/ReactiveUI.Shared/ReactiveObject/ReactiveObject.cs @@ -37,6 +37,12 @@ public class ReactiveObject : IReactiveNotifyPropertyChanged, I [SuppressMessage("Design", "SST1424:Make field readonly", Justification = "Mutated in place through the ref returned by GetReactiveStateSlot.")] private object? _reactiveStateSlot; + /// Backing handler for the PropertyChanging event. + private PropertyChangingEventHandler? _propertyChangingHandler; + + /// Backing handler for the PropertyChanged event. + private PropertyChangedEventHandler? _propertyChangedHandler; + /// public event PropertyChangingEventHandler? PropertyChanging { @@ -48,9 +54,9 @@ public event PropertyChangingEventHandler? PropertyChanging _propertyChangingEventsSubscribed = true; } - PropertyChangingHandler += value; + _propertyChangingHandler += value; } - remove => PropertyChangingHandler -= value; + remove => _propertyChangingHandler -= value; } /// @@ -64,25 +70,11 @@ public event PropertyChangedEventHandler? PropertyChanged _propertyChangedEventsSubscribed = true; } - PropertyChangedHandler += value; + _propertyChangedHandler += value; } - remove => PropertyChangedHandler -= value; + remove => _propertyChangedHandler -= value; } - /// Backing handler for the PropertyChanging event. - [SuppressMessage( - "Design", - "SST2304:Events should use the standard handler signature", - Justification = "Backs the INotifyPropertyChanging.PropertyChanging interface event, whose fixed PropertyChangingEventHandler delegate is forwarded through this handler.")] - private event PropertyChangingEventHandler? PropertyChangingHandler; - - /// Backing handler for the PropertyChanged event. - [SuppressMessage( - "Design", - "SST2304:Events should use the standard handler signature", - Justification = "Backs the INotifyPropertyChanged.PropertyChanged interface event, whose fixed PropertyChangedEventHandler delegate is forwarded through this handler.")] - private event PropertyChangedEventHandler? PropertyChangedHandler; - /// [IgnoreDataMember] [JsonIgnore] @@ -91,8 +83,8 @@ public event PropertyChangedEventHandler? PropertyChanged [Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)] #endif public IObservable> Changing => - Volatile.Read(ref field) ?? - Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangingObservable(), null) ?? field; + Volatile.Read(ref field) + ?? Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangingObservable(), null) ?? field; /// [IgnoreDataMember] @@ -102,8 +94,8 @@ public event PropertyChangedEventHandler? PropertyChanged [Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)] #endif public IObservable> Changed => - Volatile.Read(ref field) ?? - Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangedObservable(), null) ?? field; + Volatile.Read(ref field) + ?? Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangedObservable(), null) ?? field; /// [IgnoreDataMember] @@ -113,16 +105,16 @@ public event PropertyChangedEventHandler? PropertyChanged [Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)] #endif public IObservable ThrownExceptions => - Volatile.Read(ref field) ?? - Interlocked.CompareExchange(ref field, this.GetThrownExceptionsObservable(), null) ?? field; + Volatile.Read(ref field) + ?? Interlocked.CompareExchange(ref field, this.GetThrownExceptionsObservable(), null) ?? field; /// void IReactiveObject.RaisePropertyChanging(PropertyChangingEventArgs args) => - PropertyChangingHandler?.Invoke(this, args); + _propertyChangingHandler?.Invoke(this, args); /// void IReactiveObject.RaisePropertyChanged(PropertyChangedEventArgs args) => - PropertyChangedHandler?.Invoke(this, args); + _propertyChangedHandler?.Invoke(this, args); /// public IDisposable SuppressChangeNotifications() => IReactiveObjectExtensions.SuppressChangeNotifications(this); diff --git a/src/ReactiveUI.Shared/ReactiveObject/ReactiveRecord.cs b/src/ReactiveUI.Shared/ReactiveObject/ReactiveRecord.cs index 29673c3dbf..16677eb956 100644 --- a/src/ReactiveUI.Shared/ReactiveObject/ReactiveRecord.cs +++ b/src/ReactiveUI.Shared/ReactiveObject/ReactiveRecord.cs @@ -9,7 +9,6 @@ using System.ComponentModel.DataAnnotations; #endif -using System.Diagnostics.CodeAnalysis; using System.Runtime.Serialization; using System.Text.Json.Serialization; @@ -32,6 +31,12 @@ public abstract record ReactiveRecord : IReactiveNotifyPropertyChangedTracks whether property-changed event subscriptions have been set up. private bool _propertyChangedEventsSubscribed; + /// Backing event store for property-changing notifications. + private PropertyChangingEventHandler? _propertyChangingHandler; + + /// Backing event store for property-changed notifications. + private PropertyChangedEventHandler? _propertyChangedHandler; + /// public event PropertyChangingEventHandler? PropertyChanging { @@ -43,9 +48,9 @@ public event PropertyChangingEventHandler? PropertyChanging _propertyChangingEventsSubscribed = true; } - PropertyChangingHandler += value; + _propertyChangingHandler += value; } - remove => PropertyChangingHandler -= value; + remove => _propertyChangingHandler -= value; } /// @@ -59,25 +64,11 @@ public event PropertyChangedEventHandler? PropertyChanged _propertyChangedEventsSubscribed = true; } - PropertyChangedHandler += value; + _propertyChangedHandler += value; } - remove => PropertyChangedHandler -= value; + remove => _propertyChangedHandler -= value; } - /// Backing event store for property-changing notifications. - [SuppressMessage( - "Design", - "SST2304:Events should use the standard handler signature", - Justification = "Backs the INotifyPropertyChanging.PropertyChanging interface event, whose fixed PropertyChangingEventHandler delegate is forwarded through this handler.")] - private event PropertyChangingEventHandler? PropertyChangingHandler; - - /// Backing event store for property-changed notifications. - [SuppressMessage( - "Design", - "SST2304:Events should use the standard handler signature", - Justification = "Backs the INotifyPropertyChanged.PropertyChanged interface event, whose fixed PropertyChangedEventHandler delegate is forwarded through this handler.")] - private event PropertyChangedEventHandler? PropertyChangedHandler; - /// [IgnoreDataMember] [JsonIgnore] @@ -86,8 +77,8 @@ public event PropertyChangedEventHandler? PropertyChanged [Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)] #endif public IObservable> Changing => - Volatile.Read(ref field) ?? - Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangingObservable(), null) ?? field; + Volatile.Read(ref field) + ?? Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangingObservable(), null) ?? field; /// [IgnoreDataMember] @@ -97,8 +88,8 @@ public event PropertyChangedEventHandler? PropertyChanged [Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)] #endif public IObservable> Changed => - Volatile.Read(ref field) ?? - Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangedObservable(), null) ?? field; + Volatile.Read(ref field) + ?? Interlocked.CompareExchange(ref field, ((IReactiveObject)this).GetChangedObservable(), null) ?? field; /// [IgnoreDataMember] @@ -107,19 +98,19 @@ public event PropertyChangedEventHandler? PropertyChanged [Browsable(false)] [Display(Order = -1, AutoGenerateField = false, AutoGenerateFilter = false)] #endif - public IObservable ThrownExceptions => Volatile.Read(ref field) ?? - Interlocked.CompareExchange( + public IObservable ThrownExceptions => Volatile.Read(ref field) + ?? Interlocked.CompareExchange( ref field, this.GetThrownExceptionsObservable(), null) ?? field; /// void IReactiveObject.RaisePropertyChanging(PropertyChangingEventArgs args) => - PropertyChangingHandler?.Invoke(this, args); + _propertyChangingHandler?.Invoke(this, args); /// void IReactiveObject.RaisePropertyChanged(PropertyChangedEventArgs args) => - PropertyChangedHandler?.Invoke(this, args); + _propertyChangedHandler?.Invoke(this, args); /// public IDisposable SuppressChangeNotifications() => IReactiveObjectExtensions.SuppressChangeNotifications(this); diff --git a/src/ReactiveUI.Shared/ReactiveProperty/ReactiveProperty.cs b/src/ReactiveUI.Shared/ReactiveProperty/ReactiveProperty.cs index d5f3749d97..fcb407d915 100644 --- a/src/ReactiveUI.Shared/ReactiveProperty/ReactiveProperty.cs +++ b/src/ReactiveUI.Shared/ReactiveProperty/ReactiveProperty.cs @@ -192,8 +192,8 @@ public T? Value /// Uses RxSchedulers.TaskpoolScheduler as the default scheduler. /// /// A new ReactiveProperty instance. - public static ReactiveProperty Create() - => new(default, RxSchedulers.TaskpoolScheduler, false, false); + public static ReactiveProperty Create() => + new(default, RxSchedulers.TaskpoolScheduler, false, false); /// /// Creates a new instance of ReactiveProperty with an initial value without requiring RequiresUnreferencedCode attributes. @@ -201,8 +201,8 @@ public static ReactiveProperty Create() /// /// The initial value. /// A new ReactiveProperty instance. - public static ReactiveProperty Create(T? initialValue) - => new(initialValue, RxSchedulers.TaskpoolScheduler, false, false); + public static ReactiveProperty Create(T? initialValue) => + new(initialValue, RxSchedulers.TaskpoolScheduler, false, false); /// /// Creates a new instance of ReactiveProperty with configuration options without requiring RequiresUnreferencedCode attributes. @@ -289,7 +289,7 @@ public ReactiveProperty AddValidationError( /// The current ReactiveProperty instance with the validation rule applied. public ReactiveProperty AddValidationError( Func, IObservable> validator) => - AddValidationError(validator, false); + AddValidationError((Func, IObservable>)validator, false); /// Adds a validation rule to the property using the specified validator function. /// Multiple validation rules can be added by calling this method multiple times. Validation @@ -310,7 +310,7 @@ public ReactiveProperty AddValidationError( /// The current ReactiveProperty instance with the specified validation logic applied. public ReactiveProperty AddValidationError( Func> validator) => - AddValidationError(validator, false); + AddValidationError((Func>)validator, false); /// Adds asynchronous validation logic to the reactive property using the specified validator function. /// This method enables chaining of multiple validation rules on a ReactiveProperty. @@ -330,7 +330,7 @@ public ReactiveProperty AddValidationError( /// A function that asynchronously validates the property's value and returns an error message or null. /// The current ReactiveProperty instance with the validation rule applied. public ReactiveProperty AddValidationError(Func> validator) => - AddValidationError(validator, false); + AddValidationError((Func>)validator, false); /// Adds an asynchronous validation rule to the property using the specified validator function. /// The validator function is invoked whenever the property's value changes. If multiple @@ -346,7 +346,7 @@ public ReactiveProperty AddValidationError(Func> validator, /// A function that takes the current value and returns a collection of validation errors. /// The current ReactiveProperty instance with the validation rule applied. public ReactiveProperty AddValidationError(Func validator) => - AddValidationError(validator, false); + AddValidationError((Func)validator, false); /// Adds a validation rule to the reactive property using the specified validator function. /// If multiple validation rules are added, all validators are evaluated and their errors are @@ -362,7 +362,7 @@ public ReactiveProperty AddValidationError(Func validator, /// A function that returns a validation error message or null if the value is valid. /// The current ReactiveProperty instance with the validation rule applied. public ReactiveProperty AddValidationError(Func validator) => - AddValidationError(validator, false); + AddValidationError((Func)validator, false); /// Adds a validation rule to the property using the specified validator function. /// If multiple validation rules are added, all validators are evaluated and their error messages @@ -683,10 +683,6 @@ private void OnNextAt(int index, IEnumerable? value) /// the remaining sequences, then both are copied once into a pre-sized result (strings first). /// /// The aggregated errors, or when every validator reported null. - [SuppressMessage( - "Design", - "SST2326:Interface instances should not be narrowed to concrete types", - Justification = "A string is an IEnumerable of chars; the test distinguishes a scalar string from the collection validators so it is emitted as one value rather than flattened.")] private object?[]? BuildAggregate() { if (Array.TrueForAll(_latest, static x => x is null)) diff --git a/src/ReactiveUI.Shared/ReactiveProperty/ReactivePropertyMixins.cs b/src/ReactiveUI.Shared/ReactiveProperty/ReactivePropertyMixins.cs index 88eb5e5b1c..c9a2e2aabd 100644 --- a/src/ReactiveUI.Shared/ReactiveProperty/ReactivePropertyMixins.cs +++ b/src/ReactiveUI.Shared/ReactiveProperty/ReactivePropertyMixins.cs @@ -52,11 +52,7 @@ public ReactiveProperty AddValidation( var display = propertyInfo.GetCustomAttribute(); ValidationAttribute[] attrs = [.. propertyInfo.GetCustomAttributes()]; - ValidationContext context = new(self, null, null) - { - DisplayName = display?.GetName() ?? propertyInfo.Name, - MemberName = nameof(ReactiveProperty<>.Value) - }; + ValidationContext context = new(self, null, null) { DisplayName = display?.GetName() ?? propertyInfo.Name, MemberName = nameof(ReactiveProperty<>.Value) }; if (attrs.Length != 0) { diff --git a/src/ReactiveUI.Shared/Routing/RoutableViewModelMixins.cs b/src/ReactiveUI.Shared/Routing/RoutableViewModelMixins.cs index 3477c33054..34ee5194d3 100644 --- a/src/ReactiveUI.Shared/Routing/RoutableViewModelMixins.cs +++ b/src/ReactiveUI.Shared/Routing/RoutableViewModelMixins.cs @@ -155,8 +155,7 @@ public IDisposable Subscribe(IObserver observer) /// The observer receiving the focus signal. /// The router whose current view model is inspected. /// The view model being watched. - private sealed class Sink(IObserver downstream, RoutingState router, IRoutableViewModel item) - : IObserver>, IDisposable + private sealed class Sink(IObserver downstream, RoutingState router, IRoutableViewModel item) : IObserver>, IDisposable { /// The subscription to the navigation-stack change stream. private IDisposable? _subscription; @@ -251,8 +250,7 @@ public IDisposable Subscribe(IObserver observer) /// The observer receiving the lost-focus signal. /// The router whose current view model is inspected. /// The view model being watched. - private sealed class Sink(IObserver downstream, RoutingState router, IRoutableViewModel item) - : IObserver>, IDisposable + private sealed class Sink(IObserver downstream, RoutingState router, IRoutableViewModel item) : IObserver>, IDisposable { /// The subscription to the navigation-stack change stream. private IDisposable? _subscription; diff --git a/src/ReactiveUI.Shared/RxState.cs b/src/ReactiveUI.Shared/RxState.cs index 66bb230643..f0c30a81f4 100644 --- a/src/ReactiveUI.Shared/RxState.cs +++ b/src/ReactiveUI.Shared/RxState.cs @@ -82,9 +82,9 @@ private static void InitializeDefaultExceptionHandler() } _ = RxSchedulers.MainThreadScheduler.Schedule(ex, static (_, capturedException) => throw new UnhandledErrorException( - "An object implementing IHandleObservableErrors (often a ReactiveCommand or ObservableAsPropertyHelper) has errored," + - " thereby breaking its observable pipeline. To prevent this, ensure the pipeline does not error, or Subscribe to the " + - "ThrownExceptions property of the object in question to handle the erroneous case.", + "An object implementing IHandleObservableErrors (often a ReactiveCommand or ObservableAsPropertyHelper) has errored," + + " thereby breaking its observable pipeline. To prevent this, ensure the pipeline does not error, or Subscribe to the " + + "ThrownExceptions property of the object in question to handle the erroneous case.", capturedException)); }); } diff --git a/src/ReactiveUI.Shared/Scheduler/WaitForDispatcherScheduler.cs b/src/ReactiveUI.Shared/Scheduler/WaitForDispatcherScheduler.cs index e4247d54ee..85a22952ed 100644 --- a/src/ReactiveUI.Shared/Scheduler/WaitForDispatcherScheduler.cs +++ b/src/ReactiveUI.Shared/Scheduler/WaitForDispatcherScheduler.cs @@ -45,14 +45,14 @@ public IDisposable Schedule( TState state, TimeSpan dueTime, Func action) => - AttemptToCreateScheduler().Schedule(state, dueTime, action); + ScheduleRelative(state, dueTime, action); /// public IDisposable Schedule( TState state, DateTimeOffset dueTime, Func action) => - AttemptToCreateScheduler().Schedule(state, dueTime, action); + ScheduleAbsolute(state, dueTime, action); #else /// public long Timestamp => AttemptToCreateScheduler().Timestamp; @@ -74,7 +74,7 @@ public IDisposable Schedule(TState state, FuncThe action to run. /// A disposable that cancels the scheduled work. public IDisposable Schedule(TState state, TimeSpan dueTime, Func action) => - AttemptToCreateScheduler().Schedule(state, dueTime, action); + ScheduleRelative(state, dueTime, action); /// Schedules at on the underlying scheduler, /// falling back to the current-thread scheduler when the dispatcher is not yet available. @@ -84,7 +84,7 @@ public IDisposable Schedule(TState state, TimeSpan dueTime, FuncThe action to run. /// A disposable that cancels the scheduled work. public IDisposable Schedule(TState state, DateTimeOffset dueTime, Func action) => - AttemptToCreateScheduler().Schedule(state, dueTime, action); + ScheduleAbsolute(state, dueTime, action); /// public void Schedule(IWorkItem item) => AttemptToCreateScheduler().Schedule(item); @@ -93,6 +93,33 @@ public IDisposable Schedule(TState state, DateTimeOffset dueTime, Func AttemptToCreateScheduler().Schedule(item, dueTimestamp); #endif + /// Schedules against a delay measured from the scheduler's current time. + /// The work item's state type. + /// The state supplied to the action. + /// The delay before execution. + /// The scheduled work. + /// A disposable that cancels the scheduled work. + private IDisposable ScheduleRelative( + TState state, + TimeSpan dueTime, + Func action) => + AttemptToCreateScheduler().Schedule(state, dueTime, action); + + /// Schedules against an absolute point on the scheduler's timeline. + /// The work item's state type. + /// The state supplied to the action. + /// The absolute execution time. + /// The scheduled work. + /// A disposable that cancels the scheduled work. + private IDisposable ScheduleAbsolute( + TState state, + DateTimeOffset dueTime, + Func action) + { + var scheduler = AttemptToCreateScheduler(); + return scheduler.Schedule(state, dueTime, action); + } + /// /// Attempts to create and return an instance of the scheduler. If the scheduler cannot be created, returns a /// fallback scheduler instance. diff --git a/src/ReactiveUI.Shared/Suspension/DummySuspensionDriver.cs b/src/ReactiveUI.Shared/Suspension/DummySuspensionDriver.cs index 8c467467b1..eef3d33568 100644 --- a/src/ReactiveUI.Shared/Suspension/DummySuspensionDriver.cs +++ b/src/ReactiveUI.Shared/Suspension/DummySuspensionDriver.cs @@ -22,31 +22,31 @@ public sealed class DummySuspensionDriver : ISuspensionDriver { /// [RequiresUnreferencedCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] + "Implementations commonly use reflection-based serialization. " + + "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] [RequiresDynamicCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] - public IObservable LoadState() - => new ReturnSignal(null, Sequencer.Immediate); + "Implementations commonly use reflection-based serialization. " + + "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] + public IObservable LoadState() => + new ReturnSignal(null, Sequencer.Immediate); /// public IObservable LoadState(JsonTypeInfo typeInfo) => new ReturnSignal(default, Sequencer.Immediate); /// [RequiresUnreferencedCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] + "Implementations commonly use reflection-based serialization. " + + "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] [RequiresDynamicCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] - public IObservable SaveState(T state) - => ImmutableReturnRxVoidSignal.Instance; + "Implementations commonly use reflection-based serialization. " + + "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] + public IObservable SaveState(T state) => + ImmutableReturnRxVoidSignal.Instance; /// public IObservable SaveState(T state, JsonTypeInfo typeInfo) => ImmutableReturnRxVoidSignal.Instance; /// - public IObservable InvalidateState() - => ImmutableReturnRxVoidSignal.Instance; + public IObservable InvalidateState() => + ImmutableReturnRxVoidSignal.Instance; } diff --git a/src/ReactiveUI.Shared/Suspension/SuspensionHostExtensions.cs b/src/ReactiveUI.Shared/Suspension/SuspensionHostExtensions.cs index 13fd2d12dd..c42ad89539 100644 --- a/src/ReactiveUI.Shared/Suspension/SuspensionHostExtensions.cs +++ b/src/ReactiveUI.Shared/Suspension/SuspensionHostExtensions.cs @@ -34,10 +34,6 @@ public static class SuspensionHostExtensions private static ISuspensionDriver? _suspensionDriver; /// Gets or sets the ensure load app state function. Internal for testing purposes only. - [SuppressMessage( - "Roslynator", - "RCS1085:Use auto-implemented property", - Justification = "Need explicit backing field for Interlocked.Exchange")] internal static Func>? EnsureLoadAppStateFunc { get => Volatile.Read(ref _ensureLoadAppStateFunc); @@ -45,10 +41,6 @@ internal static Func>? EnsureLoadAppStateFunc } /// Gets or sets the suspension driver. Internal for testing purposes only. - [SuppressMessage( - "Roslynator", - "RCS1085:Use auto-implemented property", - Justification = "Need explicit backing field for Interlocked.Exchange")] internal static ISuspensionDriver? SuspensionDriver { get => _suspensionDriver; @@ -67,11 +59,11 @@ internal static ISuspensionDriver? SuspensionDriver /// yet been materialized, ensuring late subscribers still receive persisted data. /// [RequiresUnreferencedCode( - "This overload may invoke ISuspensionDriver.LoadState(), which is commonly reflection-based. " + - "Prefer GetAppState(ISuspensionHost) used with SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] + "This overload may invoke ISuspensionDriver.LoadState(), which is commonly reflection-based. " + + "Prefer GetAppState(ISuspensionHost) used with SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] [RequiresDynamicCode( - "This overload may invoke ISuspensionDriver.LoadState(), which is commonly reflection-based. " + - "Prefer GetAppState(ISuspensionHost) used with SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] + "This overload may invoke ISuspensionDriver.LoadState(), which is commonly reflection-based. " + + "Prefer GetAppState(ISuspensionHost) used with SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] [SuppressMessage( "Design", "SST2307:Generic method type parameters should be inferable from the parameters", @@ -93,11 +85,11 @@ public T GetAppState() /// react to hot reloads or state restoration. /// [RequiresUnreferencedCode( - "This overload uses WhenAny, which can require unreferenced/dynamic code in trimming/AOT scenarios. " + - "Prefer ObserveAppState(ISuspensionHost) for trimming/AOT scenarios.")] + "This overload uses WhenAny, which can require unreferenced/dynamic code in trimming/AOT scenarios. " + + "Prefer ObserveAppState(ISuspensionHost) for trimming/AOT scenarios.")] [RequiresDynamicCode( - "This overload uses WhenAny, which can require unreferenced/dynamic code in trimming/AOT scenarios. " + - "Prefer ObserveAppState(ISuspensionHost) for trimming/AOT scenarios.")] + "This overload uses WhenAny, which can require unreferenced/dynamic code in trimming/AOT scenarios. " + + "Prefer ObserveAppState(ISuspensionHost) for trimming/AOT scenarios.")] [SuppressMessage( "Design", "SST2307:Generic method type parameters should be inferable from the parameters", @@ -115,11 +107,11 @@ public IObservable ObserveAppState() /// Setup our suspension driver for a class derived off ISuspensionHost interface using a resolved driver. /// A disposable which will stop responding to Suspend and Resume requests. [RequiresUnreferencedCode( - "This overload may invoke ISuspensionDriver.LoadState()/SaveState(T), which are commonly reflection-based. " + - "Prefer SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] + "This overload may invoke ISuspensionDriver.LoadState()/SaveState(T), which are commonly reflection-based. " + + "Prefer SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] [RequiresDynamicCode( - "This overload may invoke ISuspensionDriver.LoadState()/SaveState(T), which are commonly reflection-based. " + - "Prefer SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] + "This overload may invoke ISuspensionDriver.LoadState()/SaveState(T), which are commonly reflection-based. " + + "Prefer SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] public IDisposable SetupDefaultSuspendResume() => item.SetupDefaultSuspendResume(null); @@ -145,11 +137,11 @@ public IDisposable SetupDefaultSuspendResume() => /// /// [RequiresUnreferencedCode( - "This overload may invoke ISuspensionDriver.LoadState()/SaveState(T), which are commonly reflection-based. " + - "Prefer SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] + "This overload may invoke ISuspensionDriver.LoadState()/SaveState(T), which are commonly reflection-based. " + + "Prefer SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] [RequiresDynamicCode( - "This overload may invoke ISuspensionDriver.LoadState()/SaveState(T), which are commonly reflection-based. " + - "Prefer SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] + "This overload may invoke ISuspensionDriver.LoadState()/SaveState(T), which are commonly reflection-based. " + + "Prefer SetupDefaultSuspendResume(..., JsonTypeInfo, ...) for trimming/AOT scenarios.")] public IDisposable SetupDefaultSuspendResume(ISuspensionDriver? driver) { ArgumentExceptionHelper.ThrowIfNull(item); @@ -292,11 +284,11 @@ public IDisposable SetupDefaultSuspendResume( /// The suspension driver. /// A completed observable. [RequiresUnreferencedCode( - "This overload may invoke ISuspensionDriver.LoadState(), which is commonly reflection-based. " + - "Prefer EnsureLoadAppState(ISuspensionHost, ISuspensionDriver?, JsonTypeInfo) for trimming/AOT scenarios.")] + "This overload may invoke ISuspensionDriver.LoadState(), which is commonly reflection-based. " + + "Prefer EnsureLoadAppState(ISuspensionHost, ISuspensionDriver?, JsonTypeInfo) for trimming/AOT scenarios.")] [RequiresDynamicCode( - "This overload may invoke ISuspensionDriver.LoadState(), which is commonly reflection-based. " + - "Prefer EnsureLoadAppState(ISuspensionHost, ISuspensionDriver?, JsonTypeInfo) for trimming/AOT scenarios.")] + "This overload may invoke ISuspensionDriver.LoadState(), which is commonly reflection-based. " + + "Prefer EnsureLoadAppState(ISuspensionHost, ISuspensionDriver?, JsonTypeInfo) for trimming/AOT scenarios.")] private static IObservable EnsureLoadAppState(ISuspensionHost item, ISuspensionDriver? driver = null) { if (item.AppState is not null) diff --git a/src/ReactiveUI.WinUI/Builder/WinUIReactiveUIBuilderExtensions.cs b/src/ReactiveUI.WinUI/Builder/WinUIReactiveUIBuilderExtensions.cs index 242506868b..e01603e66c 100644 --- a/src/ReactiveUI.WinUI/Builder/WinUIReactiveUIBuilderExtensions.cs +++ b/src/ReactiveUI.WinUI/Builder/WinUIReactiveUIBuilderExtensions.cs @@ -17,8 +17,8 @@ public static class WinUIReactiveUIBuilderExtensions /// The lazily-initialized sequencer that marshals work onto the current WinUI dispatcher queue. private static readonly Lazy LazyWinUIMainThreadScheduler = new(static () => { - var dispatcherQueue = DispatcherQueue.GetForCurrentThread() ?? - throw new InvalidOperationException("There is no current dispatcher thread"); + var dispatcherQueue = DispatcherQueue.GetForCurrentThread() + ?? throw new InvalidOperationException("There is no current dispatcher thread"); return new DispatcherQueueSequencer(dispatcherQueue); }); diff --git a/src/ReactiveUI.Winforms/CreatesWinformsCommandBinding.cs b/src/ReactiveUI.Winforms/CreatesWinformsCommandBinding.cs index 7d7a1c90c2..973b739d65 100644 --- a/src/ReactiveUI.Winforms/CreatesWinformsCommandBinding.cs +++ b/src/ReactiveUI.Winforms/CreatesWinformsCommandBinding.cs @@ -47,8 +47,8 @@ public sealed class CreatesWinformsCommandBinding : ICreatesCommandBinding /// public int GetAffinityForObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] T>(bool hasEventTarget) { var isWinformControl = typeof(Control).IsAssignableFrom(typeof(T)); @@ -85,9 +85,9 @@ public int GetAffinityForObject< /// A disposable that unbinds the command, or null if no default event was found. /// Thrown when is . public IDisposable? BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T>(ICommand? command, T? target, IObservable commandParameter) where T : class { @@ -215,9 +215,9 @@ public IDisposable? BindCommandToObject< /// A disposable that unbinds the command. /// Thrown when , , or is . public IDisposable? BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T, TEventArgs>( ICommand? command, T? target, @@ -254,9 +254,9 @@ public IDisposable? BindCommandToObject< /// A disposable that unbinds the command. /// Thrown when , , or is . public IDisposable? BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T>( ICommand? command, T? target, diff --git a/src/ReactiveUI.Winforms/PanelSetMethodBindingConverter.cs b/src/ReactiveUI.Winforms/PanelSetMethodBindingConverter.cs index d666978588..75e4b611ba 100644 --- a/src/ReactiveUI.Winforms/PanelSetMethodBindingConverter.cs +++ b/src/ReactiveUI.Winforms/PanelSetMethodBindingConverter.cs @@ -24,8 +24,8 @@ public int GetAffinityForObjects(Type? fromType, Type? toType) } var implementsControlEnumerable = Array.Exists(fromType.GetInterfaces(), static x => - x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>) && - x.GetGenericArguments()[0].IsSubclassOf(typeof(Control))); + x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>) + && x.GetGenericArguments()[0].IsSubclassOf(typeof(Control))); return implementsControlEnumerable ? ControlCollectionAffinity : 0; } diff --git a/src/ReactiveUI.Winforms/TableContentSetMethodBindingConverter.cs b/src/ReactiveUI.Winforms/TableContentSetMethodBindingConverter.cs index a98979dcae..7b07217b4e 100644 --- a/src/ReactiveUI.Winforms/TableContentSetMethodBindingConverter.cs +++ b/src/ReactiveUI.Winforms/TableContentSetMethodBindingConverter.cs @@ -24,8 +24,8 @@ public int GetAffinityForObjects(Type? fromType, Type? toType) } var implementsControlEnumerable = Array.Exists(fromType.GetInterfaces(), static x => - x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>) && - x.GetGenericArguments()[0].IsSubclassOf(typeof(Control))); + x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>) + && x.GetGenericArguments()[0].IsSubclassOf(typeof(Control))); return implementsControlEnumerable ? ControlCollectionAffinity : 0; } diff --git a/src/ReactiveUI.Winforms/WinformsCreatesObservableForProperty.cs b/src/ReactiveUI.Winforms/WinformsCreatesObservableForProperty.cs index 03908acad9..791c2ca918 100644 --- a/src/ReactiveUI.Winforms/WinformsCreatesObservableForProperty.cs +++ b/src/ReactiveUI.Winforms/WinformsCreatesObservableForProperty.cs @@ -82,8 +82,8 @@ public int GetAffinityForObject(Type? type, string propertyName, bool beforeChan { ArgumentExceptionHelper.ThrowIfNull(sender); - var ei = EventInfoCache.Get((sender.GetType(), propertyName)) ?? - throw new InvalidOperationException("Could not find a valid event for expression."); + var ei = EventInfoCache.Get((sender.GetType(), propertyName)) + ?? throw new InvalidOperationException("Could not find a valid event for expression."); return new FromEventObservable>(onNext => { diff --git a/src/ReactiveUI.Wpf.Shared/Binding/ValidationBindingWpf.cs b/src/ReactiveUI.Wpf.Shared/Binding/ValidationBindingWpf.cs index af2cc9c18b..00d45469c7 100644 --- a/src/ReactiveUI.Wpf.Shared/Binding/ValidationBindingWpf.cs +++ b/src/ReactiveUI.Wpf.Shared/Binding/ValidationBindingWpf.cs @@ -153,8 +153,8 @@ internal static string ExtractControlName(Expression[] expressionChain, Type vie var controlExpression = expressionChain[lastIndex - 1]; var controlName = controlExpression.GetMemberInfo()?.Name; - return controlName ?? - throw new ArgumentException($"Control name not found on {viewType.Name}", nameof(expressionChain)); + return controlName + ?? throw new ArgumentException($"Control name not found on {viewType.Name}", nameof(expressionChain)); } /// Enumerates all dependency properties on a WPF element using reflection. @@ -269,13 +269,7 @@ internal IDisposable Bind() { _ = _control.SetBinding( _dependencyProperty, - new System.Windows.Data.Binding - { - Source = _viewModel, - Path = new(_viewModelPropertyName), - Mode = BindingMode.TwoWay, - UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged - }); + new System.Windows.Data.Binding { Source = _viewModel, Path = new(_viewModelPropertyName), Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); _inner = new(() => BindingOperations.ClearBinding(_control, _dependencyProperty)); @@ -331,8 +325,7 @@ private static IEnumerable FindControlsByNameIterator(Dependen /// /// The view model value stream. /// The view property change stream. - private sealed class ChangedObservable(IObservable viewModelValues, IObservable viewChanges) - : IObservable + private sealed class ChangedObservable(IObservable viewModelValues, IObservable viewChanges) : IObservable { /// public IDisposable Subscribe(IObserver observer) diff --git a/src/ReactiveUI.Wpf.Shared/Common/RoutedViewHost.cs b/src/ReactiveUI.Wpf.Shared/Common/RoutedViewHost.cs index 93fd7eda57..cfe6d1106c 100644 --- a/src/ReactiveUI.Wpf.Shared/Common/RoutedViewHost.cs +++ b/src/ReactiveUI.Wpf.Shared/Common/RoutedViewHost.cs @@ -73,9 +73,9 @@ public RoutedViewHost() // NB: This used to be an error but WPF design mode can't read // good or do other stuff good. this.Log().Error( - "Couldn't find an IPlatformOperations implementation. Please make sure you have installed " + - "the latest version of the ReactiveUI packages for your platform. " + - "See https://reactiveui.net/docs/getting-started/installation for guidance."); + "Couldn't find an IPlatformOperations implementation. Please make sure you have installed " + + "the latest version of the ReactiveUI packages for your platform. " + + "See https://reactiveui.net/docs/getting-started/installation for guidance."); } else { @@ -162,8 +162,8 @@ private void ResolveViewForViewModel((IRoutableViewModel? viewModel, string? con } var viewLocator = ViewLocator ?? ReactiveUI.ViewLocator.Current; - var view = (viewLocator.ResolveView(x.viewModel, x.contract) ?? viewLocator.ResolveView(x.viewModel)) ?? - throw new InvalidOperationException($"Couldn't find view for '{x.viewModel}'."); + var view = (viewLocator.ResolveView(x.viewModel, x.contract) ?? viewLocator.ResolveView(x.viewModel)) + ?? throw new InvalidOperationException($"Couldn't find view for '{x.viewModel}'."); view.ViewModel = x.viewModel; Content = view; } diff --git a/src/ReactiveUI.Wpf.Shared/Common/ViewModelViewHost.cs b/src/ReactiveUI.Wpf.Shared/Common/ViewModelViewHost.cs index 7265bbedab..3d2ddb1731 100644 --- a/src/ReactiveUI.Wpf.Shared/Common/ViewModelViewHost.cs +++ b/src/ReactiveUI.Wpf.Shared/Common/ViewModelViewHost.cs @@ -72,9 +72,9 @@ public ViewModelViewHost() // NB: This used to be an error but WPF design mode can't read // good or do other stuff good. this.Log().Error( - "Couldn't find an IPlatformOperations implementation. Please make sure you have installed " + - "the latest version of the ReactiveUI packages for your platform. " + - "See https://reactiveui.net/docs/getting-started/installation for guidance."); + "Couldn't find an IPlatformOperations implementation. Please make sure you have installed " + + "the latest version of the ReactiveUI packages for your platform. " + + "See https://reactiveui.net/docs/getting-started/installation for guidance."); } else { diff --git a/src/ReactiveUI.Wpf.Shared/TransitioningContentControl.cs b/src/ReactiveUI.Wpf.Shared/TransitioningContentControl.cs index 8559e6b495..7718340aa8 100644 --- a/src/ReactiveUI.Wpf.Shared/TransitioningContentControl.cs +++ b/src/ReactiveUI.Wpf.Shared/TransitioningContentControl.cs @@ -609,8 +609,8 @@ internal Storyboard GetTransitionStoryboardByName(string transitionName) } } - return transition ?? - throw new InvalidOperationException($"Transition '{transitionName}' not found in visual state group."); + return transition + ?? throw new InvalidOperationException($"Transition '{transitionName}' not found in visual state group."); } /// Sets default values for certain transition types. diff --git a/src/ReactiveUI/Platforms/android/AndroidObservableForWidgets.cs b/src/ReactiveUI/Platforms/android/AndroidObservableForWidgets.cs index 5bc71b5aae..61bffa437d 100644 --- a/src/ReactiveUI/Platforms/android/AndroidObservableForWidgets.cs +++ b/src/ReactiveUI/Platforms/android/AndroidObservableForWidgets.cs @@ -309,8 +309,8 @@ private static DispatchItem CreateFromWidget( where TEventArgs : EventArgs { var memberInfo = - property.Body.GetMemberInfo() ?? - throw new ArgumentException("Does not have a valid body member info.", nameof(property)); + property.Body.GetMemberInfo() + ?? throw new ArgumentException("Does not have a valid body member info.", nameof(property)); var propName = memberInfo.Name; @@ -327,8 +327,7 @@ private static DispatchItem CreateFromWidget( /// /// The adapter view to observe. /// The expression surfaced on the emitted change. - private sealed class AdapterSelectionObservable(AdapterView adapterView, Expression expression) - : IObservable> + private sealed class AdapterSelectionObservable(AdapterView adapterView, Expression expression) : IObservable> { /// public IDisposable Subscribe(IObserver> observer) @@ -367,8 +366,7 @@ private sealed class WidgetEventObservable( TView view, Expression expression, Action> addHandler, - Action> removeHandler) - : IObservable> + Action> removeHandler) : IObservable> where TView : View where TEventArgs : EventArgs { diff --git a/src/ReactiveUI/Platforms/android/AutoSuspendHelper.cs b/src/ReactiveUI/Platforms/android/AutoSuspendHelper.cs index 92835e3bbb..ad8dd742f9 100644 --- a/src/ReactiveUI/Platforms/android/AutoSuspendHelper.cs +++ b/src/ReactiveUI/Platforms/android/AutoSuspendHelper.cs @@ -202,8 +202,7 @@ private sealed class ObservableLifecycle( Signal onCreate, Signal onRestart, Signal onPause, - Signal onSaveInstanceState) - : Java.Lang.Object, Application.IActivityLifecycleCallbacks + Signal onSaveInstanceState) : Java.Lang.Object, Application.IActivityLifecycleCallbacks { /// public void OnActivityCreated(Activity? activity, Bundle? savedInstanceState) => diff --git a/src/ReactiveUI/Platforms/android/BundleSuspensionDriver.cs b/src/ReactiveUI/Platforms/android/BundleSuspensionDriver.cs index fb1d31b32f..31da27e5c8 100644 --- a/src/ReactiveUI/Platforms/android/BundleSuspensionDriver.cs +++ b/src/ReactiveUI/Platforms/android/BundleSuspensionDriver.cs @@ -27,11 +27,11 @@ public sealed class BundleSuspensionDriver : ISuspensionDriver /// [RequiresUnreferencedCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] + "Implementations commonly use reflection-based serialization. " + + "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] [RequiresDynamicCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] + "Implementations commonly use reflection-based serialization. " + + "Prefer LoadState(JsonTypeInfo) for trimming or AOT scenarios.")] public IObservable LoadState() { try @@ -89,11 +89,11 @@ public sealed class BundleSuspensionDriver : ISuspensionDriver /// [RequiresUnreferencedCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] + "Implementations commonly use reflection-based serialization. " + + "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] [RequiresDynamicCode( - "Implementations commonly use reflection-based serialization. " + - "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] + "Implementations commonly use reflection-based serialization. " + + "Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] public IObservable SaveState(T state) { try diff --git a/src/ReactiveUI/Platforms/android/ContextExtensions.cs b/src/ReactiveUI/Platforms/android/ContextExtensions.cs index abb5e5b8c7..afcdb8d4c3 100644 --- a/src/ReactiveUI/Platforms/android/ContextExtensions.cs +++ b/src/ReactiveUI/Platforms/android/ContextExtensions.cs @@ -57,8 +57,7 @@ public IObservable Justification = "'TBinder' is the binder contract the caller names explicitly to identify and cast the bound service; there is no argument it could be inferred from.")] public IObservable ServiceBound( Intent intent) - where TBinder : class, IBinder - => + where TBinder : class, IBinder => context.ServiceBound(intent, Bind.None); /// Binds the service using the supplied and exposes a strongly-typed as an observable sequence. @@ -76,8 +75,7 @@ public IObservable public IObservable ServiceBound( Intent intent, Bind flags) - where TBinder : class, IBinder - => + where TBinder : class, IBinder => new ServiceBoundObservable(context, intent, flags); } @@ -89,8 +87,7 @@ public IObservable /// The context used to bind the service on subscription and unbind it on dispose. /// The intent identifying the service to bind. /// The bind flags. - private sealed class ServiceBoundObservable(Context context, Intent intent, Bind flags) - : IObservable + private sealed class ServiceBoundObservable(Context context, Intent intent, Bind flags) : IObservable where TBinder : class, IBinder { /// @@ -119,8 +116,7 @@ public IDisposable Subscribe(IObserver observer) /// The type of binder delivered through this service connection. /// The context held by the connection and used to unbind the service when disposed. /// The observer that receives the service binder notifications. - private sealed class ServiceConnection(Context context, IObserver observer) - : Java.Lang.Object, IServiceConnection + private sealed class ServiceConnection(Context context, IObserver observer) : Java.Lang.Object, IServiceConnection where TBinder : class, IBinder { /// The Context used to bind and unbind the service. diff --git a/src/ReactiveUI/Platforms/android/ControlFetcherMixins.cs b/src/ReactiveUI/Platforms/android/ControlFetcherMixins.cs index c03008d210..d38b2ee0f9 100644 --- a/src/ReactiveUI/Platforms/android/ControlFetcherMixins.cs +++ b/src/ReactiveUI/Platforms/android/ControlFetcherMixins.cs @@ -382,11 +382,11 @@ private static bool ShouldWireUpMember(PropertyInfo member, ResolveStrategy stra ResolveStrategy.ExplicitOptIn => member.GetCustomAttribute(true) is not null, ResolveStrategy.ExplicitOptOut => - typeof(View).IsAssignableFrom(member.PropertyType) && - member.GetCustomAttribute(true) is null, + typeof(View).IsAssignableFrom(member.PropertyType) + && member.GetCustomAttribute(true) is null, _ => - member.PropertyType.IsSubclassOf(typeof(View)) || - member.GetCustomAttribute(true) is not null, + member.PropertyType.IsSubclassOf(typeof(View)) + || member.GetCustomAttribute(true) is not null, }; /// Resolves a control on an by resource name, caching the result per activity. diff --git a/src/ReactiveUI/Platforms/android/FlexibleCommandBinder.cs b/src/ReactiveUI/Platforms/android/FlexibleCommandBinder.cs index 09b5cf698f..6b8d0fda3b 100644 --- a/src/ReactiveUI/Platforms/android/FlexibleCommandBinder.cs +++ b/src/ReactiveUI/Platforms/android/FlexibleCommandBinder.cs @@ -35,8 +35,8 @@ protected FlexibleCommandBinder() /// public int GetAffinityForObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties)] T>(bool hasEventTarget) { if (hasEventTarget) @@ -67,9 +67,9 @@ public int GetAffinityForObject< /// [RequiresUnreferencedCode("String/reflection-based event binding may require members removed by trimming.")] public IDisposable? BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T>(ICommand? command, T? target, IObservable commandParameter) where T : class { @@ -109,14 +109,14 @@ public IDisposable? BindCommandToObject< T? target, IObservable commandParameter, string eventName) - where T : class - => EmptyDisposable.Instance; + where T : class => + EmptyDisposable.Instance; /// public IDisposable? BindCommandToObject< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T, TEventArgs>( ICommand? command, T? target, diff --git a/src/ReactiveUI/Platforms/android/ReactiveActivity.cs b/src/ReactiveUI/Platforms/android/ReactiveActivity.cs index beec799ae4..6488e5690e 100644 --- a/src/ReactiveUI/Platforms/android/ReactiveActivity.cs +++ b/src/ReactiveUI/Platforms/android/ReactiveActivity.cs @@ -145,8 +145,7 @@ protected override void Dispose(bool disposing) /// Completes a task with the first activity result matching a request code, then unsubscribes — replacing /// ActivityResult.Where(matching).Select(...).FirstAsync().ToTask(). /// - private sealed class ActivityResultAwaiter - : IObserver<(int requestCode, Result resultCode, Intent? intent)>, IDisposable + private sealed class ActivityResultAwaiter : IObserver<(int requestCode, Result resultCode, Intent? intent)>, IDisposable { /// The request code this awaiter is waiting for. private readonly int _requestCode; diff --git a/src/ReactiveUI/Platforms/android/UsbManagerExtensions.cs b/src/ReactiveUI/Platforms/android/UsbManagerExtensions.cs index 991119a9fb..98a873d182 100644 --- a/src/ReactiveUI/Platforms/android/UsbManagerExtensions.cs +++ b/src/ReactiveUI/Platforms/android/UsbManagerExtensions.cs @@ -51,8 +51,7 @@ public IObservable PermissionRequested(Context context, UsbAccessory acces /// The USB manager system service. /// The context to request the permission from. /// The USB device to request permission for. - private sealed class DevicePermissionObservable(UsbManager manager, Context context, UsbDevice device) - : IObservable + private sealed class DevicePermissionObservable(UsbManager manager, Context context, UsbDevice device) : IObservable { /// Subscribes the given observer to the USB device permission result. /// The observer to receive the granted result. @@ -78,8 +77,7 @@ public IDisposable Subscribe(IObserver observer) /// The USB manager system service. /// The context to request the permission from. /// The USB accessory to request permission for. - private sealed class AccessoryPermissionObservable(UsbManager manager, Context context, UsbAccessory accessory) - : IObservable + private sealed class AccessoryPermissionObservable(UsbManager manager, Context context, UsbAccessory accessory) : IObservable { /// Subscribes the given observer to the USB accessory permission result. /// The observer to receive the granted result. @@ -101,8 +99,7 @@ public IDisposable Subscribe(IObserver observer) /// Private implementation of BroadcastReceiver to handle device permission requests. /// The observer to receive the permission result. /// The UsbDevice the permission result applies to. - private sealed class UsbDevicePermissionReceiver(IObserver observer, UsbDevice device) - : BroadcastReceiver + private sealed class UsbDevicePermissionReceiver(IObserver observer, UsbDevice device) : BroadcastReceiver { /// Handles the broadcast for a USB device permission result. /// The context in which the receiver is running. @@ -130,8 +127,7 @@ public override void OnReceive(Context? context, Intent? intent) /// Private implementation of BroadcastReceiver to handle accessory permission requests. /// The observer to receive the permission result. /// The UsbAccessory the permission result applies to. - private sealed class UsbAccessoryPermissionReceiver(IObserver observer, UsbAccessory accessory) - : BroadcastReceiver + private sealed class UsbAccessoryPermissionReceiver(IObserver observer, UsbAccessory accessory) : BroadcastReceiver { /// Handles the broadcast for a USB accessory permission result. /// The context in which the receiver is running. diff --git a/src/ReactiveUI/Platforms/apple-common/AppSupportJsonSuspensionDriver.cs b/src/ReactiveUI/Platforms/apple-common/AppSupportJsonSuspensionDriver.cs index 6f4cf16073..cfcbd9405f 100644 --- a/src/ReactiveUI/Platforms/apple-common/AppSupportJsonSuspensionDriver.cs +++ b/src/ReactiveUI/Platforms/apple-common/AppSupportJsonSuspensionDriver.cs @@ -200,6 +200,6 @@ private static string CreateAppDirectory(NSSearchPathDirectory targetDir, string /// Computes the full path to the persisted state file. /// The absolute file path. [MethodImpl(MethodImplOptions.AggressiveInlining)] - private string GetStatePath() - => Path.Combine(_appDirectory.Value, StateFileName); + private string GetStatePath() => + Path.Combine(_appDirectory.Value, StateFileName); } diff --git a/src/ReactiveUI/Platforms/apple-common/PlatformOperations.cs b/src/ReactiveUI/Platforms/apple-common/PlatformOperations.cs index 4e63beb507..ae30a82430 100644 --- a/src/ReactiveUI/Platforms/apple-common/PlatformOperations.cs +++ b/src/ReactiveUI/Platforms/apple-common/PlatformOperations.cs @@ -12,10 +12,10 @@ namespace ReactiveUI; public class PlatformOperations : IPlatformOperations { /// - public string? GetOrientation() + public string? GetOrientation() => #if UIKIT && !TVOS - => UIKit.UIDevice.CurrentDevice.Orientation.ToString(); + UIKit.UIDevice.CurrentDevice.Orientation.ToString(); #else - => null; + null; #endif } diff --git a/src/ReactiveUI/Platforms/apple-common/TargetActionCommandBinder.cs b/src/ReactiveUI/Platforms/apple-common/TargetActionCommandBinder.cs index 00b41e5119..8c2b891c30 100644 --- a/src/ReactiveUI/Platforms/apple-common/TargetActionCommandBinder.cs +++ b/src/ReactiveUI/Platforms/apple-common/TargetActionCommandBinder.cs @@ -113,9 +113,9 @@ public class TargetActionCommandBinder : ICreatesCommandBinding [RequiresUnreferencedCode("String/reflection-based event binding may require members removed by trimming.")] public IDisposable? BindCommandToObject< [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] T>( + DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T>( ICommand? command, T? target, IObservable commandParameter) @@ -252,9 +252,9 @@ public IDisposable? BindCommandToObject< /// A disposable that tears down the binding, or when binding is not possible. public IDisposable? BindCommandToObject< [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] T, TEventArgs>( + DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T, TEventArgs>( ICommand? command, T? target, IObservable commandParameter, diff --git a/src/ReactiveUI/Platforms/apple-common/ViewModelViewHost.cs b/src/ReactiveUI/Platforms/apple-common/ViewModelViewHost.cs index 19710b9619..acc91f2e03 100644 --- a/src/ReactiveUI/Platforms/apple-common/ViewModelViewHost.cs +++ b/src/ReactiveUI/Platforms/apple-common/ViewModelViewHost.cs @@ -48,8 +48,8 @@ namespace ReactiveUI; [RequiresUnreferencedCode( "This class uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public class ViewModelViewHost : ReactiveViewController { /// Tracks the currently-adopted view controller and ensures it is disowned on replacement or disposal. @@ -86,7 +86,6 @@ public ViewModelViewHost() .Subscribe(new DelegateObserver(SetViewContract)); _subscriptions.Add(contractStream); - _subscriptions.Add(_viewContractObservableSubscription); Initialize(); } @@ -143,6 +142,7 @@ protected override void Dispose(bool disposing) } _subscriptions.Dispose(); + _viewContractObservableSubscription.Dispose(); _currentView.Dispose(); } @@ -217,8 +217,8 @@ private static void Disown(NSViewController child) [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] private void Initialize() { var viewModelChanges = new PropertyObservable(this, static x => x._viewModel, nameof(ViewModel)); diff --git a/src/ReactiveUI/Platforms/ios/UIKitCommandBinders.cs b/src/ReactiveUI/Platforms/ios/UIKitCommandBinders.cs index 53e99f107f..5aab5a4fdf 100644 --- a/src/ReactiveUI/Platforms/ios/UIKitCommandBinders.cs +++ b/src/ReactiveUI/Platforms/ios/UIKitCommandBinders.cs @@ -27,18 +27,18 @@ public sealed class UIKitCommandBinders : FlexibleCommandBinder /// Cached for . private static readonly PropertyInfo UIControlEnabledProperty = - typeof(UIControl).GetRuntimeProperty(EnabledPropertyName) ?? - throw new InvalidOperationException("There is no Enabled property on UIControl which is needed for binding."); + typeof(UIControl).GetRuntimeProperty(EnabledPropertyName) + ?? throw new InvalidOperationException("There is no Enabled property on UIControl which is needed for binding."); /// Cached for . private static readonly PropertyInfo UIRefreshControlEnabledProperty = - typeof(UIRefreshControl).GetRuntimeProperty(EnabledPropertyName) ?? - throw new InvalidOperationException("There is no Enabled property on UIRefreshControl which is needed for binding."); + typeof(UIRefreshControl).GetRuntimeProperty(EnabledPropertyName) + ?? throw new InvalidOperationException("There is no Enabled property on UIRefreshControl which is needed for binding."); /// Cached for . private static readonly PropertyInfo UIBarButtonItemEnabledProperty = - typeof(UIBarButtonItem).GetRuntimeProperty(EnabledPropertyName) ?? - throw new InvalidOperationException("There is no Enabled property on UIBarButtonItem which is needed for binding."); + typeof(UIBarButtonItem).GetRuntimeProperty(EnabledPropertyName) + ?? throw new InvalidOperationException("There is no Enabled property on UIBarButtonItem which is needed for binding."); /// Initializes a new instance of the class. public UIKitCommandBinders() diff --git a/src/ReactiveUI/Platforms/mac/AutoSuspendHelper.cs b/src/ReactiveUI/Platforms/mac/AutoSuspendHelper.cs index deea3566c9..62b659dd41 100644 --- a/src/ReactiveUI/Platforms/mac/AutoSuspendHelper.cs +++ b/src/ReactiveUI/Platforms/mac/AutoSuspendHelper.cs @@ -155,11 +155,7 @@ public void DidBecomeActive(NSNotification notification) /// /// Initiates a quick save when the app is hidden, mirroring the behavior of . /// - public void DidHide(NSNotification notification) - { - ThrowIfDisposed(); - _shouldPersistState.OnNext(Scope.Empty); - } + public void DidHide(NSNotification notification) => DidResignActive(notification); /// public void Dispose() diff --git a/src/ReactiveUI/Platforms/uikit-common/CommonReactiveSource.cs b/src/ReactiveUI/Platforms/uikit-common/CommonReactiveSource.cs index 5b11bd8297..12269a3a0f 100644 --- a/src/ReactiveUI/Platforms/uikit-common/CommonReactiveSource.cs +++ b/src/ReactiveUI/Platforms/uikit-common/CommonReactiveSource.cs @@ -76,7 +76,6 @@ public CommonReactiveSource(IUICollViewAdapter adapter) _mainDisposables = []; _sectionInfoDisposable = new(); - _mainDisposables.Add(_sectionInfoDisposable); _pendingChanges = []; _sectionInfo = []; @@ -113,7 +112,11 @@ internal IReadOnlyList SectionInfo private bool IsDebugEnabled => this.Log().Level <= LogLevel.Debug; /// Disposes subscriptions and managed resources associated with this instance. - public void Dispose() => _mainDisposables.Dispose(); + public void Dispose() + { + _sectionInfoDisposable.Dispose(); + _mainDisposables.Dispose(); + } /// Returns the number of sections. /// The number of sections. @@ -378,8 +381,7 @@ private void SetUpSectionChangeSubscriptions( SwapDisposable applyPendingChangesDisposable) { var sink = new ReloadAwareSectionSink(this, sectionInfoId, applyPendingChangesDisposable); - sectionDisposables.Add(sink); - sink.Run(sectionInfo); + sink.Run(sectionInfo, sectionDisposables); } /// Handles a single item-change event received from a section while no reload is in progress. @@ -668,7 +670,7 @@ private void VerifyOnMainThread() private sealed class ReloadAwareSectionSink( CommonReactiveSource parent, int sectionInfoId, - SwapDisposable applyPendingChangesDisposable) : IDisposable + SwapDisposable applyPendingChangesDisposable) { /// The owning source whose adapter and state the sink drives. private readonly CommonReactiveSource _parent = parent; @@ -679,9 +681,6 @@ private sealed class ReloadAwareSectionSink( /// Serial disposable that holds the scheduled apply-changes action. private readonly SwapDisposable _applyPendingChangesDisposable = applyPendingChangesDisposable; - /// All subscriptions created by this sink. - private readonly MultipleDisposable _subscriptions = []; - /// The latest observed reload state. private bool _isReloading; @@ -690,16 +689,17 @@ private sealed class ReloadAwareSectionSink( /// Subscribes to the adapter reload state and to each section's collection changes. /// The current section info. - public void Run(IReadOnlyList sectionInfo) + /// The caller-owned container that holds the subscriptions. + public void Run(IReadOnlyList sectionInfo, MultipleDisposable subscriptions) { // IsReloadingData is a BehaviorSubject, so the current value arrives synchronously on subscription and is // in place before any section-change notification is dispatched below. - _subscriptions.Add(_parent._adapter.IsReloadingData.Subscribe(new DelegateObserver(OnReloadingChanged))); + subscriptions.Add(_parent._adapter.IsReloadingData.Subscribe(new DelegateObserver(OnReloadingChanged))); for (var index = 0; index < sectionInfo.Count; index++) { var section = index; - _subscriptions.Add( + subscriptions.Add( sectionInfo[section].Collection!.ObserveCollectionChanges().Subscribe( new DelegateObserver( change => OnSectionChanged(change, section), @@ -707,9 +707,6 @@ public void Run(IReadOnlyList sectionInfo) } } - /// - public void Dispose() => _subscriptions.Dispose(); - /// Records the latest reload state, logging only when it changes. /// The new reload state. private void OnReloadingChanged(bool value) diff --git a/src/ReactiveUI/Platforms/uikit-common/FlexibleCommandBinder.cs b/src/ReactiveUI/Platforms/uikit-common/FlexibleCommandBinder.cs index 61778cda7b..0b914e8264 100644 --- a/src/ReactiveUI/Platforms/uikit-common/FlexibleCommandBinder.cs +++ b/src/ReactiveUI/Platforms/uikit-common/FlexibleCommandBinder.cs @@ -102,9 +102,9 @@ protected FlexibleCommandBinder() [RequiresUnreferencedCode("String/reflection-based event binding may require members removed by trimming.")] public IDisposable? BindCommandToObject< [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] T>( + DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T>( ICommand? command, T? target, IObservable commandParameter) @@ -170,9 +170,9 @@ public IDisposable? BindCommandToObject< /// A disposable that tears down the binding, or when binding is not possible. public virtual IDisposable? BindCommandToObject< [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.PublicProperties | - DynamicallyAccessedMemberTypes.PublicEvents | - DynamicallyAccessedMemberTypes.NonPublicEvents)] T, + DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.NonPublicEvents)] T, TEventArgs>( ICommand? command, T? target, diff --git a/src/ReactiveUI/Platforms/uikit-common/ReactiveCollectionView.cs b/src/ReactiveUI/Platforms/uikit-common/ReactiveCollectionView.cs index af77ab1375..1a457af0de 100644 --- a/src/ReactiveUI/Platforms/uikit-common/ReactiveCollectionView.cs +++ b/src/ReactiveUI/Platforms/uikit-common/ReactiveCollectionView.cs @@ -17,8 +17,7 @@ namespace ReactiveUI; /// This is a UICollectionView that is both an UICollectionView and has ReactiveObject powers /// (i.e. you can call RaiseAndSetIfChanged). /// -public class ReactiveCollectionView - : UICollectionView, IReactiveNotifyPropertyChanged, IHandleObservableErrors, IReactiveObject, ICanActivate, ICanForceManualActivation +public class ReactiveCollectionView : UICollectionView, IReactiveNotifyPropertyChanged, IHandleObservableErrors, IReactiveObject, ICanActivate, ICanForceManualActivation { /// The subject used to signal view activation. private readonly Signal _activated = new(); diff --git a/src/ReactiveUI/Platforms/uikit-common/RoutedViewHost.cs b/src/ReactiveUI/Platforms/uikit-common/RoutedViewHost.cs index 23125dca1f..2ca3f0c2e1 100644 --- a/src/ReactiveUI/Platforms/uikit-common/RoutedViewHost.cs +++ b/src/ReactiveUI/Platforms/uikit-common/RoutedViewHost.cs @@ -49,8 +49,8 @@ namespace ReactiveUI; /// [RequiresUnreferencedCode("This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public class RoutedViewHost : ReactiveNavigationController { /// The disposable that tracks the current title-update subscription. diff --git a/src/Shared/ArgumentValidation.cs b/src/Shared/ArgumentValidation.cs index 6924a6aa41..64da616745 100644 --- a/src/Shared/ArgumentValidation.cs +++ b/src/Shared/ArgumentValidation.cs @@ -20,12 +20,15 @@ internal static class ArgumentValidation /// Throws an if is null. /// The reference type argument to validate as non-null. /// The name of the parameter with which corresponds. +#if NET8_0_OR_GREATER internal static void ThrowIfNull( [NotNull] object? argument, - [CallerArgumentExpression(nameof(argument))] string? paramName = null) -#if NET8_0_OR_GREATER - => ArgumentNullException.ThrowIfNull(argument, paramName); + [CallerArgumentExpression(nameof(argument))] string? paramName = null) => + ArgumentNullException.ThrowIfNull(argument, paramName); #else + internal static void ThrowIfNull( + [NotNull] object? argument, + [CallerArgumentExpression(nameof(argument))] string? paramName = null) { if (argument is not null) { @@ -58,12 +61,15 @@ internal static void ThrowIfNullWithMessage( /// The name of the parameter with which corresponds. /// is null. /// is empty. +#if NET8_0_OR_GREATER internal static void ThrowIfNullOrEmpty( [NotNull] string? argument, - [CallerArgumentExpression(nameof(argument))] string? paramName = null) -#if NET8_0_OR_GREATER - => ArgumentException.ThrowIfNullOrEmpty(argument, paramName); + [CallerArgumentExpression(nameof(argument))] string? paramName = null) => + ArgumentException.ThrowIfNullOrEmpty(argument, paramName); #else + internal static void ThrowIfNullOrEmpty( + [NotNull] string? argument, + [CallerArgumentExpression(nameof(argument))] string? paramName = null) { if (argument is null) { @@ -84,12 +90,15 @@ internal static void ThrowIfNullOrEmpty( /// The name of the parameter with which corresponds. /// is null. /// is empty or consists only of white-space characters. +#if NET8_0_OR_GREATER internal static void ThrowIfNullOrWhiteSpace( [NotNull] string? argument, - [CallerArgumentExpression(nameof(argument))] string? paramName = null) -#if NET8_0_OR_GREATER - => ArgumentException.ThrowIfNullOrWhiteSpace(argument, paramName); + [CallerArgumentExpression(nameof(argument))] string? paramName = null) => + ArgumentException.ThrowIfNullOrWhiteSpace(argument, paramName); #else + internal static void ThrowIfNullOrWhiteSpace( + [NotNull] string? argument, + [CallerArgumentExpression(nameof(argument))] string? paramName = null) { if (argument is null) { diff --git a/src/benchmarks/ReactiveUI.Benchmarks/ActivationBenchmarks.cs b/src/benchmarks/ReactiveUI.Benchmarks/ActivationBenchmarks.cs index de1e79d281..a0a07f17e9 100644 --- a/src/benchmarks/ReactiveUI.Benchmarks/ActivationBenchmarks.cs +++ b/src/benchmarks/ReactiveUI.Benchmarks/ActivationBenchmarks.cs @@ -13,7 +13,7 @@ namespace ReactiveUI.Benchmarks; /// [MemoryDiagnoser] [MarkdownExporterAttribute.GitHub] -public class ActivationBenchmarks +public class ActivationBenchmarks : IDisposable { /// The number of activate / deactivate cycles per benchmark invocation. private const int CycleCount = 10_000; @@ -25,6 +25,17 @@ public class ActivationBenchmarks [GlobalSetup] public void Setup() => _viewModel = new(); + /// Disposes the activatable view model. + [GlobalCleanup] + public void Cleanup() => Dispose(); + + /// Disposes the activatable view model. + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + /// Measures repeated activate + deactivate cycles. [Benchmark] public void ActivateDeactivate() @@ -34,4 +45,16 @@ public void ActivateDeactivate() using var activation = _viewModel.Activator.Activate(); } } + + /// Disposes resources owned by the benchmark. + /// Whether managed resources should be disposed. + protected virtual void Dispose(bool disposing) + { + if (!disposing) + { + return; + } + + _viewModel.Dispose(); + } } diff --git a/src/examples/ReactiveUI.Builder.BlazorServer/ViewModels/ChatRoomViewModel.cs b/src/examples/ReactiveUI.Builder.BlazorServer/ViewModels/ChatRoomViewModel.cs index 5b51103535..84afb61f73 100644 --- a/src/examples/ReactiveUI.Builder.BlazorServer/ViewModels/ChatRoomViewModel.cs +++ b/src/examples/ReactiveUI.Builder.BlazorServer/ViewModels/ChatRoomViewModel.cs @@ -113,10 +113,7 @@ private void SendMessageImpl() { var msg = new ChatMessage { Sender = _user, Text = MessageText, Timestamp = TimeProvider.System.GetUtcNow() }; _room.Messages.Add(msg); - var networkMessage = new ChatNetworkMessage(_room.Id, _room.Name, msg.Sender, msg.Text, msg.Timestamp) - { - InstanceId = _senderInstanceId - }; + var networkMessage = new ChatNetworkMessage(_room.Id, _room.Name, msg.Sender, msg.Text, msg.Timestamp) { InstanceId = _senderInstanceId }; MessageBus.Current.SendMessage(networkMessage, RoomName); Trace.TraceInformation($"[Room:{_room.Name}] TX '{msg.Text}' from {_user}/{Services.AppInstance.Id}"); diff --git a/src/examples/ReactiveUI.Builder.BlazorServer/ViewModels/LobbyViewModel.cs b/src/examples/ReactiveUI.Builder.BlazorServer/ViewModels/LobbyViewModel.cs index c4dd722a46..6464370a41 100644 --- a/src/examples/ReactiveUI.Builder.BlazorServer/ViewModels/LobbyViewModel.cs +++ b/src/examples/ReactiveUI.Builder.BlazorServer/ViewModels/LobbyViewModel.cs @@ -82,10 +82,7 @@ public LobbyViewModel(IScreen hostScreen) // Request a snapshot from peers shortly after activation _ = RxSchedulers.MainThreadScheduler.Schedule(RxVoid.Default, TimeSpan.FromMilliseconds(SyncRequestDelayMilliseconds), static (_, _) => { - var req = new RoomEventMessage(Services.RoomEventKind.SyncRequest, string.Empty) - { - InstanceId = Services.AppInstance.Id - }; + var req = new RoomEventMessage(Services.RoomEventKind.SyncRequest, string.Empty) { InstanceId = Services.AppInstance.Id }; Trace.TraceInformation("[Lobby] Broadcasting SyncRequest"); MessageBus.Current.SendMessage(req, RoomsKey); return EmptyDisposable.Instance; @@ -173,11 +170,7 @@ private static void HandleRemoteRoomEvent(RoomEventMessage evt) { // Respond with our snapshot of room names var snapshot = GetState().Rooms.ConvertAll(static r => r.Name); - var response = new RoomEventMessage(Services.RoomEventKind.Add, string.Empty) - { - Snapshot = snapshot, - InstanceId = Services.AppInstance.Id - }; + var response = new RoomEventMessage(Services.RoomEventKind.Add, string.Empty) { Snapshot = snapshot, InstanceId = Services.AppInstance.Id }; MessageBus.Current.SendMessage(response, RoomsKey); break; } @@ -246,10 +239,7 @@ private static void DeleteRoomImpl(ChatRoom room) return; } - var evt = new RoomEventMessage(Services.RoomEventKind.Remove, room.Name) - { - InstanceId = Services.AppInstance.Id - }; + var evt = new RoomEventMessage(Services.RoomEventKind.Remove, room.Name) { InstanceId = Services.AppInstance.Id }; MessageBus.Current.SendMessage(evt, RoomsKey); MessageBus.Current.SendMessage(new ChatStateChanged()); Trace.TraceInformation($"[Lobby] Deleted room '{room.Name}'"); @@ -276,10 +266,7 @@ private void CreateRoomImpl() state.Rooms.Add(room); // Broadcast room add to peers - var evt = new RoomEventMessage(Services.RoomEventKind.Add, room.Name) - { - InstanceId = Services.AppInstance.Id - }; + var evt = new RoomEventMessage(Services.RoomEventKind.Add, room.Name) { InstanceId = Services.AppInstance.Id }; MessageBus.Current.SendMessage(evt, RoomsKey); Trace.TraceInformation($"[Lobby] Created room '{room.Name}'"); } diff --git a/src/examples/ReactiveUI.Builder.BlazorServer/Views/RoomListItem.razor b/src/examples/ReactiveUI.Builder.BlazorServer/Views/RoomListItem.razor index 32b7572665..f5a3d8771b 100644 --- a/src/examples/ReactiveUI.Builder.BlazorServer/Views/RoomListItem.razor +++ b/src/examples/ReactiveUI.Builder.BlazorServer/Views/RoomListItem.razor @@ -11,7 +11,7 @@ @code { /// Gets or sets the chat room this row represents. [Parameter] - public ChatRoom Room { get; set; } = default!; + public ChatRoom Room { get; set; } = new(); /// Gets or sets a value indicating whether this row is the selected room. [Parameter] diff --git a/src/examples/ReactiveUI.Builder.WpfApp/MainWindow.xaml.cs b/src/examples/ReactiveUI.Builder.WpfApp/MainWindow.xaml.cs index d55df1cf9a..4d9a319fae 100644 --- a/src/examples/ReactiveUI.Builder.WpfApp/MainWindow.xaml.cs +++ b/src/examples/ReactiveUI.Builder.WpfApp/MainWindow.xaml.cs @@ -31,13 +31,7 @@ public MainWindow() Content = new RoutedViewHost { Router = screen.Router, - DefaultContent = new TextBlock - { - Text = "Loading…", - Foreground = Brushes.Gray, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - }, + DefaultContent = new TextBlock { Text = "Loading…", Foreground = Brushes.Gray, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, }, }; } diff --git a/src/examples/ReactiveUI.Builder.WpfApp/ReactiveUI.Builder.WpfApp.csproj b/src/examples/ReactiveUI.Builder.WpfApp/ReactiveUI.Builder.WpfApp.csproj index b54452c2cb..1e6a3fcdfe 100644 --- a/src/examples/ReactiveUI.Builder.WpfApp/ReactiveUI.Builder.WpfApp.csproj +++ b/src/examples/ReactiveUI.Builder.WpfApp/ReactiveUI.Builder.WpfApp.csproj @@ -14,6 +14,7 @@ + diff --git a/src/examples/ReactiveUI.Builder.WpfApp/Services/MockPaymentProcessor.cs b/src/examples/ReactiveUI.Builder.WpfApp/Services/MockPaymentProcessor.cs index df1a08ee3f..72a8378e4f 100644 --- a/src/examples/ReactiveUI.Builder.WpfApp/Services/MockPaymentProcessor.cs +++ b/src/examples/ReactiveUI.Builder.WpfApp/Services/MockPaymentProcessor.cs @@ -76,10 +76,5 @@ private static string BuildOutcome(bool approved, bool declinedForLimit, long se /// Gets the current UTC instant. /// The current UTC instant. - private static DateTimeOffset UtcNow() => -#if NET8_0_OR_GREATER - TimeProvider.System.GetUtcNow(); -#else - DateTimeOffset.UtcNow; -#endif + private static DateTimeOffset UtcNow() => TimeProvider.System.GetUtcNow(); } diff --git a/src/examples/ReactiveUI.Builder.WpfApp/ViewModels/JournalViewModel.cs b/src/examples/ReactiveUI.Builder.WpfApp/ViewModels/JournalViewModel.cs index 5d882f1b09..53f1acad4f 100644 --- a/src/examples/ReactiveUI.Builder.WpfApp/ViewModels/JournalViewModel.cs +++ b/src/examples/ReactiveUI.Builder.WpfApp/ViewModels/JournalViewModel.cs @@ -61,7 +61,7 @@ private static DateOnly UtcToday() => DateOnly.FromDateTime(TimeProvider.System.GetUtcNow().UtcDateTime); #else private static DateTime UtcToday() => - DateTimeOffset.UtcNow.UtcDateTime.Date; + TimeProvider.System.GetUtcNow().UtcDateTime.Date; #endif /// Sums today's approved transactions without LINQ allocations. diff --git a/src/examples/ReactiveUI.Samples.Winforms/LoginView.cs b/src/examples/ReactiveUI.Samples.Winforms/LoginView.cs index c130fcb9e4..3e22e6fa41 100644 --- a/src/examples/ReactiveUI.Samples.Winforms/LoginView.cs +++ b/src/examples/ReactiveUI.Samples.Winforms/LoginView.cs @@ -19,13 +19,7 @@ public sealed class LoginView : UserControl, IViewFor private readonly TextBox _username = new() { PlaceholderText = "Username", Width = 240, Name = "Username" }; /// The text box bound to the view model's password. - private readonly TextBox _password = new() - { - PlaceholderText = "Password", - Width = 240, - UseSystemPasswordChar = true, - Name = "Password" - }; + private readonly TextBox _password = new() { PlaceholderText = "Password", Width = 240, UseSystemPasswordChar = true, Name = "Password" }; /// The button bound to the view model's login command. private readonly Button _login = new() { Text = "Login", Width = 115, Name = "Login" }; @@ -40,13 +34,7 @@ public sealed class LoginView : UserControl, IViewFor Justification = "Single-threaded sample view; WhenActivated captures this for activation-scoped binding after construction.")] public LoginView() { - var layout = new FlowLayoutPanel - { - Dock = DockStyle.Fill, - FlowDirection = FlowDirection.TopDown, - Padding = new(LayoutPadding), - WrapContents = false - }; + var layout = new FlowLayoutPanel { Dock = DockStyle.Fill, FlowDirection = FlowDirection.TopDown, Padding = new(LayoutPadding), WrapContents = false }; layout.Controls.AddRange(_username, _password); diff --git a/src/tests/ReactiveUI.Blazor.Tests/BlazorReactiveUIBuilderExtensionsTests.cs b/src/tests/ReactiveUI.Blazor.Tests/BlazorReactiveUIBuilderExtensionsTests.cs index cc37553021..396b94fdb8 100644 --- a/src/tests/ReactiveUI.Blazor.Tests/BlazorReactiveUIBuilderExtensionsTests.cs +++ b/src/tests/ReactiveUI.Blazor.Tests/BlazorReactiveUIBuilderExtensionsTests.cs @@ -251,7 +251,11 @@ public IReactiveUIBuilder WithRegistrationOnBuild(Action WithTaskPoolScheduler(scheduler, true); /// - public IReactiveUIBuilder WithTaskPoolScheduler(ISequencer scheduler, bool setRxApp) => this; + public IReactiveUIBuilder WithTaskPoolScheduler(ISequencer scheduler, bool setRxApp) + { + ArgumentNullException.ThrowIfNull(scheduler); + return this; + } /// public IReactiveUIBuilder WithViewsFromAssembly(System.Reflection.Assembly assembly) => diff --git a/src/tests/ReactiveUI.Builder.Maui.Tests/TestDispatcher.cs b/src/tests/ReactiveUI.Builder.Maui.Tests/TestDispatcher.cs index 54babbbfd1..3d8f52cd95 100644 --- a/src/tests/ReactiveUI.Builder.Maui.Tests/TestDispatcher.cs +++ b/src/tests/ReactiveUI.Builder.Maui.Tests/TestDispatcher.cs @@ -21,11 +21,7 @@ public bool Dispatch(Action action) } /// - public bool DispatchDelayed(TimeSpan delay, Action action) - { - action(); - return true; - } + public bool DispatchDelayed(TimeSpan delay, Action action) => Dispatch(action); /// public IDispatcherTimer CreateTimer() => diff --git a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity01to06.cs b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity01to06.cs index 8e5c552c41..cececf7267 100644 --- a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity01to06.cs +++ b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity01to06.cs @@ -50,42 +50,6 @@ public async Task Builder_WithInstance_1_Type_skips_when_null() await Assert.That(invoked).IsFalse(); } - /// Verifies that the 1-type WithInstance extension method invokes the action with the resolved instance. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_1_Type_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - var s1 = new InstanceService01(); - resolver.RegisterConstant( - s1, - typeof(InstanceService01)); - _ = builder.WithCoreServices().Build(); - - InstanceService01? captured1 = null; - _ = builder.WithInstance(s1 => captured1 = s1); - - await Assert.That(captured1).IsSameReferenceAs(s1); - } - - /// Verifies that the 1-type WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_1_Type_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder.WithInstance(_ => invoked = true); - - await Assert.That(invoked).IsFalse(); - } - /// Verifies that the 2-types WithInstance builder instance method invokes the action with the resolved instances. /// A task representing the asynchronous test. [Test] @@ -132,52 +96,6 @@ public async Task Builder_WithInstance_2_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - /// Verifies that the 2-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_2_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - var s1 = new InstanceService01(); - resolver.RegisterConstant( - s1, - typeof(InstanceService01)); - var s2 = new InstanceService02(); - resolver.RegisterConstant( - s2, - typeof(InstanceService02)); - _ = builder.WithCoreServices().Build(); - - InstanceService01? captured1 = null; - InstanceService02? captured2 = null; - _ = builder.WithInstance((s1, s2) => - { - captured1 = s1; - captured2 = s2; - }); - - await Assert.That(captured1).IsSameReferenceAs(s1); - await Assert.That(captured2).IsSameReferenceAs(s2); - } - - /// Verifies that the 2-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_2_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder.WithInstance((_, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } - /// Verifies that the 3-types WithInstance builder instance method invokes the action with the resolved instances. /// A task representing the asynchronous test. [Test] @@ -231,59 +149,6 @@ public async Task Builder_WithInstance_3_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - /// Verifies that the 3-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_3_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - var s1 = new InstanceService01(); - resolver.RegisterConstant( - s1, - typeof(InstanceService01)); - var s2 = new InstanceService02(); - resolver.RegisterConstant( - s2, - typeof(InstanceService02)); - var s3 = new InstanceService03(); - resolver.RegisterConstant( - s3, - typeof(InstanceService03)); - _ = builder.WithCoreServices().Build(); - - InstanceService01? captured1 = null; - InstanceService02? captured2 = null; - InstanceService03? captured3 = null; - _ = builder.WithInstance((s1, s2, s3) => - { - captured1 = s1; - captured2 = s2; - captured3 = s3; - }); - - await Assert.That(captured1).IsSameReferenceAs(s1); - await Assert.That(captured2).IsSameReferenceAs(s2); - await Assert.That(captured3).IsSameReferenceAs(s3); - } - - /// Verifies that the 3-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_3_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder.WithInstance((_, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } - /// Verifies that the 4-types WithInstance builder instance method invokes the action with the resolved instances. /// A task representing the asynchronous test. [Test] @@ -345,67 +210,6 @@ public async Task Builder_WithInstance_4_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - /// Verifies that the 4-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_4_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - var s1 = new InstanceService01(); - resolver.RegisterConstant( - s1, - typeof(InstanceService01)); - var s2 = new InstanceService02(); - resolver.RegisterConstant( - s2, - typeof(InstanceService02)); - var s3 = new InstanceService03(); - resolver.RegisterConstant( - s3, - typeof(InstanceService03)); - var s4 = new InstanceService04(); - resolver.RegisterConstant( - s4, - typeof(InstanceService04)); - _ = builder.WithCoreServices().Build(); - - InstanceService01? captured1 = null; - InstanceService02? captured2 = null; - InstanceService03? captured3 = null; - InstanceService04? captured4 = null; - _ = builder.WithInstance((s1, s2, s3, s4) => - { - captured1 = s1; - captured2 = s2; - captured3 = s3; - captured4 = s4; - }); - - await Assert.That(captured1).IsSameReferenceAs(s1); - await Assert.That(captured2).IsSameReferenceAs(s2); - await Assert.That(captured3).IsSameReferenceAs(s3); - await Assert.That(captured4).IsSameReferenceAs(s4); - } - - /// Verifies that the 4-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_4_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder.WithInstance((_, _, _, _) => - invoked = true); - - await Assert.That(invoked).IsFalse(); - } - /// Verifies that the 5-types WithInstance builder instance method invokes the action with the resolved instances. /// A task representing the asynchronous test. [Test] @@ -485,85 +289,6 @@ public async Task Builder_WithInstance_5_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - /// Verifies that the 5-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_5_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - var s1 = new InstanceService01(); - resolver.RegisterConstant( - s1, - typeof(InstanceService01)); - var s2 = new InstanceService02(); - resolver.RegisterConstant( - s2, - typeof(InstanceService02)); - var s3 = new InstanceService03(); - resolver.RegisterConstant( - s3, - typeof(InstanceService03)); - var s4 = new InstanceService04(); - resolver.RegisterConstant( - s4, - typeof(InstanceService04)); - var s5 = new InstanceService05(); - resolver.RegisterConstant( - s5, - typeof(InstanceService05)); - _ = builder.WithCoreServices().Build(); - - InstanceService01? captured1 = null; - InstanceService02? captured2 = null; - InstanceService03? captured3 = null; - InstanceService04? captured4 = null; - InstanceService05? captured5 = null; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05>((s1, s2, s3, s4, s5) => - { - captured1 = s1; - captured2 = s2; - captured3 = s3; - captured4 = s4; - captured5 = s5; - }); - - await Assert.That(captured1).IsSameReferenceAs(s1); - await Assert.That(captured2).IsSameReferenceAs(s2); - await Assert.That(captured3).IsSameReferenceAs(s3); - await Assert.That(captured4).IsSameReferenceAs(s4); - await Assert.That(captured5).IsSameReferenceAs(s5); - } - - /// Verifies that the 5-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_5_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05>((_, _, _, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } - /// Verifies that the 6-types WithInstance builder instance method invokes the action with the resolved instances. /// A task representing the asynchronous test. [Test] @@ -651,92 +376,4 @@ public async Task Builder_WithInstance_6_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - - /// Verifies that the 6-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_6_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - var s1 = new InstanceService01(); - resolver.RegisterConstant( - s1, - typeof(InstanceService01)); - var s2 = new InstanceService02(); - resolver.RegisterConstant( - s2, - typeof(InstanceService02)); - var s3 = new InstanceService03(); - resolver.RegisterConstant( - s3, - typeof(InstanceService03)); - var s4 = new InstanceService04(); - resolver.RegisterConstant( - s4, - typeof(InstanceService04)); - var s5 = new InstanceService05(); - resolver.RegisterConstant( - s5, - typeof(InstanceService05)); - var s6 = new InstanceService06(); - resolver.RegisterConstant( - s6, - typeof(InstanceService06)); - _ = builder.WithCoreServices().Build(); - - InstanceService01? captured1 = null; - InstanceService02? captured2 = null; - InstanceService03? captured3 = null; - InstanceService04? captured4 = null; - InstanceService05? captured5 = null; - InstanceService06? captured6 = null; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06>((s1, s2, s3, s4, s5, s6) => - { - captured1 = s1; - captured2 = s2; - captured3 = s3; - captured4 = s4; - captured5 = s5; - captured6 = s6; - }); - - await Assert.That(captured1).IsSameReferenceAs(s1); - await Assert.That(captured2).IsSameReferenceAs(s2); - await Assert.That(captured3).IsSameReferenceAs(s3); - await Assert.That(captured4).IsSameReferenceAs(s4); - await Assert.That(captured5).IsSameReferenceAs(s5); - await Assert.That(captured6).IsSameReferenceAs(s6); - } - - /// Verifies that the 6-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_6_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06>((_, _, _, _, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } } diff --git a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity07to09.cs b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity07to09.cs index eac6e929d4..336efab0a5 100644 --- a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity07to09.cs +++ b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity07to09.cs @@ -111,103 +111,6 @@ public async Task Builder_WithInstance_7_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - /// Verifies that the 7-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_7_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - var s1 = new InstanceService01(); - resolver.RegisterConstant( - s1, - typeof(InstanceService01)); - var s2 = new InstanceService02(); - resolver.RegisterConstant( - s2, - typeof(InstanceService02)); - var s3 = new InstanceService03(); - resolver.RegisterConstant( - s3, - typeof(InstanceService03)); - var s4 = new InstanceService04(); - resolver.RegisterConstant( - s4, - typeof(InstanceService04)); - var s5 = new InstanceService05(); - resolver.RegisterConstant( - s5, - typeof(InstanceService05)); - var s6 = new InstanceService06(); - resolver.RegisterConstant( - s6, - typeof(InstanceService06)); - var s7 = new InstanceService07(); - resolver.RegisterConstant( - s7, - typeof(InstanceService07)); - _ = builder.WithCoreServices().Build(); - - InstanceService01? captured1 = null; - InstanceService02? captured2 = null; - InstanceService03? captured3 = null; - InstanceService04? captured4 = null; - InstanceService05? captured5 = null; - InstanceService06? captured6 = null; - InstanceService07? captured7 = null; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07>((s1, s2, s3, s4, s5, s6, s7) => - { - captured1 = s1; - captured2 = s2; - captured3 = s3; - captured4 = s4; - captured5 = s5; - captured6 = s6; - captured7 = s7; - }); - - await Assert.That(captured1).IsSameReferenceAs(s1); - await Assert.That(captured2).IsSameReferenceAs(s2); - await Assert.That(captured3).IsSameReferenceAs(s3); - await Assert.That(captured4).IsSameReferenceAs(s4); - await Assert.That(captured5).IsSameReferenceAs(s5); - await Assert.That(captured6).IsSameReferenceAs(s6); - await Assert.That(captured7).IsSameReferenceAs(s7); - } - - /// Verifies that the 7-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_7_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07>((_, _, _, _, _, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } - /// Verifies that the 8-types WithInstance builder instance method invokes the action with the resolved instances. /// A task representing the asynchronous test. [Test] @@ -322,120 +225,6 @@ public async Task Builder_WithInstance_8_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - /// Verifies that the 8-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Major Code Smell", - "SST1472:Signatures should not declare too many parameters", - Justification = "Test exercises a variadic overload.")] - public async Task Extension_WithInstance_8_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - var s1 = new InstanceService01(); - resolver.RegisterConstant( - s1, - typeof(InstanceService01)); - var s2 = new InstanceService02(); - resolver.RegisterConstant( - s2, - typeof(InstanceService02)); - var s3 = new InstanceService03(); - resolver.RegisterConstant( - s3, - typeof(InstanceService03)); - var s4 = new InstanceService04(); - resolver.RegisterConstant( - s4, - typeof(InstanceService04)); - var s5 = new InstanceService05(); - resolver.RegisterConstant( - s5, - typeof(InstanceService05)); - var s6 = new InstanceService06(); - resolver.RegisterConstant( - s6, - typeof(InstanceService06)); - var s7 = new InstanceService07(); - resolver.RegisterConstant( - s7, - typeof(InstanceService07)); - var s8 = new InstanceService08(); - resolver.RegisterConstant( - s8, - typeof(InstanceService08)); - _ = builder.WithCoreServices().Build(); - - InstanceService01? captured1 = null; - InstanceService02? captured2 = null; - InstanceService03? captured3 = null; - InstanceService04? captured4 = null; - InstanceService05? captured5 = null; - InstanceService06? captured6 = null; - InstanceService07? captured7 = null; - InstanceService08? captured8 = null; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07, - InstanceService08>((s1, s2, s3, s4, s5, s6, s7, s8) => - { - captured1 = s1; - captured2 = s2; - captured3 = s3; - captured4 = s4; - captured5 = s5; - captured6 = s6; - captured7 = s7; - captured8 = s8; - }); - - await Assert.That(captured1).IsSameReferenceAs(s1); - await Assert.That(captured2).IsSameReferenceAs(s2); - await Assert.That(captured3).IsSameReferenceAs(s3); - await Assert.That(captured4).IsSameReferenceAs(s4); - await Assert.That(captured5).IsSameReferenceAs(s5); - await Assert.That(captured6).IsSameReferenceAs(s6); - await Assert.That(captured7).IsSameReferenceAs(s7); - await Assert.That(captured8).IsSameReferenceAs(s8); - } - - /// Verifies that the 8-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Major Code Smell", - "SST1472:Signatures should not declare too many parameters", - Justification = "Test exercises a variadic overload.")] - public async Task Extension_WithInstance_8_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07, - InstanceService08>((_, _, _, _, _, _, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } - /// Verifies that the 9-types WithInstance builder instance method invokes the action with the resolved instances. /// A task representing the asynchronous test. [Test] @@ -519,88 +308,4 @@ public async Task Builder_WithInstance_9_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - - /// Verifies that the 9-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_9_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - RegisterServices09( - resolver, - out var s1, - out var s2, - out var s3, - out var s4, - out var s5, - out var s6, - out var s7, - out var s8, - out var s9); - _ = builder.WithCoreServices().Build(); - - InvokeWithInstance09( - builder, - out var captured1, - out var captured2, - out var captured3, - out var captured4, - out var captured5, - out var captured6, - out var captured7, - out var captured8, - out var captured9); - - await AssertSameReferences09( - captured1, - s1, - captured2, - s2, - captured3, - s3, - captured4, - s4, - captured5, - s5, - captured6, - s6, - captured7, - s7, - captured8, - s8, - captured9, - s9); - } - - /// Verifies that the 9-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Major Code Smell", - "SST1472:Signatures should not declare too many parameters", - Justification = "Test exercises a variadic overload.")] - public async Task Extension_WithInstance_9_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07, - InstanceService08, - InstanceService09>((_, _, _, _, _, _, _, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } } diff --git a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity10to12.cs b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity10to12.cs index 7047ef4672..432c61939a 100644 --- a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity10to12.cs +++ b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity10to12.cs @@ -103,95 +103,6 @@ public async Task Builder_WithInstance_10_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - /// Verifies that the 10-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_10_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - RegisterServices10( - resolver, - out var s1, - out var s2, - out var s3, - out var s4, - out var s5, - out var s6, - out var s7, - out var s8, - out var s9, - out var s10); - _ = builder.WithCoreServices().Build(); - - InvokeWithInstance10( - builder, - out var captured1, - out var captured2, - out var captured3, - out var captured4, - out var captured5, - out var captured6, - out var captured7, - out var captured8, - out var captured9, - out var captured10); - - await AssertSameReferences10( - captured1, - s1, - captured2, - s2, - captured3, - s3, - captured4, - s4, - captured5, - s5, - captured6, - s6, - captured7, - s7, - captured8, - s8, - captured9, - s9, - captured10, - s10); - } - - /// Verifies that the 10-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Major Code Smell", - "SST1472:Signatures should not declare too many parameters", - Justification = "Test exercises a variadic overload.")] - public async Task Extension_WithInstance_10_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07, - InstanceService08, - InstanceService09, - InstanceService10>((_, _, _, _, _, _, _, _, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } - /// Verifies that the 11-types WithInstance builder instance method invokes the action with the resolved instances. /// A task representing the asynchronous test. [Test] @@ -286,100 +197,6 @@ public async Task Builder_WithInstance_11_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - /// Verifies that the 11-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_11_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - RegisterServices11( - resolver, - out var s1, - out var s2, - out var s3, - out var s4, - out var s5, - out var s6, - out var s7, - out var s8, - out var s9, - out var s10, - out var s11); - _ = builder.WithCoreServices().Build(); - - InvokeWithInstance11( - builder, - out var captured1, - out var captured2, - out var captured3, - out var captured4, - out var captured5, - out var captured6, - out var captured7, - out var captured8, - out var captured9, - out var captured10, - out var captured11); - - await AssertSameReferences11( - captured1, - s1, - captured2, - s2, - captured3, - s3, - captured4, - s4, - captured5, - s5, - captured6, - s6, - captured7, - s7, - captured8, - s8, - captured9, - s9, - captured10, - s10, - captured11, - s11); - } - - /// Verifies that the 11-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Major Code Smell", - "SST1472:Signatures should not declare too many parameters", - Justification = "Test exercises a variadic overload.")] - public async Task Extension_WithInstance_11_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07, - InstanceService08, - InstanceService09, - InstanceService10, - InstanceService11>((_, _, _, _, _, _, _, _, _, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } - /// Verifies that the 12-types WithInstance builder instance method invokes the action with the resolved instances. /// A task representing the asynchronous test. [Test] @@ -478,103 +295,4 @@ public async Task Builder_WithInstance_12_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - - /// Verifies that the 12-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_12_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - RegisterServices12( - resolver, - out var s1, - out var s2, - out var s3, - out var s4, - out var s5, - out var s6, - out var s7, - out var s8, - out var s9, - out var s10, - out var s11, - out var s12); - _ = builder.WithCoreServices().Build(); - - InvokeWithInstance12( - builder, - out var captured1, - out var captured2, - out var captured3, - out var captured4, - out var captured5, - out var captured6, - out var captured7, - out var captured8, - out var captured9, - out var captured10, - out var captured11, - out var captured12); - - await AssertSameReferences12( - captured1, - s1, - captured2, - s2, - captured3, - s3, - captured4, - s4, - captured5, - s5, - captured6, - s6, - captured7, - s7, - captured8, - s8, - captured9, - s9, - captured10, - s10, - captured11, - s11, - captured12, - s12); - } - - /// Verifies that the 12-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Major Code Smell", - "SST1472:Signatures should not declare too many parameters", - Justification = "Test exercises a variadic overload.")] - public async Task Extension_WithInstance_12_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07, - InstanceService08, - InstanceService09, - InstanceService10, - InstanceService11, - InstanceService12>((_, _, _, _, _, _, _, _, _, _, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } } diff --git a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity13to14.cs b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity13to14.cs index 454e54beba..fa0d2d3c59 100644 --- a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity13to14.cs +++ b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity13to14.cs @@ -119,111 +119,6 @@ public async Task Builder_WithInstance_13_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - /// Verifies that the 13-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_13_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - RegisterServices13( - resolver, - out var s1, - out var s2, - out var s3, - out var s4, - out var s5, - out var s6, - out var s7, - out var s8, - out var s9, - out var s10, - out var s11, - out var s12, - out var s13); - _ = builder.WithCoreServices().Build(); - - InvokeWithInstance13( - builder, - out var captured1, - out var captured2, - out var captured3, - out var captured4, - out var captured5, - out var captured6, - out var captured7, - out var captured8, - out var captured9, - out var captured10, - out var captured11, - out var captured12, - out var captured13); - - await AssertSameReferences13( - captured1, - s1, - captured2, - s2, - captured3, - s3, - captured4, - s4, - captured5, - s5, - captured6, - s6, - captured7, - s7, - captured8, - s8, - captured9, - s9, - captured10, - s10, - captured11, - s11, - captured12, - s12, - captured13, - s13); - } - - /// Verifies that the 13-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Major Code Smell", - "SST1472:Signatures should not declare too many parameters", - Justification = "Test exercises a variadic overload.")] - public async Task Extension_WithInstance_13_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07, - InstanceService08, - InstanceService09, - InstanceService10, - InstanceService11, - InstanceService12, - InstanceService13>((_, _, _, _, _, _, _, _, _, _, _, _, _) => - invoked = true); - - await Assert.That(invoked).IsFalse(); - } - /// Verifies that the 14-types WithInstance builder instance method invokes the action with the resolved instances. /// A task representing the asynchronous test. [Test] @@ -332,113 +227,4 @@ public async Task Builder_WithInstance_14_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - - /// Verifies that the 14-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_14_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - RegisterServices14( - resolver, - out var s1, - out var s2, - out var s3, - out var s4, - out var s5, - out var s6, - out var s7, - out var s8, - out var s9, - out var s10, - out var s11, - out var s12, - out var s13, - out var s14); - _ = builder.WithCoreServices().Build(); - - InvokeWithInstance14( - builder, - out var captured1, - out var captured2, - out var captured3, - out var captured4, - out var captured5, - out var captured6, - out var captured7, - out var captured8, - out var captured9, - out var captured10, - out var captured11, - out var captured12, - out var captured13, - out var captured14); - - await AssertSameReferences14( - captured1, - s1, - captured2, - s2, - captured3, - s3, - captured4, - s4, - captured5, - s5, - captured6, - s6, - captured7, - s7, - captured8, - s8, - captured9, - s9, - captured10, - s10, - captured11, - s11, - captured12, - s12, - captured13, - s13, - captured14, - s14); - } - - /// Verifies that the 14-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Major Code Smell", - "SST1472:Signatures should not declare too many parameters", - Justification = "Test exercises a variadic overload.")] - public async Task Extension_WithInstance_14_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07, - InstanceService08, - InstanceService09, - InstanceService10, - InstanceService11, - InstanceService12, - InstanceService13, - InstanceService14>((_, _, _, _, _, _, _, _, _, _, _, _, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } } diff --git a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity15to16.cs b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity15to16.cs index 62d7966094..959d8c3ad4 100644 --- a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity15to16.cs +++ b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderInstanceMixinsTests.Arity15to16.cs @@ -128,120 +128,6 @@ public async Task Builder_WithInstance_15_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - /// Verifies that the 15-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_15_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - RegisterServices15( - resolver, - out var s1, - out var s2, - out var s3, - out var s4, - out var s5, - out var s6, - out var s7, - out var s8, - out var s9, - out var s10, - out var s11, - out var s12, - out var s13, - out var s14, - out var s15); - _ = builder.WithCoreServices().Build(); - - InvokeWithInstance15( - builder, - out var captured1, - out var captured2, - out var captured3, - out var captured4, - out var captured5, - out var captured6, - out var captured7, - out var captured8, - out var captured9, - out var captured10, - out var captured11, - out var captured12, - out var captured13, - out var captured14, - out var captured15); - - await AssertSameReferences15( - captured1, - s1, - captured2, - s2, - captured3, - s3, - captured4, - s4, - captured5, - s5, - captured6, - s6, - captured7, - s7, - captured8, - s8, - captured9, - s9, - captured10, - s10, - captured11, - s11, - captured12, - s12, - captured13, - s13, - captured14, - s14, - captured15, - s15); - } - - /// Verifies that the 15-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Major Code Smell", - "SST1472:Signatures should not declare too many parameters", - Justification = "Test exercises a variadic overload.")] - public async Task Extension_WithInstance_15_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07, - InstanceService08, - InstanceService09, - InstanceService10, - InstanceService11, - InstanceService12, - InstanceService13, - InstanceService14, - InstanceService15>((_, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } - /// Verifies that the 16-types WithInstance builder instance method invokes the action with the resolved instances. /// A task representing the asynchronous test. [Test] @@ -360,123 +246,4 @@ public async Task Builder_WithInstance_16_Types_skips_when_null() await Assert.That(invoked).IsFalse(); } - - /// Verifies that the 16-types WithInstance extension method invokes the action with the resolved instances. - /// A task representing the asynchronous test. - [Test] - public async Task Extension_WithInstance_16_Types_invokes_action() - { - using var resolver = new ModernDependencyResolver(); - var builder = resolver.CreateReactiveUIBuilder(); - RegisterServices16( - resolver, - out var s1, - out var s2, - out var s3, - out var s4, - out var s5, - out var s6, - out var s7, - out var s8, - out var s9, - out var s10, - out var s11, - out var s12, - out var s13, - out var s14, - out var s15, - out var s16); - _ = builder.WithCoreServices().Build(); - - InvokeWithInstance16( - builder, - out var captured1, - out var captured2, - out var captured3, - out var captured4, - out var captured5, - out var captured6, - out var captured7, - out var captured8, - out var captured9, - out var captured10, - out var captured11, - out var captured12, - out var captured13, - out var captured14, - out var captured15, - out var captured16); - - await AssertSameReferences16( - captured1, - s1, - captured2, - s2, - captured3, - s3, - captured4, - s4, - captured5, - s5, - captured6, - s6, - captured7, - s7, - captured8, - s8, - captured9, - s9, - captured10, - s10, - captured11, - s11, - captured12, - s12, - captured13, - s13, - captured14, - s14, - captured15, - s15, - captured16, - s16); - } - - /// Verifies that the 16-types WithInstance extension method skips the action when the current resolver is null. - /// A task representing the asynchronous test. - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage( - "Major Code Smell", - "SST1472:Signatures should not declare too many parameters", - Justification = "Test exercises a variadic overload.")] - public async Task Extension_WithInstance_16_Types_skips_when_null() - { - using var resolver = new ModernDependencyResolver(); - var builder = new ReactiveUIBuilder( - resolver, - null); - _ = builder.WithCoreServices(); - - var invoked = false; - _ = builder - .WithInstance< - InstanceService01, - InstanceService02, - InstanceService03, - InstanceService04, - InstanceService05, - InstanceService06, - InstanceService07, - InstanceService08, - InstanceService09, - InstanceService10, - InstanceService11, - InstanceService12, - InstanceService13, - InstanceService14, - InstanceService15, - InstanceService16>((_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) => invoked = true); - - await Assert.That(invoked).IsFalse(); - } } diff --git a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderMixinsTests.cs b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderMixinsTests.cs index 589a6df43a..13b919a0ab 100644 --- a/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderMixinsTests.cs +++ b/src/tests/ReactiveUI.Builder.Tests/Mixins/BuilderMixinsTests.cs @@ -644,7 +644,7 @@ public IAppBuilder UsingModule(T registrationModule) } /// - public IAppBuilder WithCoreServices() => this; + public IAppBuilder WithCoreServices() => UseCurrentSplatLocator(); /// public IAppBuilder WithCustomRegistration(Action configureAction) diff --git a/src/tests/ReactiveUI.Maui.Tests/BooleanToVisibilityTypeConverterTest.cs b/src/tests/ReactiveUI.Maui.Tests/BooleanToVisibilityTypeConverterTest.cs index 868a0ccafa..5bf9d72668 100644 --- a/src/tests/ReactiveUI.Maui.Tests/BooleanToVisibilityTypeConverterTest.cs +++ b/src/tests/ReactiveUI.Maui.Tests/BooleanToVisibilityTypeConverterTest.cs @@ -30,7 +30,7 @@ public async Task GetAffinityForObjects_ReturnsCorrectAffinityForBoolToVisibilit [Test] public async Task GetAffinityForObjects_ReturnsCorrectAffinityForVisibilityToBool() { - var converter = new BooleanToVisibilityTypeConverter(); + var converter = new VisibilityToBooleanTypeConverter(); var affinity = converter.GetAffinityForObjects(); @@ -118,10 +118,10 @@ public async Task TryConvert_BooleanConverter_HandlesInput() { var converter = new BooleanToVisibilityTypeConverter(); - var success = converter.TryConvertTyped(false, null, out var result); + var success = converter.TryConvertTyped("not a boolean", null, out var result); - await Assert.That(success).IsTrue(); - await Assert.That(result).IsEqualTo(Visibility.Collapsed); + await Assert.That(success).IsFalse(); + await Assert.That(result).IsNull(); } /// Tests that TryConvert with Inverse hint on Visibility to bool. diff --git a/src/tests/ReactiveUI.Maui.Tests/Builder/MauiDispatcherSequencerTest.cs b/src/tests/ReactiveUI.Maui.Tests/Builder/MauiDispatcherSequencerTest.cs index 08622258ca..01c6b88bd5 100644 --- a/src/tests/ReactiveUI.Maui.Tests/Builder/MauiDispatcherSequencerTest.cs +++ b/src/tests/ReactiveUI.Maui.Tests/Builder/MauiDispatcherSequencerTest.cs @@ -81,8 +81,8 @@ public bool Dispatch(Action action) /// public bool DispatchDelayed(TimeSpan delay, Action action) { - action(); - return true; + _ = delay; + return Dispatch(action); } /// diff --git a/src/tests/ReactiveUI.Maui.Tests/Builder/MauiReactiveUIBuilderExtensionsTest.cs b/src/tests/ReactiveUI.Maui.Tests/Builder/MauiReactiveUIBuilderExtensionsTest.cs index 343d145b41..8763ea1583 100644 --- a/src/tests/ReactiveUI.Maui.Tests/Builder/MauiReactiveUIBuilderExtensionsTest.cs +++ b/src/tests/ReactiveUI.Maui.Tests/Builder/MauiReactiveUIBuilderExtensionsTest.cs @@ -152,8 +152,8 @@ public bool Dispatch(Action action) /// public bool DispatchDelayed(TimeSpan delay, Action action) { - action(); - return true; + _ = delay; + return Dispatch(action); } /// diff --git a/src/tests/ReactiveUI.Maui.Tests/TestDispatcher.cs b/src/tests/ReactiveUI.Maui.Tests/TestDispatcher.cs index 4458b32302..a2a3fd1135 100644 --- a/src/tests/ReactiveUI.Maui.Tests/TestDispatcher.cs +++ b/src/tests/ReactiveUI.Maui.Tests/TestDispatcher.cs @@ -23,8 +23,8 @@ public bool Dispatch(Action action) /// public bool DispatchDelayed(TimeSpan delay, Action action) { - action(); - return true; + _ = delay; + return Dispatch(action); } /// diff --git a/src/tests/ReactiveUI.Maui.Tests/ViewModelViewHostTest.cs b/src/tests/ReactiveUI.Maui.Tests/ViewModelViewHostTest.cs index 8293f84719..97fcd44a58 100644 --- a/src/tests/ReactiveUI.Maui.Tests/ViewModelViewHostTest.cs +++ b/src/tests/ReactiveUI.Maui.Tests/ViewModelViewHostTest.cs @@ -299,7 +299,7 @@ private sealed class MockViewLocator : IViewLocator /// public IViewFor? ResolveView(string? contract) - where T : class => _view as IViewFor; + where T : class => ResolveView(); /// public IViewFor? ResolveView() @@ -309,16 +309,16 @@ private sealed class MockViewLocator : IViewLocator [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public IViewFor? ResolveView(object? instance, string? contract) => _view; /// [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public IViewFor? ResolveView(object? instance) => _view; } @@ -344,16 +344,16 @@ private sealed class TestViewLocator : IViewLocator [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public IViewFor? ResolveView(object? instance, string? contract) => null; /// [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public IViewFor? ResolveView(object? instance) => null; } @@ -379,7 +379,7 @@ private sealed class NonViewLocator : IViewLocator /// public IViewFor? ResolveView(string? contract) - where T : class => _view as IViewFor; + where T : class => ResolveView(); /// public IViewFor? ResolveView() @@ -389,16 +389,16 @@ private sealed class NonViewLocator : IViewLocator [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public IViewFor? ResolveView(object? instance, string? contract) => _view; /// [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public IViewFor? ResolveView(object? instance) => _view; } } diff --git a/src/tests/ReactiveUI.Test.Utilities/Logging/TestLogger.cs b/src/tests/ReactiveUI.Test.Utilities/Logging/TestLogger.cs index 66dff9f36b..536ab395bb 100644 --- a/src/tests/ReactiveUI.Test.Utilities/Logging/TestLogger.cs +++ b/src/tests/ReactiveUI.Test.Utilities/Logging/TestLogger.cs @@ -40,11 +40,11 @@ public void Write(Exception exception, string message, Type type, LogLevel logLe Messages.Add((message, typeof(TestLogger), logLevel)); /// - public void Write(string message, LogLevel logLevel) => Messages.Add((message, typeof(TestLogger), logLevel)); + public void Write(string message, LogLevel logLevel) => Write(message, typeof(TestLogger), logLevel); /// public void Write(Exception exception, string message, LogLevel logLevel) => - Messages.Add((message, typeof(TestLogger), logLevel)); + Write(message, logLevel); /// public void Write([Localizable(false)] string message, [Localizable(false)] Type type, LogLevel logLevel) => diff --git a/src/tests/ReactiveUI.Test.Utilities/Schedulers/VirtualTimeScheduler.cs b/src/tests/ReactiveUI.Test.Utilities/Schedulers/VirtualTimeScheduler.cs index 7b0da7895d..c8430ca3f2 100644 --- a/src/tests/ReactiveUI.Test.Utilities/Schedulers/VirtualTimeScheduler.cs +++ b/src/tests/ReactiveUI.Test.Utilities/Schedulers/VirtualTimeScheduler.cs @@ -44,7 +44,7 @@ public IDisposable Schedule( TState state, DateTimeOffset dueTime, Func action) => - _scheduler.Schedule(state, dueTime, action); + _scheduler.Schedule(state, dueTime - Now, action); #else /// Gets the current monotonic timestamp. public long Timestamp => _clock.Timestamp; @@ -82,32 +82,32 @@ public IDisposable Schedule( TState state, DateTimeOffset dueTime, Func action) => - _clock.Schedule(state, dueTime, action); + _clock.Schedule(state, dueTime - Now, action); #endif /// Advances virtual time by the specified duration, executing all scheduled actions. /// The time span to advance. - public void AdvanceBy(TimeSpan time) + public void AdvanceBy(TimeSpan time) => #if REACTIVE_SHIM - => _scheduler.AdvanceBy(time.Ticks); + _scheduler.AdvanceBy(time.Ticks); #else - => _clock.AdvanceBy(time); + _clock.AdvanceBy(time); #endif /// Advances virtual time to the specified absolute time, executing all scheduled actions. /// The absolute time to advance to. - public void AdvanceTo(DateTimeOffset time) + public void AdvanceTo(DateTimeOffset time) => #if REACTIVE_SHIM - => _scheduler.AdvanceTo((time - DateTimeOffset.MinValue).Ticks); + _scheduler.AdvanceTo((time - DateTimeOffset.MinValue).Ticks); #else - => _clock.AdvanceTo(time); + _clock.AdvanceTo(time); #endif /// Runs all scheduled actions until there are no more. - public void Start() + public void Start() => #if REACTIVE_SHIM - => _scheduler.Start(); + _scheduler.Start(); #else - => _clock.Start(); + _clock.Start(); #endif } diff --git a/src/tests/ReactiveUI.Testing.Tests/AppBuilderTestBaseTests.cs b/src/tests/ReactiveUI.Testing.Tests/AppBuilderTestBaseTests.cs index cfe6f1d221..d498efcd90 100644 --- a/src/tests/ReactiveUI.Testing.Tests/AppBuilderTestBaseTests.cs +++ b/src/tests/ReactiveUI.Testing.Tests/AppBuilderTestBaseTests.cs @@ -95,12 +95,12 @@ private sealed class TestHelper : AppBuilderTestBase /// The asynchronous test body to execute. /// A representing the asynchronous operation. public static new Task RunAppBuilderTestAsync(Func testBody) => - AppBuilderTestBase.RunAppBuilderTestAsync(testBody); + AppBuilderTestBase.RunAppBuilderTestAsync((Func)testBody); /// Exposes the protected synchronous app builder test runner for testing. /// The synchronous test body to execute. /// A representing the asynchronous operation. public static new Task RunAppBuilderTestAsync(Action testBody) => - AppBuilderTestBase.RunAppBuilderTestAsync(testBody); + AppBuilderTestBase.RunAppBuilderTestAsync((Action)testBody); } } diff --git a/src/tests/ReactiveUI.Tests.Reactive/ReactiveUI.Tests.Reactive.csproj b/src/tests/ReactiveUI.Tests.Reactive/ReactiveUI.Tests.Reactive.csproj index fa526333fa..0a3e944342 100644 --- a/src/tests/ReactiveUI.Tests.Reactive/ReactiveUI.Tests.Reactive.csproj +++ b/src/tests/ReactiveUI.Tests.Reactive/ReactiveUI.Tests.Reactive.csproj @@ -30,4 +30,8 @@ Resources.Designer.cs + + + + diff --git a/src/tests/ReactiveUI.Tests/AutoPersist/AutoPersistHelperTest.cs b/src/tests/ReactiveUI.Tests/AutoPersist/AutoPersistHelperTest.cs index 4780a99f6c..b67d13e5b0 100644 --- a/src/tests/ReactiveUI.Tests/AutoPersist/AutoPersistHelperTest.cs +++ b/src/tests/ReactiveUI.Tests/AutoPersist/AutoPersistHelperTest.cs @@ -387,7 +387,7 @@ public async Task AutoPersist_NullManualSaveSignal_ThrowsArgumentNullException() await Assert.ThrowsAsync(async () => { - _ = fixture.AutoPersist(static _ => ImmutableReturnRxVoidSignal.Instance, null!, TimeSpan.FromSeconds(1)); + _ = fixture.AutoPersist(static _ => ImmutableReturnRxVoidSignal.Instance, (IObservable)null!, TimeSpan.FromSeconds(1)); await Task.CompletedTask; }); } @@ -401,7 +401,7 @@ public async Task AutoPersist_NullMetadata_ThrowsArgumentNullException() await Assert.ThrowsAsync(async () => { - _ = fixture.AutoPersist(static _ => ImmutableReturnRxVoidSignal.Instance, null!, TimeSpan.FromSeconds(1)); + _ = fixture.AutoPersist(static _ => ImmutableReturnRxVoidSignal.Instance, (AutoPersistHelperMixins.AutoPersistMetadata)null!, TimeSpan.FromSeconds(1)); await Task.CompletedTask; }); } @@ -532,8 +532,8 @@ private sealed class ObjectWithoutDataContract : ReactiveObject [SuppressMessage( "Design", "SST2324:Public member on a non-public type", - Justification = "the public surface is required for interface/reflection binding; the containing " + - "test double is an intentionally non-public detail.")] + Justification = "the public surface is required for interface/reflection binding; the containing " + + "test double is an intentionally non-public detail.")] public string? Property { get; @@ -550,8 +550,8 @@ private class DataContractBaseFixture : ReactiveObject [SuppressMessage( "Design", "SST2324:Public member on a non-public type", - Justification = "the public surface is required for interface/reflection binding; the containing " + - "test double is an intentionally non-public detail.")] + Justification = "the public surface is required for interface/reflection binding; the containing " + + "test double is an intentionally non-public detail.")] public string? BaseValue { get; diff --git a/src/tests/ReactiveUI.Tests/Bindings/CommandBindings/CreatesCommandBindingViaCommandParameterTests.cs b/src/tests/ReactiveUI.Tests/Bindings/CommandBindings/CreatesCommandBindingViaCommandParameterTests.cs index b124013679..020c958ca4 100644 --- a/src/tests/ReactiveUI.Tests/Bindings/CommandBindings/CreatesCommandBindingViaCommandParameterTests.cs +++ b/src/tests/ReactiveUI.Tests/Bindings/CommandBindings/CreatesCommandBindingViaCommandParameterTests.cs @@ -153,26 +153,6 @@ public async Task GetAffinityForObject_Generic_WithEventTarget_Returns0() await Assert.That(affinity).IsEqualTo(0); } - /// Verifies that the affinity check returns 5 for targets with command and command parameter properties. - /// A representing the asynchronous unit test. - [Test] - public async Task GetAffinityForObject_WithCommandAndCommandParameter_Returns5() - { - var binder = new CreatesCommandBindingViaCommandParameter(); - var affinity = binder.GetAffinityForObject(false); - await Assert.That(affinity).IsEqualTo(BindingAffinity.Explicit); - } - - /// Verifies that the affinity check returns 0 when an event target is requested. - /// A representing the asynchronous unit test. - [Test] - public async Task GetAffinityForObject_WithEventTarget_Returns0() - { - var binder = new CreatesCommandBindingViaCommandParameter(); - var affinity = binder.GetAffinityForObject(true); - await Assert.That(affinity).IsEqualTo(0); - } - /// Verifies that the affinity check returns 0 when only a command property is present. /// A representing the asynchronous unit test. [Test] diff --git a/src/tests/ReactiveUI.Tests/Bindings/CommandBindings/CreatesCommandBindingViaEventTests.cs b/src/tests/ReactiveUI.Tests/Bindings/CommandBindings/CreatesCommandBindingViaEventTests.cs index 4a15e811a5..d21b35b8ca 100644 --- a/src/tests/ReactiveUI.Tests/Bindings/CommandBindings/CreatesCommandBindingViaEventTests.cs +++ b/src/tests/ReactiveUI.Tests/Bindings/CommandBindings/CreatesCommandBindingViaEventTests.cs @@ -202,26 +202,6 @@ public async Task GetAffinityForObject_Generic_WithEventTarget_Returns5() await Assert.That(affinity).IsEqualTo(BindingAffinity.Explicit); } - /// Verifies that the affinity check returns 3 for a target exposing a Click event. - /// A representing the asynchronous unit test. - [Test] - public async Task GetAffinityForObject_WithClickEvent_Returns3() - { - var binder = new CreatesCommandBindingViaEvent(); - var affinity = binder.GetAffinityForObject(false); - await Assert.That(affinity).IsEqualTo(BindingAffinity.DefaultEvent); - } - - /// Verifies that the affinity check returns 5 when an event target is requested. - /// A representing the asynchronous unit test. - [Test] - public async Task GetAffinityForObject_WithEventTarget_Returns5() - { - var binder = new CreatesCommandBindingViaEvent(); - var affinity = binder.GetAffinityForObject(true); - await Assert.That(affinity).IsEqualTo(BindingAffinity.Explicit); - } - /// Verifies that the affinity check returns 3 for a target exposing a MouseUp event. /// A representing the asynchronous unit test. [Test] diff --git a/src/tests/ReactiveUI.Tests/Bindings/Converters/ConverterMigrationHelperTests.cs b/src/tests/ReactiveUI.Tests/Bindings/Converters/ConverterMigrationHelperTests.cs index bc8480fded..bf20d57a00 100644 --- a/src/tests/ReactiveUI.Tests/Bindings/Converters/ConverterMigrationHelperTests.cs +++ b/src/tests/ReactiveUI.Tests/Bindings/Converters/ConverterMigrationHelperTests.cs @@ -323,26 +323,26 @@ private sealed class TestDependencyResolver : IReadonlyDependencyResolver public object? GetService(Type? serviceType) => _services.FirstOrDefault(); /// - public object? GetService(Type? serviceType, string? contract) => _services.FirstOrDefault(); + public object? GetService(Type? serviceType, string? contract) => GetService(serviceType); /// public T? GetService() => _services.OfType().FirstOrDefault(); /// - public T? GetService(string? contract) => _services.OfType().FirstOrDefault(); + public T? GetService(string? contract) => GetService(); /// public IEnumerable GetServices(Type? serviceType) => _services.Where(static s => s is not null); /// public IEnumerable GetServices(Type? serviceType, string? contract) => - _services.Where(static s => s is not null); + GetServices(serviceType); /// public IEnumerable GetServices() => _services.OfType(); /// - public IEnumerable GetServices(string? contract) => _services.OfType(); + public IEnumerable GetServices(string? contract) => GetServices(); } /// Test typed converter for testing purposes. diff --git a/src/tests/ReactiveUI.Tests/Bindings/Property/Mocks/MockBindingConverterResolver.cs b/src/tests/ReactiveUI.Tests/Bindings/Property/Mocks/MockBindingConverterResolver.cs index 523b1c463a..9e6acddb69 100644 --- a/src/tests/ReactiveUI.Tests/Bindings/Property/Mocks/MockBindingConverterResolver.cs +++ b/src/tests/ReactiveUI.Tests/Bindings/Property/Mocks/MockBindingConverterResolver.cs @@ -15,8 +15,8 @@ namespace ReactiveUI.Tests.Bindings.Property.Mocks; [SuppressMessage( "Design", "SST2324:public member on non-public type", - Justification = "the public API is exercised directly by tests; the containing mock type is an " + - "intentionally non-public implementation detail of the test project.")] + Justification = "the public API is exercised directly by tests; the containing mock type is an " + + "intentionally non-public implementation detail of the test project.")] internal sealed class MockBindingConverterResolver : IBindingConverterResolver { /// The registered type converters keyed by source and target type. diff --git a/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/BindingConverterResolverTests.cs b/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/BindingConverterResolverTests.cs index ceaa56d52a..06f994de9b 100644 --- a/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/BindingConverterResolverTests.cs +++ b/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/BindingConverterResolverTests.cs @@ -172,22 +172,6 @@ public async Task GetSetMethodConverter_WithNullToType_HandlesGracefully() await Assert.That(converterFunc).IsNull(); } - /// Verifies that GetBindingConverter handles null services gracefully. - /// A representing the asynchronous unit test. - [Test] - public async Task GetBindingConverter_WithNoRxConverters_FallsBackToSplat() - { - // Arrange - var resolver = new BindingConverterResolver(); - - // Act - Get a converter that should be found in Splat - var converter = resolver.GetBindingConverter(typeof(MockType), typeof(MockType)); - - // Assert - await Assert.That(converter).IsNotNull(); - await Assert.That(converter).IsTypeOf(); - } - /// Test executor that registers mock converters. public class Executor : BaseAppBuilderTestExecutor { diff --git a/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/BindingHookEvaluatorTests.cs b/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/BindingHookEvaluatorTests.cs index 5f51b9415d..104b5193d0 100644 --- a/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/BindingHookEvaluatorTests.cs +++ b/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/BindingHookEvaluatorTests.cs @@ -247,8 +247,8 @@ public bool ExecuteHook( var viewModelProperties = getCurrentViewModelProperties(); // Reject if the property name is "RejectMe" - return viewModelProperties is null || viewModelProperties.Length == 0 || - viewModelProperties[^1].Expression?.GetMemberInfo()?.Name != "RejectMe"; + return viewModelProperties is null || viewModelProperties.Length == 0 + || viewModelProperties[^1].Expression?.GetMemberInfo()?.Name != "RejectMe"; } } diff --git a/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/PropertyBindingExpressionCompilerTests.cs b/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/PropertyBindingExpressionCompilerTests.cs index 1bb7a9a17b..b817b9b1ea 100644 --- a/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/PropertyBindingExpressionCompilerTests.cs +++ b/src/tests/ReactiveUI.Tests/Bindings/Property/Unit/PropertyBindingExpressionCompilerTests.cs @@ -47,8 +47,8 @@ public async Task CreateSetThenGet_ForSimpleProperty_SetsAndGetsValue() Expression> expr = v => v.SomeStringProperty; var rewritten = Reflection.Rewrite(expr.Body); var memberInfo = rewritten.GetMemberInfo(); - var getter = Reflection.GetValueFetcherOrThrow(memberInfo) ?? - throw new InvalidOperationException(GetterNotFoundMessage); + var getter = Reflection.GetValueFetcherOrThrow(memberInfo) + ?? throw new InvalidOperationException(GetterNotFoundMessage); var setter = Reflection.GetValueSetterOrThrow(memberInfo); // Act @@ -73,8 +73,8 @@ public async Task CreateSetThenGet_WhenValueUnchanged_DoesNotEmit() Expression> expr = v => v.SomeStringProperty; var rewritten = Reflection.Rewrite(expr.Body); var memberInfo = rewritten.GetMemberInfo(); - var getter = Reflection.GetValueFetcherOrThrow(memberInfo) ?? - throw new InvalidOperationException(GetterNotFoundMessage); + var getter = Reflection.GetValueFetcherOrThrow(memberInfo) + ?? throw new InvalidOperationException(GetterNotFoundMessage); var setter = Reflection.GetValueSetterOrThrow(memberInfo); // Act @@ -98,8 +98,8 @@ public async Task CreateSetThenGet_WithConverter_ConvertsAndSetsValue() Expression> expr = v => v.SomeStringProperty; var rewritten = Reflection.Rewrite(expr.Body); var memberInfo = rewritten.GetMemberInfo(); - var getter = Reflection.GetValueFetcherOrThrow(memberInfo) ?? - throw new InvalidOperationException(GetterNotFoundMessage); + var getter = Reflection.GetValueFetcherOrThrow(memberInfo) + ?? throw new InvalidOperationException(GetterNotFoundMessage); var setter = Reflection.GetValueSetterOrThrow(memberInfo); // Act @@ -126,8 +126,8 @@ public async Task CreateSetThenGet_WithConverter_WhenConvertedValueUnchanged_Doe Expression> expr = v => v.SomeStringProperty; var rewritten = Reflection.Rewrite(expr.Body); var memberInfo = rewritten.GetMemberInfo(); - var getter = Reflection.GetValueFetcherOrThrow(memberInfo) ?? - throw new InvalidOperationException(GetterNotFoundMessage); + var getter = Reflection.GetValueFetcherOrThrow(memberInfo) + ?? throw new InvalidOperationException(GetterNotFoundMessage); var setter = Reflection.GetValueSetterOrThrow(memberInfo); // Act @@ -272,8 +272,8 @@ public async Task CreateDirectSetObservable_EmitsChanges() Expression> expr = v => v.SomeStringProperty; var rewritten = Reflection.Rewrite(expr.Body); var memberInfo = rewritten.GetMemberInfo(); - var getter = Reflection.GetValueFetcherOrThrow(memberInfo) ?? - throw new InvalidOperationException(GetterNotFoundMessage); + var getter = Reflection.GetValueFetcherOrThrow(memberInfo) + ?? throw new InvalidOperationException(GetterNotFoundMessage); var setter = Reflection.GetValueSetterOrThrow(memberInfo); // Act @@ -313,8 +313,8 @@ public async Task CreateDirectSetObservable_WhenValueUnchanged_DoesNotEmit() Expression> expr = v => v.SomeStringProperty; var rewritten = Reflection.Rewrite(expr.Body); var memberInfo = rewritten.GetMemberInfo(); - var getter = Reflection.GetValueFetcherOrThrow(memberInfo) ?? - throw new InvalidOperationException(GetterNotFoundMessage); + var getter = Reflection.GetValueFetcherOrThrow(memberInfo) + ?? throw new InvalidOperationException(GetterNotFoundMessage); var setter = Reflection.GetValueSetterOrThrow(memberInfo); // Act @@ -352,8 +352,8 @@ public async Task CreateDirectSetObservable_WithConverter_ConvertsAndSetsValue() Expression> expr = v => v.SomeStringProperty; var rewritten = Reflection.Rewrite(expr.Body); var memberInfo = rewritten.GetMemberInfo(); - var getter = Reflection.GetValueFetcherOrThrow(memberInfo) ?? - throw new InvalidOperationException(GetterNotFoundMessage); + var getter = Reflection.GetValueFetcherOrThrow(memberInfo) + ?? throw new InvalidOperationException(GetterNotFoundMessage); var setter = Reflection.GetValueSetterOrThrow(memberInfo); // Act @@ -397,8 +397,8 @@ public async Task CreateChainedSetObservable_EmitsChanges() var rewritten = Reflection.Rewrite(expr.Body); var chain = compiler.GetExpressionChainArray(rewritten.GetParent())!; var memberInfo = rewritten.GetMemberInfo(); - var getter = Reflection.GetValueFetcherOrThrow(memberInfo) ?? - throw new InvalidOperationException(GetterNotFoundMessage); + var getter = Reflection.GetValueFetcherOrThrow(memberInfo) + ?? throw new InvalidOperationException(GetterNotFoundMessage); var setter = Reflection.GetValueSetterOrThrow(memberInfo); // Act @@ -462,9 +462,9 @@ public string? SomeStringProperty [SuppressMessage( "Design", "SST2324:'SomeIntProperty' is declared 'public' but its containing type is only reachable as 'private'", - Justification = "mirrors the shape of the sibling TestView fixtures used across the property-binding " + - "compiler tests; this file's scenarios do not currently exercise it, but the public accessor keeps " + - "parity with those fixtures.")] + Justification = "mirrors the shape of the sibling TestView fixtures used across the property-binding " + + "compiler tests; this file's scenarios do not currently exercise it, but the public accessor keeps " + + "parity with those fixtures.")] public int SomeIntProperty { get; diff --git a/src/tests/ReactiveUI.Tests/ChangeSets/ChangeSetExtensionsTests.cs b/src/tests/ReactiveUI.Tests/ChangeSets/ChangeSetExtensionsTests.cs index d7d64d8c84..093a912369 100644 --- a/src/tests/ReactiveUI.Tests/ChangeSets/ChangeSetExtensionsTests.cs +++ b/src/tests/ReactiveUI.Tests/ChangeSets/ChangeSetExtensionsTests.cs @@ -122,6 +122,6 @@ private sealed class RaisingCollection : INotifyCollectionChanged, IEnumerable GetEnumerator() => _items.GetEnumerator(); /// - IEnumerator IEnumerable.GetEnumerator() => _items.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } } diff --git a/src/tests/ReactiveUI.Tests/CommandBinding/CommandBindingTests.cs b/src/tests/ReactiveUI.Tests/CommandBinding/CommandBindingTests.cs index 45a374ee15..54a5ee7d2b 100644 --- a/src/tests/ReactiveUI.Tests/CommandBinding/CommandBindingTests.cs +++ b/src/tests/ReactiveUI.Tests/CommandBinding/CommandBindingTests.cs @@ -100,8 +100,8 @@ private sealed class FakeControl [SuppressMessage( "Design", "SST2324:public member on non-public type", - Justification = "the public surface is required for reflection/string-based event binding; the " + - "containing test double is an intentionally non-public detail.")] + Justification = "the public surface is required for reflection/string-based event binding; the " + + "containing test double is an intentionally non-public detail.")] public event EventHandler? Click; /// Raises the event. @@ -112,8 +112,8 @@ private sealed class FakeControl [SuppressMessage( "Design", "SST1452:unused type parameter", - Justification = "type parameters are mandated by the implemented interface signatures; the no-op " + - "test double does not reference them.")] + Justification = "type parameters are mandated by the implemented interface signatures; the no-op " + + "test double does not reference them.")] private sealed class FakeCustomBinder : ICreatesCommandBinding { /// The high affinity returned for . @@ -141,11 +141,8 @@ public IDisposable BindCommandToObject( T? target, IObservable commandParameter, string eventName) - where T : class - { - BindCalled = true; - return Scope.Empty; - } + where T : class => + BindCommandToObject(command, target, commandParameter); /// public IDisposable? BindCommandToObject( @@ -155,11 +152,8 @@ public IDisposable BindCommandToObject( Action> addHandler, Action> removeHandler) where T : class - where TEventArgs : EventArgs - { - BindCalled = true; - return Scope.Empty; - } + where TEventArgs : EventArgs => + BindCommandToObject(command, target, commandParameter, string.Empty); /// public int GetAffinityForObject(bool hasEventTarget) => @@ -201,8 +195,8 @@ public FakeViewModel? ViewModel [SuppressMessage( "Usage", "SST2315:type owns a disposable but is not IDisposable", - Justification = "test fixture; the owned disposable lives for the test-process lifetime and is " + - "released at process exit.")] + Justification = "test fixture; the owned disposable lives for the test-process lifetime and is " + + "released at process exit.")] private sealed class FakeViewModel : ReactiveObject { /// Gets the command under test. diff --git a/src/tests/ReactiveUI.Tests/Commands/ReactiveCommandTest.InvokeCommand.cs b/src/tests/ReactiveUI.Tests/Commands/ReactiveCommandTest.InvokeCommand.cs index cb2fe6ca32..f878e4a198 100644 --- a/src/tests/ReactiveUI.Tests/Commands/ReactiveCommandTest.InvokeCommand.cs +++ b/src/tests/ReactiveUI.Tests/Commands/ReactiveCommandTest.InvokeCommand.cs @@ -290,16 +290,14 @@ public async Task InvokeCommand_ReactiveCommandInTarget_RespectsCanExecuteWindow public async Task InvokeCommand_ReactiveCommandInTarget_SwallowsExceptions() { var count = 0; - var target = new ReactiveCommandHolder - { - TheCommand = ReactiveCommand.Create( - _ => - { - ++count; - throw new InvalidOperationException(); - }, - outputScheduler: Sequencer.Immediate) - }; + var command = ReactiveCommand.Create( + _ => + { + ++count; + throw new InvalidOperationException(); + }, + outputScheduler: Sequencer.Immediate); + var target = new ReactiveCommandHolder { TheCommand = command }; _ = target.TheCommand.ThrownExceptions.Subscribe(); var source = new Signal(); _ = source.InvokeCommand(target, x => x.TheCommand!); diff --git a/src/tests/ReactiveUI.Tests/Commands/ReactiveCommandTest.cs b/src/tests/ReactiveUI.Tests/Commands/ReactiveCommandTest.cs index 08d67c9ecf..9c337d45d5 100644 --- a/src/tests/ReactiveUI.Tests/Commands/ReactiveCommandTest.cs +++ b/src/tests/ReactiveUI.Tests/Commands/ReactiveCommandTest.cs @@ -581,8 +581,8 @@ await Assert.ThrowsExactlyAsync(static async () => [SuppressMessage( "Performance", "PSH1211:pass the value directly instead of calling ToString", - Justification = "ToString() converts the int parameter to the string result type required by " + - "CreateFromObservable; removing it would change the observable's element type.")] + Justification = "ToString() converts the int parameter to the string result type required by " + + "CreateFromObservable; removing it would change the observable's element type.")] public async Task CreateFromObservable_WithParam_PassesParameterToObservable() { var command = ReactiveCommand.CreateFromObservable( diff --git a/src/tests/ReactiveUI.Tests/Comparers/OrderedComparerTests.cs b/src/tests/ReactiveUI.Tests/Comparers/OrderedComparerTests.cs index 8f84d9dd9a..bc1ab6d6c3 100644 --- a/src/tests/ReactiveUI.Tests/Comparers/OrderedComparerTests.cs +++ b/src/tests/ReactiveUI.Tests/Comparers/OrderedComparerTests.cs @@ -71,14 +71,7 @@ public async Task SmokeTest() var carol = new Employee { Name = "Carol", Age = TiedAge, Salary = TiedSalary }; var xavier = new Employee { Name = "Xavier", Age = TiedAge, Salary = TiedSalary }; - var employees = new List - { - adam, - alice, - bob, - carol, - xavier - }; + var employees = new List { adam, alice, bob, carol, xavier }; employees.Sort(OrderedComparer.OrderBy(static x => x.Name)); await Assert.That(employees.SequenceEqual([adam, alice, bob, carol, xavier])).IsTrue(); diff --git a/src/tests/ReactiveUI.Tests/InteractionBinding/InteractionBinderImplementationTests.cs b/src/tests/ReactiveUI.Tests/InteractionBinding/InteractionBinderImplementationTests.cs index 7f4271da1e..c5b5a5a8b8 100644 --- a/src/tests/ReactiveUI.Tests/InteractionBinding/InteractionBinderImplementationTests.cs +++ b/src/tests/ReactiveUI.Tests/InteractionBinding/InteractionBinderImplementationTests.cs @@ -244,7 +244,7 @@ public async Task RegisterTaskHandlerToNewlyAssignedNestedViewModel() static input => { input.SetOutput(true); - return Signal.Emit(RxVoid.Default); + return Task.CompletedTask; }); vm.InteractionViewModel = new(); diff --git a/src/tests/ReactiveUI.Tests/Mixins/DependencyResolverMixinsTypeFactoryTests.cs b/src/tests/ReactiveUI.Tests/Mixins/DependencyResolverMixinsTypeFactoryTests.cs index e238a1a554..ad3c0c447c 100644 --- a/src/tests/ReactiveUI.Tests/Mixins/DependencyResolverMixinsTypeFactoryTests.cs +++ b/src/tests/ReactiveUI.Tests/Mixins/DependencyResolverMixinsTypeFactoryTests.cs @@ -49,8 +49,8 @@ private sealed class NoParameterlessType(int value) [SuppressMessage( "Design", "SST2324:public member on non-public type", - Justification = "the public surface mirrors the sibling test fixture's shape for readability; " + - "the containing test double is an intentionally non-public detail.")] + Justification = "the public surface mirrors the sibling test fixture's shape for readability; " + + "the containing test double is an intentionally non-public detail.")] public int Value { get; } = value; } } diff --git a/src/tests/ReactiveUI.Tests/Mocks/FakeCollectionViewModel.cs b/src/tests/ReactiveUI.Tests/Mocks/FakeCollectionViewModel.cs index 3dfb39035c..5ffe58a388 100644 --- a/src/tests/ReactiveUI.Tests/Mocks/FakeCollectionViewModel.cs +++ b/src/tests/ReactiveUI.Tests/Mocks/FakeCollectionViewModel.cs @@ -16,8 +16,8 @@ public class FakeCollectionViewModel : ReactiveObject [System.Diagnostics.CodeAnalysis.SuppressMessage( "Design", "SST2403:'this' escapes 'FakeCollectionViewModel' before construction finishes", - Justification = "canonical ObservableAsPropertyHelper initialization requires 'this' in the constructor; " + - "the single-threaded fixture never exposes the half-built instance.")] + Justification = "canonical ObservableAsPropertyHelper initialization requires 'this' in the constructor; " + + "the single-threaded fixture never exposes the half-built instance.")] public FakeCollectionViewModel(FakeCollectionModel model) { Model = model; diff --git a/src/tests/ReactiveUI.Tests/ObservedChanged/Mocks/NewGameViewModel.cs b/src/tests/ReactiveUI.Tests/ObservedChanged/Mocks/NewGameViewModel.cs index 405699dbdb..1a279f44cc 100644 --- a/src/tests/ReactiveUI.Tests/ObservedChanged/Mocks/NewGameViewModel.cs +++ b/src/tests/ReactiveUI.Tests/ObservedChanged/Mocks/NewGameViewModel.cs @@ -40,8 +40,8 @@ public NewGameViewModel() x => x.Players.Count, x => x.NewPlayerName, (count, newPlayerName) => - count < MaxPlayers && !string.IsNullOrWhiteSpace(newPlayerName) && - !Players.Contains(newPlayerName)); + count < MaxPlayers && !string.IsNullOrWhiteSpace(newPlayerName) + && !Players.Contains(newPlayerName)); AddPlayer = ReactiveCommand.Create( () => { diff --git a/src/tests/ReactiveUI.Tests/PropertyBinderImplementationAdvancedTests.cs b/src/tests/ReactiveUI.Tests/PropertyBinderImplementationAdvancedTests.cs index c2f237cf7d..d5a77d137b 100644 --- a/src/tests/ReactiveUI.Tests/PropertyBinderImplementationAdvancedTests.cs +++ b/src/tests/ReactiveUI.Tests/PropertyBinderImplementationAdvancedTests.cs @@ -557,11 +557,8 @@ public bool TryConvert( object from, Type toType, object? conversionHint, - [NotNullWhen(true)] out object? result) - { - result = null; - return false; - } + [NotNullWhen(true)] out object? result) => + TryConvertTyped(from, conversionHint, out result); } /// A test view used to exercise binding scenarios. diff --git a/src/tests/ReactiveUI.Tests/ReactiveObjects/ReactiveObjectTests.cs b/src/tests/ReactiveUI.Tests/ReactiveObjects/ReactiveObjectTests.cs index f639ee9084..a25ffb3970 100644 --- a/src/tests/ReactiveUI.Tests/ReactiveObjects/ReactiveObjectTests.cs +++ b/src/tests/ReactiveUI.Tests/ReactiveObjects/ReactiveObjectTests.cs @@ -234,8 +234,8 @@ public async Task ReactiveObjectCanSuppressChangeNotifications() public async Task ReactiveObjectShouldntSerializeAnythingExtra() { var fixture = new TestFixture { IsNotNullString = FooText, IsOnlyOneWord = BazText }; - var json = JsonHelper.Serialize(fixture) ?? - throw new InvalidOperationException("JSON string should not be null"); + var json = JsonHelper.Serialize(fixture) + ?? throw new InvalidOperationException("JSON string should not be null"); using (Assert.Multiple()) { diff --git a/src/tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj b/src/tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj index 22666a2f68..0cb93a8579 100644 --- a/src/tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj +++ b/src/tests/ReactiveUI.Tests/ReactiveUI.Tests.csproj @@ -13,6 +13,9 @@ + + + PublicResXFileCodeGenerator diff --git a/src/tests/ReactiveUI.Tests/ReflectionTest.cs b/src/tests/ReactiveUI.Tests/ReflectionTest.cs index a7612d7073..88e75a724f 100644 --- a/src/tests/ReactiveUI.Tests/ReflectionTest.cs +++ b/src/tests/ReactiveUI.Tests/ReflectionTest.cs @@ -21,18 +21,6 @@ public class ReflectionTest /// The replacement text value used to verify reflective setters. private const string NewValueText = "NewValue"; - /// Tests that ExpressionToPropertyNames converts deeply nested property access. - /// A representing the asynchronous operation. - [Test] - public async Task ExpressionToPropertyNames_DeeplyNestedProperty_ReturnsFullPath() - { - Expression> expression = x => x.Child!.IsOnlyOneWord; - - var result = Reflection.ExpressionToPropertyNames(expression.Body); - - await Assert.That(result).IsEqualTo("Child.IsOnlyOneWord"); - } - /// Tests that ExpressionToPropertyNames converts nested property access. /// A representing the asynchronous operation. [Test] @@ -468,8 +456,8 @@ private sealed class TestClassWithEvent [SuppressMessage( "Design", "SST2324:public member on non-public type", - Justification = "the public method mirrors the public TestEvent event for API symmetry in this " + - "reflection-test fixture; the containing test double is an intentionally non-public detail.")] + Justification = "the public method mirrors the public TestEvent event for API symmetry in this " + + "reflection-test fixture; the containing test double is an intentionally non-public detail.")] public void OnTestEvent() => TestEvent?.Invoke(this, EventArgs.Empty); } diff --git a/src/tests/ReactiveUI.Tests/Registration/DependencyResolverRegistrarTests.cs b/src/tests/ReactiveUI.Tests/Registration/DependencyResolverRegistrarTests.cs index 750132cc8a..245472ba41 100644 --- a/src/tests/ReactiveUI.Tests/Registration/DependencyResolverRegistrarTests.cs +++ b/src/tests/ReactiveUI.Tests/Registration/DependencyResolverRegistrarTests.cs @@ -191,8 +191,8 @@ private sealed class TestService; [SuppressMessage( "Design", "SST1452:Type parameter is never used", - Justification = "type parameters are mandated by the implemented interface signatures; the no-op test " + - "double does not reference them.")] + Justification = "type parameters are mandated by the implemented interface signatures; the no-op test " + + "double does not reference them.")] private sealed class MockDependencyResolver : IMutableDependencyResolver, IDisposable { /// Gets the recorded calls to RegisterConstant. @@ -209,13 +209,13 @@ public void Register(Func factory, Type? serviceType, string? contract) RegisterCalls.Add((factory, contract)); /// - public void Register(Func factory, Type? serviceType) => RegisterCalls.Add((factory, null)); + public void Register(Func factory, Type? serviceType) => Register(factory, serviceType, null); /// - public void Register(Func factory) => RegisterCalls.Add((factory, null)); + public void Register(Func factory) => RegisterCalls.Add(((object)factory, null)); /// - public void Register(Func factory, string? contract) => RegisterCalls.Add((factory, contract)); + public void Register(Func factory, string? contract) => RegisterCalls.Add(((object)factory, contract)); /// public void Register() @@ -379,8 +379,8 @@ public IDisposable ServiceRegistrationCallback(string? contract, Action null; /// Gets the registered services for the given type and contract; this stub always returns an empty sequence. @@ -390,8 +390,8 @@ public IDisposable ServiceRegistrationCallback(string? contract, Action GetServices(Type? serviceType, string? contract) => []; /// diff --git a/src/tests/ReactiveUI.Tests/Resolvers/InpcObservableForPropertyTests.cs b/src/tests/ReactiveUI.Tests/Resolvers/InpcObservableForPropertyTests.cs index 70cb0ba1ff..f0b307726a 100644 --- a/src/tests/ReactiveUI.Tests/Resolvers/InpcObservableForPropertyTests.cs +++ b/src/tests/ReactiveUI.Tests/Resolvers/InpcObservableForPropertyTests.cs @@ -49,8 +49,8 @@ public async Task NotificationOnPropertyChanged() var changes = new List>(); - var propertyName = exp.GetMemberInfo()?.Name ?? - throw new InvalidOperationException(PropertyNameNullMessage); + var propertyName = exp.GetMemberInfo()?.Name + ?? throw new InvalidOperationException(PropertyNameNullMessage); _ = ObservableMixins.WhereNotNull(instance.GetNotificationForProperty(testClass, exp, propertyName)).Subscribe(changes.Add); const int ExpectedChangeCount = 2; @@ -80,8 +80,8 @@ public async Task NotificationOnPropertyChanging() var changes = new List>(); - var propertyName = exp.GetMemberInfo()?.Name ?? - throw new InvalidOperationException(PropertyNameNullMessage); + var propertyName = exp.GetMemberInfo()?.Name + ?? throw new InvalidOperationException(PropertyNameNullMessage); _ = ObservableMixins.WhereNotNull(instance.GetNotificationForProperty(testClass, exp, propertyName, true)).Subscribe(changes.Add); const int ExpectedChangeCount = 2; @@ -111,8 +111,8 @@ public async Task NotificationOnWholeObjectChanged() var changes = new List>(); - var propertyName = exp.GetMemberInfo()?.Name ?? - throw new InvalidOperationException(PropertyNameNullMessage); + var propertyName = exp.GetMemberInfo()?.Name + ?? throw new InvalidOperationException(PropertyNameNullMessage); _ = ObservableMixins.WhereNotNull(instance.GetNotificationForProperty(testClass, exp, propertyName)).Subscribe(changes.Add); const int ExpectedChangeCount = 2; @@ -145,8 +145,8 @@ public async Task NotificationOnWholeObjectChanging() var changes = new List>(); - var propertyName = exp.GetMemberInfo()?.Name ?? - throw new InvalidOperationException(PropertyNameNullMessage); + var propertyName = exp.GetMemberInfo()?.Name + ?? throw new InvalidOperationException(PropertyNameNullMessage); _ = ObservableMixins.WhereNotNull(instance.GetNotificationForProperty(testClass, exp, propertyName, true)).Subscribe(changes.Add); const int ExpectedChangeCount = 2; @@ -189,8 +189,8 @@ public async Task ChangingNotificationIgnoresOtherPropertiesAndDisposes() Expression> expr = x => x.Property1; var exp = Reflection.Rewrite(expr.Body); - var propertyName = exp.GetMemberInfo()?.Name ?? - throw new InvalidOperationException(PropertyNameNullMessage); + var propertyName = exp.GetMemberInfo()?.Name + ?? throw new InvalidOperationException(PropertyNameNullMessage); var changes = new List>(); var subscription = instance.GetNotificationForProperty(testClass, exp, propertyName, true).Subscribe(changes.Add); @@ -263,7 +263,7 @@ public void RaiseChanged(string? propertyName) => /// Raises the event. /// The name of the property that changed. private void OnPropertyChanged([CallerMemberName] string? propertyName = null) => - PropertyChanged?.Invoke(this, new(propertyName)); + RaiseChanged(propertyName); } /// A test fixture implementing to drive changing notifications. diff --git a/src/tests/ReactiveUI.Tests/RxAppBuilderTest.cs b/src/tests/ReactiveUI.Tests/RxAppBuilderTest.cs index 345d4206bf..a072e8375f 100644 --- a/src/tests/ReactiveUI.Tests/RxAppBuilderTest.cs +++ b/src/tests/ReactiveUI.Tests/RxAppBuilderTest.cs @@ -74,13 +74,13 @@ private sealed class TestResolver : IMutableDependencyResolver, IReadonlyDepende public IEnumerable GetServices(Type? serviceType) => []; /// - public IEnumerable GetServices(Type? serviceType, string? contract) => []; + public IEnumerable GetServices(Type? serviceType, string? contract) => GetServices(serviceType); /// - public IEnumerable GetServices() => []; + public IEnumerable GetServices() => GetServices(null); /// - public IEnumerable GetServices(string? contract) => []; + public IEnumerable GetServices(string? contract) => (IEnumerable)[]; /// public bool HasRegistration(Type? serviceType) => false; diff --git a/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostExtensionsAotTests.StateLifecycle.cs b/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostExtensionsAotTests.StateLifecycle.cs index 17836e36eb..4ef7bfe24d 100644 --- a/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostExtensionsAotTests.StateLifecycle.cs +++ b/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostExtensionsAotTests.StateLifecycle.cs @@ -87,12 +87,7 @@ public async Task SetupDefaultSuspendResume_Typed_ShouldDisposePersistTokenAfter [Test] public async Task SetupDefaultSuspendResume_Typed_ShouldInvalidateState_CallsDriverInvalidateState() { - using var host = new SuspensionHost - { - IsLaunchingNew = Signal.Silent(), - IsResuming = Signal.Silent(), - ShouldPersistState = Signal.Silent() - }; + using var host = new SuspensionHost { IsLaunchingNew = Signal.Silent(), IsResuming = Signal.Silent(), ShouldPersistState = Signal.Silent() }; var driver = new TestSuspensionDriver(); var invalidateSubject = new Signal(); diff --git a/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostExtensionsAotTests.cs b/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostExtensionsAotTests.cs index 35caac4b9f..e676f49f14 100644 --- a/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostExtensionsAotTests.cs +++ b/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostExtensionsAotTests.cs @@ -344,15 +344,13 @@ public async Task SetupDefaultSuspendResume_Typed_ShouldPersistCreatedState_When var createdState = new TestAppState { Value = CreatedStateValueForLaunchBeforeSetup }; var createNewAppStateCallCount = 0; - using var host = new SuspensionHost + TestAppState CreateNewAppState() { - CreateNewAppStateTyped = () => - { - createNewAppStateCallCount++; - return createdState; - }, - ShouldInvalidateState = Signal.Silent() - }; + createNewAppStateCallCount++; + return createdState; + } + + using var host = new SuspensionHost { CreateNewAppStateTyped = CreateNewAppState, ShouldInvalidateState = Signal.Silent() }; var launchSubject = new Signal(); var resumeSubject = new Signal(); @@ -444,19 +442,20 @@ public IObservable InvalidateState() /// [RequiresUnreferencedCode("Reflection-based serialization")] [RequiresDynamicCode("Reflection-based serialization")] - public IObservable SaveState(TState state) - { - SaveStateCallCount++; - if (state is T typedState) - { - LastSavedState = typedState; - } - - return Signal.Emit(RxVoid.Default, Sequencer.Immediate); - } + public IObservable SaveState(TState state) => SaveStateCore(state); /// public IObservable SaveState(TState state, JsonTypeInfo typeInfo) + { + _ = typeInfo; + return SaveStateCore(state); + } + + /// Records and completes a save request. + /// The state type. + /// The state to save. + /// A completion signal. + private IObservable SaveStateCore(TState state) { SaveStateCallCount++; if (state is T typedState) diff --git a/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostGenericTests.cs b/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostGenericTests.cs index 1d23b15597..e7ac51dc4b 100644 --- a/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostGenericTests.cs +++ b/src/tests/ReactiveUI.Tests/Suspension/SuspensionHostGenericTests.cs @@ -535,9 +535,9 @@ private sealed class OtherAppState [SuppressMessage( "Design", "SST2324:'Name' is declared 'public' but its containing type is only reachable as 'private'", - Justification = "OtherAppState exists only to be a type distinct from DummyAppState for mismatch " + - "testing; Name keeps the type from being empty (see SST1436) and its public accessor mirrors " + - "DummyAppState.Value's shape.")] + Justification = "OtherAppState exists only to be a type distinct from DummyAppState for mismatch " + + "testing; Name keeps the type from being empty (see SST1436) and its public accessor mirrors " + + "DummyAppState.Value's shape.")] public string? Name { get; set; } } } diff --git a/src/tests/ReactiveUI.Tests/SuspensionHostExtensionsTests.cs b/src/tests/ReactiveUI.Tests/SuspensionHostExtensionsTests.cs index e6431b4dda..d580551b94 100644 --- a/src/tests/ReactiveUI.Tests/SuspensionHostExtensionsTests.cs +++ b/src/tests/ReactiveUI.Tests/SuspensionHostExtensionsTests.cs @@ -270,16 +270,6 @@ public async Task ObserveAppStateDoesNotThrowException() await Assert.That(() => fixture.ObserveAppState().Subscribe()).ThrowsNothing(); } - /// Verifies that observing AppState does not throw . - /// A representing the asynchronous operation. - [Test] - public async Task ObserveAppStateDoesNotThrowInvalidCastException() - { - var fixture = new SuspensionHost(); - - await Assert.That(() => fixture.ObserveAppState().Subscribe()).ThrowsNothing(); - } - /// Verifies that ObserveAppState emits values when AppState changes. /// A representing the asynchronous operation. [Test] @@ -336,7 +326,7 @@ public async Task SetupDefaultSuspendResume_IsResumingOrIsLaunchingNew_TriggersS { CreateNewAppState = static () => new DummyAppState(), ShouldPersistState = Signal.Silent(), - ShouldInvalidateState = Signal.Silent() + ShouldInvalidateState = Signal.Silent(), }; var driver = new TestSuspensionDriver(); @@ -358,12 +348,7 @@ public async Task SetupDefaultSuspendResume_IsResumingOrIsLaunchingNew_TriggersS [Test] public async Task SetupDefaultSuspendResume_ShouldInvalidateState_CallsDriverInvalidateState() { - using var host = new SuspensionHost - { - IsLaunchingNew = Signal.Silent(), - IsResuming = Signal.Silent(), - ShouldPersistState = Signal.Silent() - }; + using var host = new SuspensionHost { IsLaunchingNew = Signal.Silent(), IsResuming = Signal.Silent(), ShouldPersistState = Signal.Silent() }; var driver = new TestSuspensionDriver(); var invalidateSubject = new Signal(); @@ -382,13 +367,7 @@ public async Task SetupDefaultSuspendResume_ShouldInvalidateState_CallsDriverInv public async Task SetupDefaultSuspendResume_ShouldPersistState_CallsDriverSaveState() { var appState = new DummyAppState(); - using var host = new SuspensionHost - { - AppState = appState, - IsLaunchingNew = Signal.Silent(), - IsResuming = Signal.Silent(), - ShouldInvalidateState = Signal.Silent() - }; + using var host = new SuspensionHost { AppState = appState, IsLaunchingNew = Signal.Silent(), IsResuming = Signal.Silent(), ShouldInvalidateState = Signal.Silent() }; var driver = new TestSuspensionDriver(); var persistSubject = new Signal(); @@ -524,15 +503,20 @@ public IObservable InvalidateState() "Implementations commonly use reflection-based serialization. Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] [RequiresDynamicCode( "Implementations commonly use reflection-based serialization. Prefer SaveState(T, JsonTypeInfo) for trimming or AOT scenarios.")] - public IObservable SaveState(T state) - { - SaveStateCallCount++; - LastSavedState = state; - return Signal.Emit(RxVoid.Default, Sequencer.Immediate); - } + public IObservable SaveState(T state) => SaveStateCore(state); /// public IObservable SaveState(T state, JsonTypeInfo typeInfo) + { + _ = typeInfo; + return SaveStateCore(state); + } + + /// Records and completes a save request. + /// The state type. + /// The state to save. + /// A completion signal. + private IObservable SaveStateCore(T state) { SaveStateCallCount++; LastSavedState = state; diff --git a/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.ObservableForProperty.cs b/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.ObservableForProperty.cs index f847b2a4be..cfe14e9615 100644 --- a/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.ObservableForProperty.cs +++ b/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.ObservableForProperty.cs @@ -535,46 +535,6 @@ public async Task OfpSimpleChildPropertyTest() } } - /// Simple property observation test. - /// A representing the asynchronous operation. - [Test] - [TestExecutor] - public async Task OfpSimplePropertyTest() - { - var fixture = new TestFixture(); - - var changes = fixture.ObservableForProperty(x => x.IsOnlyOneWord).Collect(); - - fixture.IsOnlyOneWord = FooText; - - // ImmediateScheduler executes synchronously - await Assert.That(changes).Count().IsEqualTo(1); - - fixture.IsOnlyOneWord = BarText; - - // ImmediateScheduler executes synchronously - await Assert.That(changes).Count().IsEqualTo(ExpectedCountAfterSecondChange); - - fixture.IsOnlyOneWord = BazText; - - // ImmediateScheduler executes synchronously - await Assert.That(changes).Count().IsEqualTo(ExpectedCountAfterThirdChange); - - fixture.IsOnlyOneWord = BazText; - - // ImmediateScheduler executes synchronously - await Assert.That(changes).Count().IsEqualTo(ExpectedCountAfterThirdChange); - - using (Assert.Multiple()) - { - await Assert.That(changes.All(x => x.Sender == fixture)).IsTrue(); - - await Assert.That(changes.All(static x => x.GetPropertyName() == IsOnlyOneWordName)).IsTrue(); - - await Assert.That(changes.Select(static x => x.Value!)).IsEquivalentTo([FooText, BarText, BazText]); - } - } - /// Tests SubscribeToExpressionChain basic functionality. /// A representing the asynchronous operation. [Test] diff --git a/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.WhenAnyValue.cs b/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.WhenAnyValue.cs index 172a95322b..7747f2ce80 100644 --- a/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.WhenAnyValue.cs +++ b/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.WhenAnyValue.cs @@ -67,8 +67,8 @@ public async Task WhenAnyValueWith11ParamertersReturnsValues() var (value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11) = tuple; - return value1 + value2 + value3 + value4 + value5 + value6 + value7 + value8 + value9 + value10 + - value11; + return value1 + value2 + value3 + value4 + value5 + value6 + value7 + value8 + value9 + value10 + + value11; }).Subscribe(value => result = value); await Assert.That(result).IsEqualTo("1357911"); @@ -102,8 +102,8 @@ public async Task WhenAnyValueWith12ParamertersReturnsValues() var (value1, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11, value12) = tuple; - return value1 + value2 + value3 + value4 + value5 + value6 + value7 + value8 + value9 + value10 + - value11 + value12; + return value1 + value2 + value3 + value4 + value5 + value6 + value7 + value8 + value9 + value10 + + value11 + value12; }).Subscribe(value => result = value); await Assert.That(result).IsEqualTo("1357911"); diff --git a/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.cs b/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.cs index e98a808db4..61670a2d65 100644 --- a/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.cs +++ b/src/tests/ReactiveUI.Tests/WhenAny/ReactiveNotifyPropertyChangedMixinTest.cs @@ -249,8 +249,8 @@ public async Task MultiPropertyExpressionsShouldBeProperlyResolved() foreach (var x in results) { var names = x.output.Select(static y => - y.GetMemberInfo()?.Name ?? - throw new InvalidOperationException("propertyName should not be null.")).ToArray(); + y.GetMemberInfo()?.Name + ?? throw new InvalidOperationException("propertyName should not be null.")).ToArray(); await Assert.That(names).IsEquivalentTo(data[x.input], CollectionOrdering.Matching); } diff --git a/src/tests/ReactiveUI.WinForms.Tests/winforms/ActivationTests.cs b/src/tests/ReactiveUI.WinForms.Tests/winforms/ActivationTests.cs index a033262b12..7c39cfa7c5 100644 --- a/src/tests/ReactiveUI.WinForms.Tests/winforms/ActivationTests.cs +++ b/src/tests/ReactiveUI.WinForms.Tests/winforms/ActivationTests.cs @@ -146,10 +146,7 @@ public async Task SmokeTestUserControl() [Test] public async Task ActivationIsSkippedInDesignMode() { - using var control = new DesignModeTestControl - { - Site = new DesignModeSite(), - }; + using var control = new DesignModeTestControl { Site = new DesignModeSite() }; _ = control.Handle; diff --git a/src/tests/ReactiveUI.WinForms.Tests/winforms/ContentControlBindingHookTests.cs b/src/tests/ReactiveUI.WinForms.Tests/winforms/ContentControlBindingHookTests.cs index fbeb9c2995..43d95b8168 100644 --- a/src/tests/ReactiveUI.WinForms.Tests/winforms/ContentControlBindingHookTests.cs +++ b/src/tests/ReactiveUI.WinForms.Tests/winforms/ContentControlBindingHookTests.cs @@ -107,27 +107,4 @@ public async Task ExecuteHook_Returns_True_When_ViewProperties_Is_Empty() await Assert.That(result).IsTrue(); } - - /// Tests that ExecuteHook returns true when the sender is a panel and the property is Controls. - /// A representing the asynchronous operation. - [Test] - public async Task ExecuteHook_Returns_True_When_Sender_Is_Panel_And_Property_Is_Controls() - { - var hook = new ContentControlBindingHook(); - var panel = new Panel(); - Expression> expr = x => x.Controls; - var viewProperties = new IObservedChange[] - { - new ObservedChange(panel, expr.Body, panel.Controls) - }; - - var result = hook.ExecuteHook( - null, - new(), - static () => [], - () => viewProperties, - BindingDirection.OneWay); - - await Assert.That(result).IsTrue(); - } } diff --git a/src/tests/ReactiveUI.WinForms.Tests/winforms/Mocks/FakeViewLocator.cs b/src/tests/ReactiveUI.WinForms.Tests/winforms/Mocks/FakeViewLocator.cs index de9125624b..4398b1f359 100644 --- a/src/tests/ReactiveUI.WinForms.Tests/winforms/Mocks/FakeViewLocator.cs +++ b/src/tests/ReactiveUI.WinForms.Tests/winforms/Mocks/FakeViewLocator.cs @@ -27,8 +27,8 @@ internal sealed class FakeViewLocator : IViewLocator [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public IViewFor? ResolveView(object? instance, string? contract) { if (instance is null) @@ -49,7 +49,7 @@ internal sealed class FakeViewLocator : IViewLocator [RequiresUnreferencedCode( "This method uses reflection to determine the view model type at runtime, which may be incompatible with trimming.")] [RequiresDynamicCode( - "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + - "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] + "If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, " + + "or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public IViewFor? ResolveView(object? instance) => ResolveView(instance, null); } diff --git a/src/tests/ReactiveUI.WinForms.Tests/winforms/ReactiveUserControlTest.cs b/src/tests/ReactiveUI.WinForms.Tests/winforms/ReactiveUserControlTest.cs index 14026987f9..53c5465912 100644 --- a/src/tests/ReactiveUI.WinForms.Tests/winforms/ReactiveUserControlTest.cs +++ b/src/tests/ReactiveUI.WinForms.Tests/winforms/ReactiveUserControlTest.cs @@ -54,10 +54,7 @@ public async Task IViewForViewModel_CanBeSetAndRetrieved() [Test] public async Task ViewModel_CanBeSetToNull() { - var control = new ReactiveUserControl - { - ViewModel = new(), - }; + var control = new ReactiveUserControl { ViewModel = new() }; control.ViewModel = null; await Assert.That(control.ViewModel).IsNull(); diff --git a/src/tests/ReactiveUI.WinForms.Tests/winforms/WinFormsRoutedViewHostTests.cs b/src/tests/ReactiveUI.WinForms.Tests/winforms/WinFormsRoutedViewHostTests.cs index 046b6d6606..2c563b04c5 100644 --- a/src/tests/ReactiveUI.WinForms.Tests/winforms/WinFormsRoutedViewHostTests.cs +++ b/src/tests/ReactiveUI.WinForms.Tests/winforms/WinFormsRoutedViewHostTests.cs @@ -46,12 +46,7 @@ public async Task ShouldSetDefaultContentWhenViewModelIsNull() var defaultContent = new Control(); var viewLocator = new FakeViewLocator { LocatorFunc = static _ => new FakeWinformsView() }; var router = new RoutingState(Sequencer.Immediate); - var target = new WinFormsRoutedViewHost - { - Router = router, - ViewLocator = viewLocator, - DefaultContent = defaultContent - }; + var target = new WinFormsRoutedViewHost { Router = router, ViewLocator = viewLocator, DefaultContent = defaultContent }; await Assert.That(target.Controls.Contains(defaultContent)).IsTrue(); } @@ -76,12 +71,7 @@ public async Task ShouldResolveViewWithViewContractObservable() { var viewLocator = new FakeViewLocator { LocatorFunc = static _ => new FakeWinformsView() }; var router = new RoutingState(Sequencer.Immediate); - var target = new WinFormsRoutedViewHost - { - Router = router, - ViewLocator = viewLocator, - ViewContractObservable = Signal.Emit("MyContract") - }; + var target = new WinFormsRoutedViewHost { Router = router, ViewLocator = viewLocator, ViewContractObservable = Signal.Emit("MyContract") }; _ = router.Navigate.Execute(new FakeWinformViewModel()).Subscribe(); await Assert.That(target.Controls.OfType().Count()).IsEqualTo(1); @@ -138,12 +128,7 @@ public async Task NavigatingBackToEmptyStack_RestoresDefaultContent() var defaultContent = new Control(); var viewLocator = new FakeViewLocator { LocatorFunc = static _ => new FakeWinformsView() }; var router = new RoutingState(Sequencer.Immediate); - using var target = new WinFormsRoutedViewHost - { - Router = router, - ViewLocator = viewLocator, - DefaultContent = defaultContent, - }; + using var target = new WinFormsRoutedViewHost { Router = router, ViewLocator = viewLocator, DefaultContent = defaultContent }; _ = router.Navigate.Execute(new FakeWinformViewModel()).Subscribe(); diff --git a/src/tests/ReactiveUI.WinForms.Tests/winforms/WinFormsViewModelViewHostTests.cs b/src/tests/ReactiveUI.WinForms.Tests/winforms/WinFormsViewModelViewHostTests.cs index 617e53a2bc..27d8bf647e 100644 --- a/src/tests/ReactiveUI.WinForms.Tests/winforms/WinFormsViewModelViewHostTests.cs +++ b/src/tests/ReactiveUI.WinForms.Tests/winforms/WinFormsViewModelViewHostTests.cs @@ -32,12 +32,7 @@ public class WinFormsViewModelViewHostTests public async Task SettingViewModelShouldAddTheViewtoItsControls() { var viewLocator = new FakeViewLocator { LocatorFunc = static _ => new FakeWinformsView() }; - var target = new WinFormsViewModelViewHost - { - ViewLocator = viewLocator, - - ViewModel = new FakeWinformViewModel() - }; + var target = new WinFormsViewModelViewHost { ViewLocator = viewLocator, ViewModel = new FakeWinformViewModel() }; using (Assert.Multiple()) { @@ -52,13 +47,7 @@ public async Task SettingViewModelShouldAddTheViewtoItsControls() public async Task ShouldDisposePreviousView() { var viewLocator = new FakeViewLocator { LocatorFunc = static _ => new FakeWinformsView() }; - var target = new WinFormsViewModelViewHost - { - CacheViews = false, - ViewLocator = viewLocator, - - ViewModel = new FakeWinformViewModel() - }; + var target = new WinFormsViewModelViewHost { CacheViews = false, ViewLocator = viewLocator, ViewModel = new FakeWinformViewModel() }; var currentView = target.CurrentView; var isDisposed = false; @@ -93,13 +82,7 @@ public async Task ShouldCacheViewWhenEnabled() { var viewLocator = new FakeViewLocator { LocatorFunc = static _ => new FakeWinformsView() }; var defaultContent = new Control(); - var target = new WinFormsViewModelViewHost - { - DefaultContent = defaultContent, - ViewLocator = viewLocator, - CacheViews = true, - ViewModel = new FakeWinformViewModel() - }; + var target = new WinFormsViewModelViewHost { DefaultContent = defaultContent, ViewLocator = viewLocator, CacheViews = true, ViewModel = new FakeWinformViewModel() }; var cachedView = target.Content; target.ViewModel = new FakeWinformViewModel(); await Assert.That(ReferenceEquals(cachedView, target.Content)).IsTrue(); @@ -112,13 +95,7 @@ public async Task ShouldNotCacheViewWhenDisabled() { var viewLocator = new FakeViewLocator { LocatorFunc = static _ => new FakeWinformsView() }; var defaultContent = new Control(); - var target = new WinFormsViewModelViewHost - { - DefaultContent = defaultContent, - ViewLocator = viewLocator, - CacheViews = false, - ViewModel = new FakeWinformViewModel() - }; + var target = new WinFormsViewModelViewHost { DefaultContent = defaultContent, ViewLocator = viewLocator, CacheViews = false, ViewModel = new FakeWinformViewModel() }; var cachedView = target.CurrentView; target.ViewModel = new FakeWinformViewModel(); await Assert.That(ReferenceEquals(cachedView, target.CurrentView)).IsFalse(); @@ -155,11 +132,7 @@ public async Task SettingProperty_RaisesPropertyChangingAndChanged() public async Task Dispose_TearsDownCleanly() { var viewLocator = new FakeViewLocator { LocatorFunc = static _ => new FakeWinformsView() }; - var target = new WinFormsViewModelViewHost - { - ViewLocator = viewLocator, - ViewModel = new FakeWinformViewModel(), - }; + var target = new WinFormsViewModelViewHost { ViewLocator = viewLocator, ViewModel = new FakeWinformViewModel() }; target.Dispose(); @@ -173,11 +146,7 @@ public async Task NullViewModelWithDefaultContent_ShowsDefaultContent() { var viewLocator = new FakeViewLocator { LocatorFunc = static _ => new FakeWinformsView() }; var defaultContent = new Control(); - using var target = new WinFormsViewModelViewHost - { - ViewLocator = viewLocator, - DefaultContent = defaultContent, - }; + using var target = new WinFormsViewModelViewHost { ViewLocator = viewLocator, DefaultContent = defaultContent }; // ViewModel stays null, so the view-model/contract combine resolves to the default content. target.ViewModel = new FakeWinformViewModel(); @@ -192,12 +161,7 @@ public async Task NullViewModelWithDefaultContent_ShowsDefaultContent() public async Task UnresolvableViewModel_LeavesContentUnchanged() { var viewLocator = new FakeViewLocator { LocatorFunc = static _ => null! }; - using var target = new WinFormsViewModelViewHost - { - CacheViews = false, - ViewLocator = viewLocator, - ViewModel = new FakeWinformViewModel(), - }; + using var target = new WinFormsViewModelViewHost { CacheViews = false, ViewLocator = viewLocator, ViewModel = new FakeWinformViewModel() }; await Assert.That(target.CurrentView).IsNull(); } diff --git a/src/tests/ReactiveUI.Wpf.Tests/Wpf/AutoSuspendHelperTest.cs b/src/tests/ReactiveUI.Wpf.Tests/Wpf/AutoSuspendHelperTest.cs index 4285c4a43c..89952109b3 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Wpf/AutoSuspendHelperTest.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Wpf/AutoSuspendHelperTest.cs @@ -45,10 +45,7 @@ public async Task IdleTimeout_CanBeSetAndRetrieved() _ = new Application(); } - var helper = new AutoSuspendHelper(Application.Current!) - { - IdleTimeout = TimeSpan.FromSeconds(CustomIdleTimeoutSeconds) - }; + var helper = new AutoSuspendHelper(Application.Current!) { IdleTimeout = TimeSpan.FromSeconds(CustomIdleTimeoutSeconds) }; await Assert.That(helper.IdleTimeout).IsEqualTo(TimeSpan.FromSeconds(CustomIdleTimeoutSeconds)); } diff --git a/src/tests/ReactiveUI.Wpf.Tests/Wpf/FollowObservableStateBehaviorTests.cs b/src/tests/ReactiveUI.Wpf.Tests/Wpf/FollowObservableStateBehaviorTests.cs index cf2497452c..8eb4384f6d 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Wpf/FollowObservableStateBehaviorTests.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Wpf/FollowObservableStateBehaviorTests.cs @@ -33,10 +33,7 @@ public class FollowObservableStateBehaviorTests public async Task StateObservable_WhenChanged_TransitionsVisualState() { var button = new Button(); - var behavior = new FollowObservableStateBehavior - { - SchedulerOverride = Sequencer.Immediate - }; + var behavior = new FollowObservableStateBehavior { SchedulerOverride = Sequencer.Immediate }; var stateSubject = new Signal(); // Attach behavior to button @@ -108,10 +105,7 @@ public void OnStateObservableChanged_NullNewValue_ThrowsArgumentNullException() public async Task StateObservable_WhenChangedMultipleTimes_DisposesOldSubscription() { var button = new Button(); - var behavior = new FollowObservableStateBehavior - { - SchedulerOverride = Sequencer.Immediate - }; + var behavior = new FollowObservableStateBehavior { SchedulerOverride = Sequencer.Immediate }; var behaviors = Interaction.GetBehaviors(button); behaviors.Add(behavior); @@ -141,11 +135,7 @@ public async Task AutoResubscribeOnError_WhenTrue_ResubscribesAfterError() { var button = new Button(); var scheduler = new VirtualTimeScheduler(); - var behavior = new FollowObservableStateBehavior - { - AutoResubscribeOnError = true, - SchedulerOverride = scheduler - }; + var behavior = new FollowObservableStateBehavior { AutoResubscribeOnError = true, SchedulerOverride = scheduler }; var behaviors = Interaction.GetBehaviors(button); behaviors.Add(behavior); @@ -178,11 +168,7 @@ public async Task AutoResubscribeOnError_WhenFalse_DoesNotResubscribe() { var button = new Button(); var scheduler = new VirtualTimeScheduler(); - var behavior = new FollowObservableStateBehavior - { - AutoResubscribeOnError = false, - SchedulerOverride = scheduler - }; + var behavior = new FollowObservableStateBehavior { AutoResubscribeOnError = false, SchedulerOverride = scheduler }; var behaviors = Interaction.GetBehaviors(button); behaviors.Add(behavior); @@ -206,10 +192,7 @@ public async Task AutoResubscribeOnError_WhenFalse_DoesNotResubscribe() public async Task OnDetaching_DisposesWatcher() { var button = new Button(); - var behavior = new FollowObservableStateBehavior - { - SchedulerOverride = Sequencer.Immediate - }; + var behavior = new FollowObservableStateBehavior { SchedulerOverride = Sequencer.Immediate }; var behaviors = Interaction.GetBehaviors(button); behaviors.Add(behavior); @@ -231,11 +214,7 @@ public async Task TargetObject_WhenSet_UsedInsteadOfAssociatedObject() { var button = new Button(); var targetButton = new Button(); - var behavior = new FollowObservableStateBehavior - { - TargetObject = targetButton, - SchedulerOverride = Sequencer.Immediate - }; + var behavior = new FollowObservableStateBehavior { TargetObject = targetButton, SchedulerOverride = Sequencer.Immediate }; var behaviors = Interaction.GetBehaviors(button); behaviors.Add(behavior); @@ -255,10 +234,7 @@ public async Task TargetObject_WhenSet_UsedInsteadOfAssociatedObject() public async Task StateObservable_Getter_ReturnsSetValue() { var button = new Button(); - var behavior = new FollowObservableStateBehavior - { - SchedulerOverride = Sequencer.Immediate - }; + var behavior = new FollowObservableStateBehavior { SchedulerOverride = Sequencer.Immediate }; var behaviors = Interaction.GetBehaviors(button); behaviors.Add(behavior); @@ -278,10 +254,7 @@ public async Task TargetObject_Getter_ReturnsSetValue() { var button = new Button(); var targetButton = new Button(); - var behavior = new FollowObservableStateBehavior - { - TargetObject = targetButton - }; + var behavior = new FollowObservableStateBehavior { TargetObject = targetButton }; var behaviors = Interaction.GetBehaviors(button); behaviors.Add(behavior); diff --git a/src/tests/ReactiveUI.Wpf.Tests/Wpf/ObservableTriggerTests.cs b/src/tests/ReactiveUI.Wpf.Tests/Wpf/ObservableTriggerTests.cs index 3fdf9bba75..5ba7a5398e 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Wpf/ObservableTriggerTests.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Wpf/ObservableTriggerTests.cs @@ -42,18 +42,12 @@ public class ObservableTriggerTests public async Task Observable_WhenEmits_InvokesActions() { var button = new Button(); - var trigger = new ObservableTrigger - { - SchedulerOverride = Sequencer.Immediate - }; + var trigger = new ObservableTrigger { SchedulerOverride = Sequencer.Immediate }; var subject = new Signal(); var actionInvoked = false; // Create a test action - var action = new TestAction - { - OnInvoke = _ => actionInvoked = true - }; + var action = new TestAction { OnInvoke = _ => actionInvoked = true }; // Attach trigger to button var triggers = Interaction.GetTriggers(button); @@ -123,10 +117,7 @@ public void OnObservableChanged_NullNewValue_ThrowsArgumentNullException() public async Task Observable_Getter_ReturnsSetValue() { var button = new Button(); - var trigger = new ObservableTrigger - { - SchedulerOverride = Sequencer.Immediate - }; + var trigger = new ObservableTrigger { SchedulerOverride = Sequencer.Immediate }; var triggers = Interaction.GetTriggers(button); triggers.Add(trigger); @@ -145,10 +136,7 @@ public async Task Observable_Getter_ReturnsSetValue() public async Task Observable_WhenChangedMultipleTimes_DisposesOldSubscription() { var button = new Button(); - var trigger = new ObservableTrigger - { - SchedulerOverride = Sequencer.Immediate - }; + var trigger = new ObservableTrigger { SchedulerOverride = Sequencer.Immediate }; var triggers = Interaction.GetTriggers(button); triggers.Add(trigger); @@ -175,11 +163,7 @@ public async Task AutoResubscribeOnError_WhenTrue_ResubscribesAfterError() { var button = new Button(); var scheduler = new VirtualTimeScheduler(); - var trigger = new ObservableTrigger - { - AutoResubscribeOnError = true, - SchedulerOverride = scheduler - }; + var trigger = new ObservableTrigger { AutoResubscribeOnError = true, SchedulerOverride = scheduler }; var triggers = Interaction.GetTriggers(button); triggers.Add(trigger); @@ -212,11 +196,7 @@ public async Task AutoResubscribeOnError_WhenFalse_DoesNotResubscribe() { var button = new Button(); var scheduler = new VirtualTimeScheduler(); - var trigger = new ObservableTrigger - { - AutoResubscribeOnError = false, - SchedulerOverride = scheduler - }; + var trigger = new ObservableTrigger { AutoResubscribeOnError = false, SchedulerOverride = scheduler }; var triggers = Interaction.GetTriggers(button); triggers.Add(trigger); @@ -240,17 +220,11 @@ public async Task AutoResubscribeOnError_WhenFalse_DoesNotResubscribe() public async Task Observable_MultipleEmissions_InvokesActionsMultipleTimes() { var button = new Button(); - var trigger = new ObservableTrigger - { - SchedulerOverride = Sequencer.Immediate - }; + var trigger = new ObservableTrigger { SchedulerOverride = Sequencer.Immediate }; var subject = new Signal(); var invokeCount = 0; - var action = new TestAction - { - OnInvoke = _ => invokeCount++ - }; + var action = new TestAction { OnInvoke = _ => invokeCount++ }; var triggers = Interaction.GetTriggers(button); triggers.Add(trigger); diff --git a/src/tests/ReactiveUI.Wpf.Tests/Wpf/TransitioningContentControlTest.cs b/src/tests/ReactiveUI.Wpf.Tests/Wpf/TransitioningContentControlTest.cs index d48eeb06ba..609a46b511 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Wpf/TransitioningContentControlTest.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Wpf/TransitioningContentControlTest.cs @@ -77,10 +77,7 @@ public class TransitioningContentControlTest [Test] public async Task Transition_SetAndGet_WorksCorrectly() { - var control = new TransitioningContentControl - { - Transition = TransitioningContentControl.TransitionType.Fade - }; + var control = new TransitioningContentControl { Transition = TransitioningContentControl.TransitionType.Fade }; await Assert.That(control.Transition).IsEqualTo(TransitioningContentControl.TransitionType.Fade); @@ -94,10 +91,7 @@ public async Task Transition_SetAndGet_WorksCorrectly() [Test] public async Task Direction_SetAndGet_WorksCorrectly() { - var control = new TransitioningContentControl - { - Direction = TransitioningContentControl.TransitionDirection.Left - }; + var control = new TransitioningContentControl { Direction = TransitioningContentControl.TransitionDirection.Left }; await Assert.That(control.Direction).IsEqualTo(TransitioningContentControl.TransitionDirection.Left); @@ -111,10 +105,7 @@ public async Task Direction_SetAndGet_WorksCorrectly() [Test] public async Task Duration_SetAndGet_WorksCorrectly() { - var control = new TransitioningContentControl - { - Duration = TimeSpan.FromSeconds(HalfSecond) - }; + var control = new TransitioningContentControl { Duration = TimeSpan.FromSeconds(HalfSecond) }; await Assert.That(control.Duration).IsEqualTo(TimeSpan.FromSeconds(HalfSecond)); @@ -257,11 +248,7 @@ public async Task GetDpiScaleForElement_WithOverride_ReturnsOverriddenDpi() [Test] public async Task SetFadeTransitionDefaults_WithValidStoryboard_SetsDuration() { - var control = new TransitioningContentControl - { - Duration = TimeSpan.FromSeconds(HalfSecond), - Transition = TransitioningContentControl.TransitionType.Fade - }; + var control = new TransitioningContentControl { Duration = TimeSpan.FromSeconds(HalfSecond), Transition = TransitioningContentControl.TransitionType.Fade }; var storyboard = new Storyboard(); var animation1 = new DoubleAnimation(); @@ -386,13 +373,7 @@ public async Task SetMoveTransitionDefaults_WithDirection_SetsCorrectValues( public async Task SetBounceTransitionDefaults_WithDirection_SetsCorrectToValue( TransitioningContentControl.TransitionDirection direction) { - var control = new TransitioningContentControl - { - Transition = TransitioningContentControl.TransitionType.Bounce, - Direction = direction, - Width = ControlSize, - Height = ControlSize - }; + var control = new TransitioningContentControl { Transition = TransitioningContentControl.TransitionType.Bounce, Direction = direction, Width = ControlSize, Height = ControlSize }; control.Measure(new(ControlSize, ControlSize)); control.Arrange(new(0, 0, ControlSize, ControlSize)); @@ -504,12 +485,7 @@ public async Task GetRenderTargetBitmapFromUiElement_WithZeroSize_ReturnsDefault [Test] public async Task GetRenderTargetBitmapFromUiElement_WithRenderedElement_CreatesBitmap() { - var button = new Button - { - Width = ButtonWidth, - Height = ButtonHeight, - Content = "Test" - }; + var button = new Button { Width = ButtonWidth, Height = ButtonHeight, Content = "Test" }; button.Measure(new(ButtonWidth, ButtonHeight)); button.Arrange(new(0, 0, ButtonWidth, ButtonHeight)); @@ -590,12 +566,7 @@ public async Task GetTransitionStoryboardByName_WithValidTransition_ReturnsStory public async Task SetTransitionDefaultValues_WithTransitionType_DoesNotThrow( TransitioningContentControl.TransitionType transitionType) { - var control = new TransitioningContentControl - { - Transition = transitionType, - Width = ControlSize, - Height = ControlSize - }; + var control = new TransitioningContentControl { Transition = transitionType, Width = ControlSize, Height = ControlSize }; control.Measure(new(ControlSize, ControlSize)); control.Arrange(new(0, 0, ControlSize, ControlSize)); @@ -611,13 +582,7 @@ public async Task SetTransitionDefaultValues_WithTransitionType_DoesNotThrow( [Test] public async Task OnApplyTemplate_WithoutContainer_ThrowsInvalidOperationException() { - var control = new TransitioningContentControl - { - Template = new(typeof(TransitioningContentControl)) - { - VisualTree = new(typeof(Grid)) { Name = "WrongName" }, - }, - }; + var control = new TransitioningContentControl { Template = new(typeof(TransitioningContentControl)) { VisualTree = new(typeof(Grid)) { Name = "WrongName" } } }; await Assert.That(control.ApplyTemplate) .Throws(); @@ -628,13 +593,7 @@ await Assert.That(control.ApplyTemplate) [Test] public async Task OnApplyTemplate_WithoutContentPresenter_ThrowsInvalidOperationException() { - var control = new TransitioningContentControl - { - Template = new(typeof(TransitioningContentControl)) - { - VisualTree = new(typeof(Grid)) { Name = PartContainerName }, - }, - }; + var control = new TransitioningContentControl { Template = new(typeof(TransitioningContentControl)) { VisualTree = new(typeof(Grid)) { Name = PartContainerName } } }; await Assert.That(control.ApplyTemplate) .Throws(); @@ -675,11 +634,7 @@ public async Task TransitionDirection_Enum_HasExpectedValues() [Test] public async Task CompletingTransition_Set_TriggersSetTransitionDefaultValues() { - var control = new TransitioningContentControl - { - Transition = TransitioningContentControl.TransitionType.Fade, - Duration = TimeSpan.FromSeconds(HalfSecond) - }; + var control = new TransitioningContentControl { Transition = TransitioningContentControl.TransitionType.Fade, Duration = TimeSpan.FromSeconds(HalfSecond) }; var storyboard = new Storyboard(); var animation1 = new DoubleAnimation(); @@ -805,11 +760,7 @@ public async Task PrepareTransitionImages_WithZeroSizeElement_HandlesGracefully( [Test] public async Task SetSlideTransitionDefaults_WithInvalidDirection_Throws() { - var control = new TransitioningContentControl - { - Transition = TransitioningContentControl.TransitionType.Slide, - Direction = TransitioningContentControl.TransitionDirection.Left, - }; + var control = new TransitioningContentControl { Transition = TransitioningContentControl.TransitionType.Slide, Direction = TransitioningContentControl.TransitionDirection.Left }; var storyboard = new Storyboard(); storyboard.Children.Add(new DoubleAnimation()); @@ -827,11 +778,7 @@ public async Task SetSlideTransitionDefaults_WithInvalidDirection_Throws() [Test] public async Task SetMoveTransitionDefaults_WithInvalidDirection_Throws() { - var control = new TransitioningContentControl - { - Transition = TransitioningContentControl.TransitionType.Move, - Direction = TransitioningContentControl.TransitionDirection.Left, - }; + var control = new TransitioningContentControl { Transition = TransitioningContentControl.TransitionType.Move, Direction = TransitioningContentControl.TransitionDirection.Left }; var storyboard = new Storyboard(); storyboard.Children.Add(new DoubleAnimation()); @@ -847,11 +794,7 @@ public async Task SetMoveTransitionDefaults_WithInvalidDirection_Throws() [Test] public async Task SetBounceTransitionDefaults_WithInvalidDirection_Throws() { - var control = new TransitioningContentControl - { - Transition = TransitioningContentControl.TransitionType.Bounce, - Direction = TransitioningContentControl.TransitionDirection.Left, - }; + var control = new TransitioningContentControl { Transition = TransitioningContentControl.TransitionType.Bounce, Direction = TransitioningContentControl.TransitionDirection.Left }; var storyboard = new Storyboard(); storyboard.Children.Add(new DoubleAnimation()); @@ -866,10 +809,7 @@ public async Task SetBounceTransitionDefaults_WithInvalidDirection_Throws() [Test] public async Task SetTransitionDefaultValues_WithInvalidType_Throws() { - var control = new TransitioningContentControl - { - Transition = (TransitioningContentControl.TransitionType)InvalidEnumValue, - }; + var control = new TransitioningContentControl { Transition = (TransitioningContentControl.TransitionType)InvalidEnumValue }; await Assert.That(control.SetTransitionDefaultValues).Throws(); } @@ -879,11 +819,7 @@ public async Task SetTransitionDefaultValues_WithInvalidType_Throws() [Test] public async Task CompletingTransition_SetTwice_DecouplesPreviousTransition() { - var control = new TransitioningContentControl - { - Transition = TransitioningContentControl.TransitionType.Fade, - Duration = TimeSpan.FromSeconds(HalfSecond), - }; + var control = new TransitioningContentControl { Transition = TransitioningContentControl.TransitionType.Fade, Duration = TimeSpan.FromSeconds(HalfSecond) }; var first = new Storyboard(); first.Children.Add(new DoubleAnimation()); @@ -905,11 +841,7 @@ public async Task CompletingTransition_SetTwice_DecouplesPreviousTransition() [Test] public async Task CompletingTransition_SetToNull_Decouples() { - var control = new TransitioningContentControl - { - Transition = TransitioningContentControl.TransitionType.Fade, - Duration = TimeSpan.FromSeconds(HalfSecond), - }; + var control = new TransitioningContentControl { Transition = TransitioningContentControl.TransitionType.Fade, Duration = TimeSpan.FromSeconds(HalfSecond) }; var first = new Storyboard(); first.Children.Add(new DoubleAnimation()); @@ -1010,10 +942,7 @@ public async Task OnContentChanged_WithoutPreviousImageSite_UpdatesContentImmedi [Test] public async Task OnContentChanged_WithoutTemplate_DoesNotThrow() { - var control = new TransitioningContentControl - { - Content = new TextBlock { Text = NewContentText }, - }; + var control = new TransitioningContentControl { Content = new TextBlock { Text = NewContentText } }; await Assert.That(control.CurrentContentPresentationSite).IsNull(); } @@ -1094,12 +1023,7 @@ private static void ChangeContentDrivingTransition(TransitioningContentControl c /// A realized . private static TransitioningContentControl CreateRealizedControl(bool includePreviousImage = true) { - var control = new TransitioningContentControl - { - Width = ControlSize, - Height = ControlSize, - Content = new TextBlock { Text = "initial" }, - }; + var control = new TransitioningContentControl { Width = ControlSize, Height = ControlSize, Content = new TextBlock { Text = "initial" } }; var template = new ControlTemplate(typeof(TransitioningContentControl)); var grid = new FrameworkElementFactory(typeof(Grid)) { Name = PartContainerName }; diff --git a/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfActivationForViewFetcherTest.cs b/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfActivationForViewFetcherTest.cs index df6fd7433e..5cafa01b93 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfActivationForViewFetcherTest.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfActivationForViewFetcherTest.cs @@ -139,10 +139,7 @@ public async Task WpfWhenActivatedOverloadsDelegateToRuntimeActivationFetcher() (Action _) => activationCount++, view)); - view.RaiseEvent(new() - { - RoutedEvent = FrameworkElement.LoadedEvent - }); + view.RaiseEvent(new() { RoutedEvent = FrameworkElement.LoadedEvent }); await Assert.That(activationCount).IsEqualTo(WhenActivatedOverloadCount); disposables.Dispose(); @@ -162,19 +159,13 @@ public async Task FrameworkElementIsActivatedAndDeactivated() var obs = activation.GetActivationForView(uc); var activated = obs.Collect(); - var loaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.LoadedEvent - }; + var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; uc.RaiseEvent(loaded); await _expectedActivated.AssertAreEqual(activated); - var unloaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.UnloadedEvent - }; + var unloaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.UnloadedEvent }; uc.RaiseEvent(unloaded); @@ -186,19 +177,13 @@ public async Task FrameworkElementIsActivatedAndDeactivated() [Test] public async Task IsHitTestVisibleActivatesFrameworkElement() { - var uc = new WpfTestUserControl - { - IsHitTestVisible = false - }; + var uc = new WpfTestUserControl { IsHitTestVisible = false }; var activation = new ActivationForViewFetcher(); var obs = activation.GetActivationForView(uc); var activated = obs.Collect(); - var loaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.LoadedEvent - }; + var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; uc.RaiseEvent(loaded); @@ -210,10 +195,7 @@ public async Task IsHitTestVisibleActivatesFrameworkElement() // IsHitTestVisible true, we don't want the event to repeat unnecessarily. await _expectedActivated.AssertAreEqual(activated); - var unloaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.UnloadedEvent - }; + var unloaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.UnloadedEvent }; uc.RaiseEvent(unloaded); @@ -232,10 +214,7 @@ public async Task IsHitTestVisibleDeactivatesFrameworkElement() var obs = activation.GetActivationForView(uc); var activated = obs.Collect(); - var loaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.LoadedEvent - }; + var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; uc.RaiseEvent(loaded); @@ -257,10 +236,7 @@ public async Task FrameworkElementIsActivatedAndDeactivatedWithHitTest() var obs = activation.GetActivationForView(uc); var activated = obs.Collect(); - var loaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.LoadedEvent - }; + var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; uc.RaiseEvent(loaded); @@ -276,10 +252,7 @@ public async Task FrameworkElementIsActivatedAndDeactivatedWithHitTest() await _expectedActivatedDeactivatedActivated.AssertAreEqual(activated); - var unloaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.UnloadedEvent - }; + var unloaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.UnloadedEvent }; uc.RaiseEvent(unloaded); diff --git a/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfActiveContentTests.cs b/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfActiveContentTests.cs index 38e0e72f4a..692a353764 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfActiveContentTests.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfActiveContentTests.cs @@ -86,11 +86,7 @@ public async Task BindListFunctionalTest() public async Task ResolveViewBIfViewBIsRegistered() { var vm = new FakeViewWithContract.MyViewModel(); - var host = new ViewModelViewHost - { - ViewModel = vm, - ViewContract = FakeViewWithContract.ContractB, - }; + var host = new ViewModelViewHost { ViewModel = vm, ViewContract = FakeViewWithContract.ContractB }; // Simulate activation by raising the Loaded event var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; @@ -107,12 +103,7 @@ public async Task ResolveViewBIfViewBIsRegistered() public async Task ResolveView0WithFallback() { var vm = new FakeViewWithContract.MyViewModel(); - var host = new ViewModelViewHost - { - ViewModel = vm, - ViewContract = FakeViewWithContract.ContractB, - ContractFallbackByPass = false, - }; + var host = new ViewModelViewHost { ViewModel = vm, ViewContract = FakeViewWithContract.ContractB, ContractFallbackByPass = false }; // Simulate activation by raising the Loaded event var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; @@ -129,12 +120,7 @@ public async Task ResolveView0WithFallback() public async Task ResolveNoneWithFallbackBypass() { var vm = new FakeViewWithContract.MyViewModel(); - var host = new ViewModelViewHost - { - ContractFallbackByPass = true, - ViewContract = FakeViewWithContract.ContractB, - ViewModel = vm, - }; + var host = new ViewModelViewHost { ContractFallbackByPass = true, ViewContract = FakeViewWithContract.ContractB, ViewModel = vm }; // Simulate activation by raising the Loaded event var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; diff --git a/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfCommandBindingImplementationTests.cs b/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfCommandBindingImplementationTests.cs index 508bef791d..b40b2623ab 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfCommandBindingImplementationTests.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfCommandBindingImplementationTests.cs @@ -31,6 +31,25 @@ public class WpfCommandBindingImplementationTests /// The name of the mouse up routed event used for explicit event wiring. private const string MouseUpEventName = "MouseUp"; + /// The null-input command-binding cases exercised by the parameterized test. + public enum NullBindingCase + { + /// An explicit-event binding with no target. + ExplicitEventNullTarget, + + /// A default-event binding with no target. + DefaultEventNullTarget, + + /// An explicit-event binding with no event name. + NullEventName, + + /// An explicit-event binding with no command. + ExplicitEventNullCommand, + + /// A default-event binding with no command. + DefaultEventNullCommand + } + /// Commands the bind to explicit event wireup. /// A representing the asynchronous operation. [Test] @@ -52,79 +71,47 @@ public async Task CommandBindToExplicitEventWireup() await Assert.That(invokeCount).IsEqualTo(1); } - /// Binds the command to object target is null. + /// Verifies command binding handles null targets, event names, and commands according to its contract. + /// The null-input case to exercise. /// A representing the asynchronous operation. [Test] - public async Task BindCommandToObjectWithEventTargetIsNull() + [Arguments(NullBindingCase.ExplicitEventNullTarget)] + [Arguments(NullBindingCase.DefaultEventNullTarget)] + [Arguments(NullBindingCase.NullEventName)] + [Arguments(NullBindingCase.ExplicitEventNullCommand)] + [Arguments(NullBindingCase.DefaultEventNullCommand)] + public async Task BindCommandToObject_NullInput_HandlesAsDocumented(NullBindingCase bindingCase) { - var vm = new CommandBindingViewModel(); - _ = new CommandBindingView { ViewModel = vm }; - - var invokeCount = 0; - _ = vm.Command2.Subscribe(_ => invokeCount++); + var command = ReactiveCommand.Create(static () => { }, outputScheduler: Sequencer.Immediate); + var target = new System.Windows.Controls.Button(); + var parameter = Signal.Emit(null); - // Test that binding with null target throws - await Assert.That(invokeCount).IsEqualTo(0); - } - - /// Binds the command to object target is null. - /// A representing the asynchronous operation. - [Test] - public async Task BindCommandToObjectTargetIsNull() - { - var vm = new CommandBindingViewModel(); - _ = new CommandBindingView { ViewModel = vm }; - - var invokeCount = 0; - _ = vm.Command2.Subscribe(_ => invokeCount++); - - // Test that binding with null target throws when target is required - await Assert.That(invokeCount).IsEqualTo(0); - } - - /// Binds the command to object target is null. - /// A representing the asynchronous operation. - [Test] - public async Task BindCommandToObjectEventIsNull() - { - var vm = new CommandBindingViewModel(); - _ = new CommandBindingView { ViewModel = vm }; - - var invokeCount = 0; - _ = vm.Command2.Subscribe(_ => invokeCount++); - - // Test that binding with non-existent event name throws - await Assert.That(invokeCount).IsEqualTo(0); - } - - /// Binds the command to object command is null. - /// A representing the asynchronous operation. - [Test] - public async Task BindCommandToObjectWithEventCommandIsArgumentNull() - { - var vm = new CommandBindingViewModel(); - _ = new CommandBindingView { ViewModel = vm }; - - var invokeCount = 0; - _ = vm.Command2.Subscribe(_ => invokeCount++); - - // Test that binding with null command throws appropriate exception - await Assert.That(invokeCount).IsEqualTo(0); - } - - /// Binds the command to object command is null. - /// A representing the asynchronous operation. - [Test] - public async Task BindCommandToObjectCommandIsArgumentNull() - { - var vm = new CommandBindingViewModel(); - _ = new CommandBindingView { ViewModel = vm }; - - var invokeCount = 0; - _ = vm.Command2.Subscribe(_ => invokeCount++); + IDisposable Bind() => bindingCase switch + { + NullBindingCase.ExplicitEventNullTarget => CreatesCommandBinding.BindCommandToObject( + command, + null, + parameter, + nameof(System.Windows.Controls.Button.Click)), + NullBindingCase.DefaultEventNullTarget => CreatesCommandBinding.BindCommandToObject(command, null, parameter), + NullBindingCase.NullEventName => CreatesCommandBinding.BindCommandToObject(command, target, parameter, null!), + NullBindingCase.ExplicitEventNullCommand => CreatesCommandBinding.BindCommandToObject( + null, + target, + parameter, + nameof(System.Windows.Controls.Button.Click)), + NullBindingCase.DefaultEventNullCommand => CreatesCommandBinding.BindCommandToObject(null, target, parameter), + _ => throw new ArgumentOutOfRangeException(nameof(bindingCase), bindingCase, null) + }; + + if (bindingCase is NullBindingCase.ExplicitEventNullTarget or NullBindingCase.DefaultEventNullTarget or NullBindingCase.NullEventName) + { + _ = Assert.Throws(() => Bind()); + return; + } - // Test that binding with null command throws exception - await Assert.That(invokeCount).IsEqualTo(0); + using var binding = Bind(); + await Assert.That(binding).IsNotNull(); } /// Commands the bind view model to view with observable. @@ -227,9 +214,9 @@ public async Task BindCommandShouldNotWarnWhenBindingToFieldDeclaredInXaml() var view = new FakeXamlCommandBindingView { ViewModel = vm }; await Assert.That(testLogger.Messages.Exists(t => - t.message.Contains(nameof(POCOObservableForProperty), StringComparison.Ordinal) && - t.message.Contains(view.NameOfButtonDeclaredInXaml, StringComparison.Ordinal) && - t.logLevel == LogLevel.Warn)).IsFalse(); + t.message.Contains(nameof(POCOObservableForProperty), StringComparison.Ordinal) + && t.message.Contains(view.NameOfButtonDeclaredInXaml, StringComparison.Ordinal) + && t.logLevel == LogLevel.Warn)).IsFalse(); } /// Verifies that an overwritten view model is garbage collected after a command binding. diff --git a/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfPropertyBinderImplementationTests.cs b/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfPropertyBinderImplementationTests.cs index b2f60bef2c..66833d3935 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfPropertyBinderImplementationTests.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Wpf/WpfPropertyBinderImplementationTests.cs @@ -96,10 +96,7 @@ public ForeignDispatcher() Dispatcher = Dispatcher.CurrentDispatcher; ready.Set(); Dispatcher.Run(); - }) - { - IsBackground = true, - }; + }) { IsBackground = true }; thread.SetApartmentState(ApartmentState.STA); thread.Start(); _ = ready.Wait(DispatcherStartTimeoutMs); diff --git a/src/tests/ReactiveUI.Wpf.Tests/Xaml/CommandBindingImplementationTests.cs b/src/tests/ReactiveUI.Wpf.Tests/Xaml/CommandBindingImplementationTests.cs index f1c5f3fd97..1cf18c0fff 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Xaml/CommandBindingImplementationTests.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Xaml/CommandBindingImplementationTests.cs @@ -49,10 +49,7 @@ public async Task CommandBindByNameWireup() [Test] public async Task CommandBindNestedCommandWireup() { - var vm = new CommandBindViewModel - { - NestedViewModel = new() - }; + var vm = new CommandBindViewModel { NestedViewModel = new() }; var view = new CommandBindView { ViewModel = vm }; @@ -157,10 +154,7 @@ public async Task CommandBindWithParameterExpression() [Test] public async Task CommandBindWithDelaySetVmParameterExpression() { - var view = new ReactiveObjectCommandBindView - { - ViewModel = new() - }; + var view = new ReactiveObjectCommandBindView { ViewModel = new() }; var received = 0; view.ViewModel.Command1 = ReactiveCommand.Create(i => received = i); diff --git a/src/tests/ReactiveUI.Wpf.Tests/Xaml/RoutedViewHostTests.cs b/src/tests/ReactiveUI.Wpf.Tests/Xaml/RoutedViewHostTests.cs index f5312dd612..09898318b8 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Xaml/RoutedViewHostTests.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Xaml/RoutedViewHostTests.cs @@ -30,19 +30,13 @@ public class RoutedViewHostTests [Test] public async Task RoutedViewHostDefaultContentNotNull() { - var uc = new RoutedViewHost - { - DefaultContent = new System.Windows.Controls.Label() - }; + var uc = new RoutedViewHost { DefaultContent = new System.Windows.Controls.Label() }; var activation = new ActivationForViewFetcher(); var controlActivated = activation.GetActivationForView(uc).Collect(); // Simulate activation by raising the Loaded event - var loaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.LoadedEvent - }; + var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; uc.RaiseEvent(loaded); await _expectedActivated.AssertAreEqual(controlActivated); @@ -59,20 +53,13 @@ public async Task RoutedViewHostDefaultContentNotNullWithViewModelAndActivated() var router = new RoutingState(Sequencer.Immediate); var viewModel = new TestViewModel(); - var uc = new RoutedViewHost - { - DefaultContent = new System.Windows.Controls.Label(), - Router = router - }; + var uc = new RoutedViewHost { DefaultContent = new System.Windows.Controls.Label(), Router = router }; var activation = new ActivationForViewFetcher(); var controlActivated = activation.GetActivationForView(uc).Collect(); // Simulate activation by raising the Loaded event - var loaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.LoadedEvent - }; + var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; uc.RaiseEvent(loaded); await _expectedActivated.AssertAreEqual(controlActivated); @@ -94,11 +81,7 @@ public async Task RoutedViewHostDefaultContentNotNullWithViewModelAndNotActivate var router = new RoutingState(Sequencer.Immediate); var viewModel = new TestViewModel(); - var uc = new RoutedViewHost - { - DefaultContent = new System.Windows.Controls.Label(), - Router = router - }; + var uc = new RoutedViewHost { DefaultContent = new System.Windows.Controls.Label(), Router = router }; var activation = new ActivationForViewFetcher(); var controlActivated = activation.GetActivationForView(uc).Collect(); @@ -107,10 +90,7 @@ public async Task RoutedViewHostDefaultContentNotNullWithViewModelAndNotActivate _ = router.Navigate.Execute(viewModel).Subscribe(); // Activate by raising the Loaded event - var loaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.LoadedEvent - }; + var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; uc.RaiseEvent(loaded); await _expectedActivated.AssertAreEqual(controlActivated); diff --git a/src/tests/ReactiveUI.Wpf.Tests/Xaml/RoutingStateTests.cs b/src/tests/ReactiveUI.Wpf.Tests/Xaml/RoutingStateTests.cs index 01518b91de..ead0bc044c 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Xaml/RoutingStateTests.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Xaml/RoutingStateTests.cs @@ -155,10 +155,7 @@ public async Task CurrentViewModelObservableIsAccurateViaWhenAnyObservable() [Test] public async Task NavigateAndResetCheckNavigationStack() { - var fixture = new TestScreen - { - Router = new(Sequencer.Immediate) - }; + var fixture = new TestScreen { Router = new(Sequencer.Immediate) }; var viewModel = new TestViewModel(); await Assert.That(fixture.Router.NavigationStack).Count().IsLessThanOrEqualTo(0); diff --git a/src/tests/ReactiveUI.Wpf.Tests/Xaml/ViewModelViewHostTests.cs b/src/tests/ReactiveUI.Wpf.Tests/Xaml/ViewModelViewHostTests.cs index 80f90cbbae..377aa8e525 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Xaml/ViewModelViewHostTests.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Xaml/ViewModelViewHostTests.cs @@ -30,19 +30,13 @@ public class ViewModelViewHostTests [Test] public async Task ViewModelViewHostDefaultContentNotNull() { - var uc = new ViewModelViewHost - { - DefaultContent = new System.Windows.Controls.Label() - }; + var uc = new ViewModelViewHost { DefaultContent = new System.Windows.Controls.Label() }; var activation = new ActivationForViewFetcher(); var controlActivated = activation.GetActivationForView(uc).Collect(); // Simulate activation by raising the Loaded event - var loaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.LoadedEvent - }; + var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; uc.RaiseEvent(loaded); await _expectedActivated.AssertAreEqual(controlActivated); @@ -57,20 +51,13 @@ public async Task ViewModelViewHostContentNotNullWithViewModelAndActivated() { var viewModel = new TestViewModel(); - var uc = new ViewModelViewHost - { - DefaultContent = new System.Windows.Controls.Label(), - ViewModel = viewModel - }; + var uc = new ViewModelViewHost { DefaultContent = new System.Windows.Controls.Label(), ViewModel = viewModel }; var activation = new ActivationForViewFetcher(); var controlActivated = activation.GetActivationForView(uc).Collect(); // Simulate activation by raising the Loaded event - var loaded = new RoutedEventArgs - { - RoutedEvent = FrameworkElement.LoadedEvent - }; + var loaded = new RoutedEventArgs { RoutedEvent = FrameworkElement.LoadedEvent }; uc.RaiseEvent(loaded); await _expectedActivated.AssertAreEqual(controlActivated); diff --git a/src/tests/ReactiveUI.Wpf.Tests/Xaml/WhenAnyThroughDependencyObjectTests.cs b/src/tests/ReactiveUI.Wpf.Tests/Xaml/WhenAnyThroughDependencyObjectTests.cs index 7e841717d2..57f5852d97 100644 --- a/src/tests/ReactiveUI.Wpf.Tests/Xaml/WhenAnyThroughDependencyObjectTests.cs +++ b/src/tests/ReactiveUI.Wpf.Tests/Xaml/WhenAnyThroughDependencyObjectTests.cs @@ -27,15 +27,7 @@ public class WhenAnyThroughDependencyObjectTests [Test] public async Task WhenAnyThroughAViewShouldntGiveNullValues() { - var vm = new HostTestFixture - { - Child = new() - { - IsNotNullString = "Foo", - IsOnlyOneWord = "Baz", - PocoProperty = "Bamf" - }, - }; + var vm = new HostTestFixture { Child = new() { IsNotNullString = "Foo", IsOnlyOneWord = "Baz", PocoProperty = "Bamf" } }; var fixture = new HostTestView();