diff --git a/.vscode/settings.json b/.vscode/settings.json index a743130f..ace92905 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,7 @@ { "cSpell.words": [ + "LLMBRO", + "MBRO", "app", "nuget", "nupkg", diff --git a/src/xunit.analyzers.fixes/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckFixer.cs b/src/xunit.analyzers.fixes/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckFixer.cs index 7f6d2b11..8bfa0213 100644 --- a/src/xunit.analyzers.fixes/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckFixer.cs +++ b/src/xunit.analyzers.fixes/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckFixer.cs @@ -111,13 +111,11 @@ private static ArgumentListSyntax GetArguments(InvocationExpressionSyntax invoca { var arguments = invocation.ArgumentList; var argumentSyntax = invocation.ArgumentList.Arguments.Last(); - var lambdaExpression = argumentSyntax.Expression as LambdaExpressionSyntax; - if (lambdaExpression == null) + if (!(argumentSyntax.Expression is LambdaExpressionSyntax lambdaExpression)) return arguments; - var awaitExpression = lambdaExpression.Body as AwaitExpressionSyntax; - if (awaitExpression == null) + if (!(lambdaExpression.Body is AwaitExpressionSyntax awaitExpression)) return arguments; var lambdaExpressionWithoutAsyncKeyword = RemoveAsyncKeywordFromLambdaExpression(lambdaExpression, awaitExpression); @@ -132,12 +130,12 @@ private static ExpressionSyntax RemoveAsyncKeywordFromLambdaExpression(LambdaExp { if (lambdaExpression is SimpleLambdaExpressionSyntax simpleLambdaExpression) return simpleLambdaExpression.ReplaceNode(awaitExpression, awaitExpression.Expression) - .WithAsyncKeyword(default(SyntaxToken)) + .WithAsyncKeyword(default) .WithLeadingTrivia(simpleLambdaExpression.AsyncKeyword.LeadingTrivia); if (lambdaExpression is ParenthesizedLambdaExpressionSyntax parenthesizedLambdaExpression) return parenthesizedLambdaExpression.ReplaceNode(awaitExpression, awaitExpression.Expression) - .WithAsyncKeyword(default(SyntaxToken)) + .WithAsyncKeyword(default) .WithLeadingTrivia(parenthesizedLambdaExpression.AsyncKeyword.LeadingTrivia); return lambdaExpression; diff --git a/src/xunit.analyzers.fixes/CodeActions/Actions.cs b/src/xunit.analyzers.fixes/CodeActions/Actions.cs index 479e1f01..1eb5d21a 100644 --- a/src/xunit.analyzers.fixes/CodeActions/Actions.cs +++ b/src/xunit.analyzers.fixes/CodeActions/Actions.cs @@ -69,8 +69,8 @@ public static async Task SetBaseClass(Document document, ClassDeclarat var semanticModel = await document.GetSemanticModelAsync(cancellationToken); var baseTypeNode = generator.TypeExpression(semanticModel.Compilation.GetTypeByMetadataName(baseType)); var baseTypes = generator.GetBaseAndInterfaceTypes(declaration); - var updatedDeclaration = default(SyntaxNode); + SyntaxNode updatedDeclaration; if (baseTypes?.Count == 0 || semanticModel.GetTypeInfo(baseTypes[0], cancellationToken).Type?.TypeKind != TypeKind.Class) updatedDeclaration = generator.AddBaseType(declaration, baseTypeNode); else diff --git a/src/xunit.analyzers.fixes/FixProviders/UseGenericOverloadFix.cs b/src/xunit.analyzers.fixes/FixProviders/UseGenericOverloadFix.cs index 752075fa..1783c8fb 100644 --- a/src/xunit.analyzers.fixes/FixProviders/UseGenericOverloadFix.cs +++ b/src/xunit.analyzers.fixes/FixProviders/UseGenericOverloadFix.cs @@ -29,12 +29,10 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) var syntaxNode = root.FindNode(context.Span); var invocation = syntaxNode.FirstAncestorOrSelf(); - var typeOfExpression = invocation.ArgumentList.Arguments[0].Expression as TypeOfExpressionSyntax; - if (typeOfExpression == null) + if (!(invocation.ArgumentList.Arguments[0].Expression is TypeOfExpressionSyntax typeOfExpression)) return; - var memberAccess = invocation.Expression as MemberAccessExpressionSyntax; - if (memberAccess == null) + if (!(invocation.Expression is MemberAccessExpressionSyntax memberAccess)) return; var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); diff --git a/src/xunit.analyzers/AssertCollectionContainsShouldNotUseBoolCheck.cs b/src/xunit.analyzers/AssertCollectionContainsShouldNotUseBoolCheck.cs index 9f0896a0..7b052138 100644 --- a/src/xunit.analyzers/AssertCollectionContainsShouldNotUseBoolCheck.cs +++ b/src/xunit.analyzers/AssertCollectionContainsShouldNotUseBoolCheck.cs @@ -32,8 +32,7 @@ protected override void Analyze(SyntaxNodeAnalysisContext context, InvocationExp if (method.Parameters.Length > 1 && method.Parameters[1].Type.SpecialType.Equals(SpecialType.System_String)) return; - var invocationExpression = arguments.First().Expression as InvocationExpressionSyntax; - if (invocationExpression == null) + if (!(arguments.First().Expression is InvocationExpressionSyntax invocationExpression)) return; var symbolInfo = context.SemanticModel.GetSymbolInfo(invocationExpression); diff --git a/src/xunit.analyzers/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheck.cs b/src/xunit.analyzers/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheck.cs index 045081cb..84d1be5b 100644 --- a/src/xunit.analyzers/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheck.cs +++ b/src/xunit.analyzers/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheck.cs @@ -25,8 +25,7 @@ protected override void Analyze(SyntaxNodeAnalysisContext context, InvocationExp if (arguments.Count != 1) return; - var invocationExpression = arguments.First().Expression as InvocationExpressionSyntax; - if (invocationExpression == null) + if (!(arguments.First().Expression is InvocationExpressionSyntax invocationExpression)) return; var symbolInfo = context.SemanticModel.GetSymbolInfo(invocationExpression); diff --git a/src/xunit.analyzers/AssertEqualShouldNotBeUsedForBoolLiteralCheck.cs b/src/xunit.analyzers/AssertEqualShouldNotBeUsedForBoolLiteralCheck.cs index c9b0ac08..1c02f57e 100644 --- a/src/xunit.analyzers/AssertEqualShouldNotBeUsedForBoolLiteralCheck.cs +++ b/src/xunit.analyzers/AssertEqualShouldNotBeUsedForBoolLiteralCheck.cs @@ -31,8 +31,7 @@ protected override void Analyze(SyntaxNodeAnalysisContext context, InvocationExp !method.TypeArguments[0].SpecialType.Equals(SpecialType.System_Boolean)) return; - var literalFirstArgument = arguments.First().Expression as LiteralExpressionSyntax; - if (literalFirstArgument == null) + if (!(arguments.First().Expression is LiteralExpressionSyntax literalFirstArgument)) return; var isTrue = literalFirstArgument.IsKind(SyntaxKind.TrueLiteralExpression); diff --git a/src/xunit.analyzers/AssertIsTypeShouldNotBeUsedForAbstractType.cs b/src/xunit.analyzers/AssertIsTypeShouldNotBeUsedForAbstractType.cs index c036b76d..598ca8e6 100755 --- a/src/xunit.analyzers/AssertIsTypeShouldNotBeUsedForAbstractType.cs +++ b/src/xunit.analyzers/AssertIsTypeShouldNotBeUsedForAbstractType.cs @@ -21,8 +21,7 @@ public AssertIsTypeShouldNotBeUsedForAbstractType() protected override void Analyze(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation, IMethodSymbol method) { - var genericName = invocation.GetSimpleName() as GenericNameSyntax; - if (genericName == null) + if (!(invocation.GetSimpleName() is GenericNameSyntax genericName)) return; var typeSyntax = genericName.TypeArgumentList.Arguments[0]; diff --git a/src/xunit.analyzers/AssertIsTypeShouldUseGenericOverloadType.cs b/src/xunit.analyzers/AssertIsTypeShouldUseGenericOverloadType.cs index 130874a1..899706e2 100644 --- a/src/xunit.analyzers/AssertIsTypeShouldUseGenericOverloadType.cs +++ b/src/xunit.analyzers/AssertIsTypeShouldUseGenericOverloadType.cs @@ -24,8 +24,7 @@ protected override void Analyze(SyntaxNodeAnalysisContext context, InvocationExp if (arguments.Count != 2) return; - var typeOfExpression = arguments[0].Expression as TypeOfExpressionSyntax; - if (typeOfExpression == null) + if (!(arguments[0].Expression is TypeOfExpressionSyntax typeOfExpression)) return; var typeInfo = context.SemanticModel.GetTypeInfo(typeOfExpression.Type); diff --git a/src/xunit.analyzers/AssertRegexMatchShouldNotUseBoolLiteralCheck.cs b/src/xunit.analyzers/AssertRegexMatchShouldNotUseBoolLiteralCheck.cs index 61750ef1..02e7c572 100644 --- a/src/xunit.analyzers/AssertRegexMatchShouldNotUseBoolLiteralCheck.cs +++ b/src/xunit.analyzers/AssertRegexMatchShouldNotUseBoolLiteralCheck.cs @@ -29,8 +29,7 @@ protected override void Analyze(SyntaxNodeAnalysisContext context, InvocationExp if (arguments.Count != 1) return; - var invocationExpression = arguments.First().Expression as InvocationExpressionSyntax; - if (invocationExpression == null) + if (!(arguments.First().Expression is InvocationExpressionSyntax invocationExpression)) return; var symbolInfo = context.SemanticModel.GetSymbolInfo(invocationExpression); diff --git a/src/xunit.analyzers/AssertStringEqualityCheckShouldNotUseBoolCheck.cs b/src/xunit.analyzers/AssertStringEqualityCheckShouldNotUseBoolCheck.cs index e70aea2e..a8743f31 100644 --- a/src/xunit.analyzers/AssertStringEqualityCheckShouldNotUseBoolCheck.cs +++ b/src/xunit.analyzers/AssertStringEqualityCheckShouldNotUseBoolCheck.cs @@ -41,8 +41,7 @@ protected override void Analyze(SyntaxNodeAnalysisContext context, InvocationExp if (arguments.Count != 1) return; - var invocationExpression = arguments.First().Expression as InvocationExpressionSyntax; - if (invocationExpression == null) + if (!(arguments.First().Expression is InvocationExpressionSyntax invocationExpression)) return; var symbolInfo = context.SemanticModel.GetSymbolInfo(invocationExpression); diff --git a/src/xunit.analyzers/AssertSubstringCheckShouldNotUseBoolCheck.cs b/src/xunit.analyzers/AssertSubstringCheckShouldNotUseBoolCheck.cs index 3d4567a6..31272d63 100644 --- a/src/xunit.analyzers/AssertSubstringCheckShouldNotUseBoolCheck.cs +++ b/src/xunit.analyzers/AssertSubstringCheckShouldNotUseBoolCheck.cs @@ -33,8 +33,7 @@ protected override void Analyze(SyntaxNodeAnalysisContext context, InvocationExp if (arguments.Count != 1) return; - var invocationExpression = arguments.First().Expression as InvocationExpressionSyntax; - if (invocationExpression == null) + if (!(arguments.First().Expression is InvocationExpressionSyntax invocationExpression)) return; var symbolInfo = context.SemanticModel.GetSymbolInfo(invocationExpression); diff --git a/src/xunit.analyzers/AssertThrowsShouldNotBeUsedForAsyncThrowsCheck.cs b/src/xunit.analyzers/AssertThrowsShouldNotBeUsedForAsyncThrowsCheck.cs index 97d1abf3..0cae9e25 100644 --- a/src/xunit.analyzers/AssertThrowsShouldNotBeUsedForAsyncThrowsCheck.cs +++ b/src/xunit.analyzers/AssertThrowsShouldNotBeUsedForAsyncThrowsCheck.cs @@ -50,13 +50,11 @@ protected override void Analyze(SyntaxNodeAnalysisContext context, InvocationExp private static SymbolInfo GetThrowExpressionSymbol(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation) { var argumentExpression = invocation.ArgumentList.Arguments.Last().Expression; - var lambdaExpression = argumentExpression as LambdaExpressionSyntax; - if (lambdaExpression == null) + if (!(argumentExpression is LambdaExpressionSyntax lambdaExpression)) return context.SemanticModel.GetSymbolInfo(argumentExpression); - var awaitExpression = lambdaExpression.Body as AwaitExpressionSyntax; - if (awaitExpression == null) + if (!(lambdaExpression.Body is AwaitExpressionSyntax awaitExpression)) return context.SemanticModel.GetSymbolInfo(lambdaExpression.Body); return context.SemanticModel.GetSymbolInfo(awaitExpression.Expression); diff --git a/src/xunit.analyzers/AssertThrowsShouldUseGenericOverloadCheck.cs b/src/xunit.analyzers/AssertThrowsShouldUseGenericOverloadCheck.cs index ac9dc1de..6080a759 100644 --- a/src/xunit.analyzers/AssertThrowsShouldUseGenericOverloadCheck.cs +++ b/src/xunit.analyzers/AssertThrowsShouldUseGenericOverloadCheck.cs @@ -22,8 +22,7 @@ protected override void Analyze(SyntaxNodeAnalysisContext context, InvocationExp if (arguments.Count != 2) return; - var typeOfExpression = arguments[0].Expression as TypeOfExpressionSyntax; - if (typeOfExpression == null) + if (!(arguments[0].Expression is TypeOfExpressionSyntax typeOfExpression)) return; var typeInfo = context.SemanticModel.GetTypeInfo(typeOfExpression.Type); diff --git a/src/xunit.analyzers/ClassDataAttributeMustPointAtValidClass.cs b/src/xunit.analyzers/ClassDataAttributeMustPointAtValidClass.cs index cf09be1c..5a0081ac 100644 --- a/src/xunit.analyzers/ClassDataAttributeMustPointAtValidClass.cs +++ b/src/xunit.analyzers/ClassDataAttributeMustPointAtValidClass.cs @@ -25,8 +25,7 @@ internal override void AnalyzeCompilation(CompilationStartAnalysisContext compil if (!Equals(semanticModel.GetTypeInfo(attribute).Type, xunitContext.Core.ClassDataAttributeType)) return; - var argumentExpression = attribute.ArgumentList?.Arguments.FirstOrDefault()?.Expression as TypeOfExpressionSyntax; - if (argumentExpression == null) + if (!(attribute.ArgumentList?.Arguments.FirstOrDefault()?.Expression is TypeOfExpressionSyntax argumentExpression)) return; var classType = (INamedTypeSymbol)semanticModel.GetTypeInfo(argumentExpression.Type).Type; diff --git a/src/xunit.analyzers/InlineDataShouldBeUniqueWithinTheory.cs b/src/xunit.analyzers/InlineDataShouldBeUniqueWithinTheory.cs index 97cd974f..b1cbcb87 100644 --- a/src/xunit.analyzers/InlineDataShouldBeUniqueWithinTheory.cs +++ b/src/xunit.analyzers/InlineDataShouldBeUniqueWithinTheory.cs @@ -145,17 +145,11 @@ private bool AreArgumentsEqual(ImmutableArray xArguments, ImmutableArray break; case TypedConstant xArgArray when xArgArray.Kind == TypedConstantKind.Array && !xArgArray.IsNull: - switch (y) + return y switch { - case TypedConstant yArgArray when yArgArray.Kind == TypedConstantKind.Array: - return AreArgumentsEqual( - xArgArray.Values.Cast().ToImmutableArray(), - yArgArray.Values.Cast().ToImmutableArray()); - - default: - return false; - } - + TypedConstant yArgArray when yArgArray.Kind == TypedConstantKind.Array => AreArgumentsEqual(xArgArray.Values.Cast().ToImmutableArray(), yArgArray.Values.Cast().ToImmutableArray()), + _ => false, + }; default: return false; } @@ -174,16 +168,12 @@ private static bool IsSingleNullByInlineDataOrByDefaultParamValue(ImmutableArray if (args.Length != 1) return false; - switch (args[0]) + return (args[0]) switch { - case TypedConstant xSingleNull when xSingleNull.Kind == TypedConstantKind.Array && xSingleNull.IsNull: - return true; - - case IParameterSymbol xParamDefaultNull when xParamDefaultNull.ExplicitDefaultValue == null: - return true; - } - - return false; + TypedConstant xSingleNull when xSingleNull.Kind == TypedConstantKind.Array && xSingleNull.IsNull => true, + IParameterSymbol xParamDefaultNull when xParamDefaultNull.ExplicitDefaultValue == null => true, + _ => false, + }; } /// diff --git a/src/xunit.analyzers/MemberDataShouldReferenceValidMember.cs b/src/xunit.analyzers/MemberDataShouldReferenceValidMember.cs index b70a7400..977ad154 100644 --- a/src/xunit.analyzers/MemberDataShouldReferenceValidMember.cs +++ b/src/xunit.analyzers/MemberDataShouldReferenceValidMember.cs @@ -45,8 +45,7 @@ compilation is CSharpCompilation cSharpCompilation return; var constantValue = semanticModel.GetConstantValue(memberNameArgument.Expression, symbolContext.CancellationToken); - var memberName = constantValue.Value as string; - if (memberName == null) + if (!(constantValue.Value is string memberName)) return; var memberTypeArgument = attribute.ArgumentList.Arguments.FirstOrDefault(a => a.NameEquals?.Name.Identifier.ValueText == "MemberType"); @@ -162,13 +161,13 @@ compilation is CSharpCompilation cSharpCompilation static ITypeSymbol GetMemberType(ISymbol memberSymbol) { - switch (memberSymbol) + return memberSymbol switch { - case IPropertySymbol prop: return prop.Type; - case IFieldSymbol field: return field.Type; - case IMethodSymbol method: return method.ReturnType; - default: return null; - } + IPropertySymbol prop => prop.Type, + IFieldSymbol field => field.Type, + IMethodSymbol method => method.ReturnType, + _ => null, + }; } static ISymbol FindMemberSymbol(string memberName, ITypeSymbol type) diff --git a/src/xunit.analyzers/SyntaxExtensions.cs b/src/xunit.analyzers/SyntaxExtensions.cs index de1da609..0ddcd324 100644 --- a/src/xunit.analyzers/SyntaxExtensions.cs +++ b/src/xunit.analyzers/SyntaxExtensions.cs @@ -24,16 +24,12 @@ internal static bool ContainsAttributeType(this SyntaxList internal static SimpleNameSyntax GetSimpleName(this InvocationExpressionSyntax invocation) { - switch (invocation.Expression) + return invocation.Expression switch { - case MemberAccessExpressionSyntax memberAccess: - return memberAccess.Name; - - case SimpleNameSyntax simpleName: - return simpleName; - } - - return null; + MemberAccessExpressionSyntax memberAccess => memberAccess.Name, + SimpleNameSyntax simpleName => simpleName, + _ => null, + }; } internal static bool IsEnumValueExpression(this ExpressionSyntax expression, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) diff --git a/test/xunit.analyzers.tests/FactMethodShouldNotHaveTestDataTests.cs b/test/xunit.analyzers.tests/FactMethodShouldNotHaveTestDataTests.cs index d6fca5b0..776aec73 100644 --- a/test/xunit.analyzers.tests/FactMethodShouldNotHaveTestDataTests.cs +++ b/test/xunit.analyzers.tests/FactMethodShouldNotHaveTestDataTests.cs @@ -18,7 +18,7 @@ public async void DoesNotFindErrorForFactMethodWithNoDataAttributes() [InlineData("ClassData(typeof(string))")] public async void DoesNotFindErrorForTheoryMethodWithDataAttributes(string dataAttribute) { - var source = "public class TestClass { [Xunit.Theory, Xunit." + dataAttribute + "] public void TestMethod() { } }"; + var source = "public class TestClass { [Xunit.Theory, Xunit." + dataAttribute + "] public void TestMethod() { } }"; await Verify.VerifyAnalyzerAsync(source); } @@ -48,7 +48,7 @@ public async void DoesNotFindErrorForDerivedFactMethodWithDataAttributes(string [InlineData("ClassData(typeof(string))")] public async void FindsErrorForFactMethodsWithDataAttributes(string dataAttribute) { - var source = "public class TestClass { [Xunit.Fact, Xunit." + dataAttribute + "] public void TestMethod() { } }"; + var source = "public class TestClass { [Xunit.Fact, Xunit." + dataAttribute + "] public void TestMethod() { } }"; var expected = Verify.Diagnostic().WithSpan(1, 59 + dataAttribute.Length, 1, 69 + dataAttribute.Length); await Verify.VerifyAnalyzerAsync(source, expected); diff --git a/test/xunit.analyzers.tests/InlineDataShouldBeUniqueWithinTheoryTests.cs b/test/xunit.analyzers.tests/InlineDataShouldBeUniqueWithinTheoryTests.cs index 3a168ec3..75c92a49 100644 --- a/test/xunit.analyzers.tests/InlineDataShouldBeUniqueWithinTheoryTests.cs +++ b/test/xunit.analyzers.tests/InlineDataShouldBeUniqueWithinTheoryTests.cs @@ -12,7 +12,7 @@ public class ForNonRelatedToInlineDataMethod : InlineDataShouldBeUniqueWithinThe [Fact] public async void DoesNotFindError_WhenNoDataAttributes() { - var source = "public class TestClass { [Xunit.Fact] public void TestMethod() { } }"; + var source = "public class TestClass { [Xunit.Fact] public void TestMethod() { } }"; await Verify.VerifyAnalyzerAsync(source); } diff --git a/test/xunit.analyzers.tests/MemberDataShouldReferenceValidMemberTests.cs b/test/xunit.analyzers.tests/MemberDataShouldReferenceValidMemberTests.cs index fc09ce77..371684b2 100644 --- a/test/xunit.analyzers.tests/MemberDataShouldReferenceValidMemberTests.cs +++ b/test/xunit.analyzers.tests/MemberDataShouldReferenceValidMemberTests.cs @@ -14,7 +14,7 @@ public class OtherClass { public static System.Collections.Generic.IEnumerable), typeof(Tuple<,>), typeof(Tuple<,,>), typeof(Tuple<,,,>), typeof(Tuple<,,,,>), typeof(Tuple<,,,,,>), typeof(Tuple<,,,,,,>), }; + private static readonly Type[] TupleOpenGenericTypes = + { + typeof(Tuple<>), + typeof(Tuple<,>), + typeof(Tuple<,,>), + typeof(Tuple<,,,>), + typeof(Tuple<,,,,>), + typeof(Tuple<,,,,,>), + typeof(Tuple<,,,,,,>), + }; + private static readonly ConcurrentDictionary> ConverterCache = new ConcurrentDictionary>(); public TupleMemberDataAttribute(string memberName, params object[] parameters)