diff --git a/src/Microsoft.AspNetCore.Mvc.Analyzers/CodeAnalysisExtensions.cs b/src/Microsoft.AspNetCore.Mvc.Analyzers/CodeAnalysisExtensions.cs index c473cc091d..6c191174ab 100644 --- a/src/Microsoft.AspNetCore.Mvc.Analyzers/CodeAnalysisExtensions.cs +++ b/src/Microsoft.AspNetCore.Mvc.Analyzers/CodeAnalysisExtensions.cs @@ -11,6 +11,14 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers { public static bool HasAttribute(this ITypeSymbol typeSymbol, ITypeSymbol attribute, bool inherit) { + Debug.Assert(typeSymbol != null); + Debug.Assert(attribute != null); + + if (!inherit) + { + return HasAttribute(typeSymbol, attribute); + } + foreach (var type in typeSymbol.GetTypeHierarchy()) { if (type.HasAttribute(attribute)) @@ -22,17 +30,47 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers return false; } - public static bool HasAttribute(this ISymbol symbol, ITypeSymbol attribute) + public static bool HasAttribute(this IMethodSymbol methodSymbol, ITypeSymbol attribute, bool inherit) { - Debug.Assert(symbol != null); + Debug.Assert(methodSymbol != null); Debug.Assert(attribute != null); - foreach (var declaredAttribute in symbol.GetAttributes()) + if (!inherit) { - if (declaredAttribute.AttributeClass == attribute) + return HasAttribute(methodSymbol, attribute); + } + + while (methodSymbol != null) + { + if (methodSymbol.HasAttribute(attribute)) { return true; } + + methodSymbol = methodSymbol.IsOverride ? methodSymbol.OverriddenMethod : null; + } + + return false; + } + + public static bool HasAttribute(this IPropertySymbol propertySymbol, ITypeSymbol attribute, bool inherit) + { + Debug.Assert(propertySymbol != null); + Debug.Assert(attribute != null); + + if (!inherit) + { + return HasAttribute(propertySymbol, attribute); + } + + while (propertySymbol != null) + { + if (propertySymbol.HasAttribute(attribute)) + { + return true; + } + + propertySymbol = propertySymbol.IsOverride ? propertySymbol.OverriddenProperty : null; } return false; @@ -67,6 +105,19 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers return false; } + private static bool HasAttribute(this ISymbol symbol, ITypeSymbol attribute) + { + foreach (var declaredAttribute in symbol.GetAttributes()) + { + if (attribute.IsAssignableFrom(declaredAttribute.AttributeClass)) + { + return true; + } + } + + return false; + } + private static IEnumerable GetTypeHierarchy(this ITypeSymbol typeSymbol) { while (typeSymbol != null) diff --git a/src/Microsoft.AspNetCore.Mvc.Analyzers/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.Mvc.Analyzers/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..45468cf21e --- /dev/null +++ b/src/Microsoft.AspNetCore.Mvc.Analyzers/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Analyzers.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/CodeAnalysisExtensionsTest.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/CodeAnalysisExtensionsTest.cs new file mode 100644 index 0000000000..e0e9a90d5c --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/CodeAnalysisExtensionsTest.cs @@ -0,0 +1,243 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Analyzer.Testing; +using Microsoft.AspNetCore.Mvc.Analyzers.Infrastructure; +using Microsoft.CodeAnalysis; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public class CodeAnalysisExtensionsTest + { + [Fact] + public async Task HasAttribute_ReturnsFalseIfSymbolDoesNotHaveAttribute() + { + // Arrange + var compilation = await GetCompilation(); + var attribute = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsFalseIfTypeDoesNotHaveAttribute"); + var testClass = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsFalseIfTypeDoesNotHaveAttributeTest"); + var testMethod = (IMethodSymbol)testClass.GetMembers("SomeMethod").First(); + var testProperty = (IPropertySymbol)testClass.GetMembers("SomeProperty").First(); + + // Act + var classHasAttribute = CodeAnalysisExtensions.HasAttribute(testClass, attribute, inherit: false); + var methodHasAttribute = CodeAnalysisExtensions.HasAttribute(testMethod, attribute, inherit: false); + var propertyHasAttribute = CodeAnalysisExtensions.HasAttribute(testProperty, attribute, inherit: false); + + // AssertControllerAttribute + Assert.False(classHasAttribute); + Assert.False(methodHasAttribute); + Assert.False(propertyHasAttribute); + } + + [Fact] + public async Task HasAttribute_ReturnsTrueIfTypeHasAttribute() + { + // Arrange + var compilation = await GetCompilation(); + var attribute = compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Mvc.ControllerAttribute"); + var testClass = compilation.GetTypeByMetadataName($"{GetType().Namespace}.{nameof(HasAttribute_ReturnsTrueIfTypeHasAttribute)}"); + + // Act + var hasAttribute = CodeAnalysisExtensions.HasAttribute(testClass, attribute, inherit: false); + + // Assert + Assert.True(hasAttribute); + } + + [Fact] + public async Task HasAttribute_ReturnsTrueIfBaseTypeHasAttribute() + { + // Arrange + var compilation = await GetCompilation(); + var attribute = compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Mvc.ControllerAttribute"); + var testClass = compilation.GetTypeByMetadataName($"{GetType().Namespace}.{nameof(HasAttribute_ReturnsTrueIfBaseTypeHasAttribute)}"); + + // Act + var hasAttributeWithoutInherit = CodeAnalysisExtensions.HasAttribute(testClass, attribute, inherit: false); + var hasAttributeWithInherit = CodeAnalysisExtensions.HasAttribute(testClass, attribute, inherit: true); + + // Assert + Assert.False(hasAttributeWithoutInherit); + Assert.True(hasAttributeWithInherit); + } + + [Fact] + public async Task HasAttribute_ReturnsTrueForInterfaceContractOnAttribute() + { + // Arrange + var compilation = await GetCompilation(); + var @interface = compilation.GetTypeByMetadataName($"{GetType().Namespace}.IHasAttribute_ReturnsTrueForInterfaceContractOnAttribute"); + var testClass = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsTrueForInterfaceContractOnAttributeTest"); + var derivedClass = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsTrueForInterfaceContractOnAttributeDerived"); + + // Act + var hasAttribute = CodeAnalysisExtensions.HasAttribute(testClass, @interface, inherit: true); + var hasAttributeOnDerived = CodeAnalysisExtensions.HasAttribute(testClass, @interface, inherit: true); + + // Assert + Assert.True(hasAttribute); + Assert.True(hasAttributeOnDerived); + } + + [Fact] + public async Task HasAttribute_ReturnsTrueForAttributesOnMethods() + { + // Arrange + var compilation = await GetCompilation(); + var attribute = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsTrueForAttributesOnMethodsAttribute"); + var testClass = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsTrueForAttributesOnMethodsTest"); + var method = (IMethodSymbol)testClass.GetMembers("SomeMethod").First(); + + // Act + var hasAttribute = CodeAnalysisExtensions.HasAttribute(method, attribute, inherit: false); + + // Assert + Assert.True(hasAttribute); + } + + [Fact] + public async Task HasAttribute_ReturnsTrueForAttributesOnOverriddenMethods() + { + // Arrange + var compilation = await GetCompilation(); + var attribute = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsTrueForAttributesOnOverriddenMethodsAttribute"); + var testClass = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsTrueForAttributesOnOverriddenMethodsTest"); + var method = (IMethodSymbol)testClass.GetMembers("SomeMethod").First(); + + + // Act + var hasAttributeWithoutInherit = CodeAnalysisExtensions.HasAttribute(method, attribute, inherit: false); + var hasAttributeWithInherit = CodeAnalysisExtensions.HasAttribute(method, attribute, inherit: true); + + // Assert + Assert.False(hasAttributeWithoutInherit); + Assert.True(hasAttributeWithInherit); + } + + [Fact] + public async Task HasAttribute_ReturnsTrueForAttributesOnProperties() + { + // Arrange + var compilation = await GetCompilation(); + var attribute = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsTrueForAttributesOnPropertiesAttribute"); + var testClass = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsTrueForAttributesOnProperties"); + var property = (IPropertySymbol)testClass.GetMembers("SomeProperty").First(); + + // Act + var hasAttribute = CodeAnalysisExtensions.HasAttribute(property, attribute, inherit: false); + + // Assert + Assert.True(hasAttribute); + } + + [Fact] + public async Task HasAttribute_ReturnsTrueForAttributesOnOverridenProperties() + { + // Arrange + var compilation = await GetCompilation(); + var attribute = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsTrueForAttributesOnOverriddenPropertiesAttribute"); + var testClass = compilation.GetTypeByMetadataName($"{GetType().Namespace}.HasAttribute_ReturnsTrueForAttributesOnOverriddenProperties"); + var property = (IPropertySymbol)testClass.GetMembers("SomeProperty").First(); + + // Act + var hasAttributeWithoutInherit = CodeAnalysisExtensions.HasAttribute(property, attribute, inherit: false); + var hasAttributeWithInherit = CodeAnalysisExtensions.HasAttribute(property, attribute, inherit: true); + + // Assert + Assert.False(hasAttributeWithoutInherit); + Assert.True(hasAttributeWithInherit); + } + + [Fact] + public async Task IsAssignable_ReturnsFalseForDifferentTypes() + { + // Arrange + var compilation = await GetCompilation(); + var source = compilation.GetTypeByMetadataName($"{GetType().Namespace}.IsAssignable_ReturnsFalseForDifferentTypesA"); + var target = compilation.GetTypeByMetadataName($"{GetType().Namespace}.IsAssignable_ReturnsFalseForDifferentTypesB"); + + // Act + var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(source, target); + + // Assert + Assert.False(isAssignableFrom); + } + + [Fact] + public async Task IsAssignable_ReturnsFalseIfTypeDoesNotImplementInterface() + { + // Arrange + var compilation = await GetCompilation(nameof(IsAssignable_ReturnsFalseForDifferentTypes)); + var source = compilation.GetTypeByMetadataName($"{GetType().Namespace}.IsAssignable_ReturnsFalseForDifferentTypesA"); + var target = compilation.GetTypeByMetadataName($"System.IDisposable"); + + // Act + var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(source, target); + + // Assert + Assert.False(isAssignableFrom); + } + + [Fact] + public async Task IsAssignable_ReturnsTrueIfTypesAreExact() + { + // Arrange + var compilation = await GetCompilation(); + var source = compilation.GetTypeByMetadataName($"{GetType().Namespace}.IsAssignable_ReturnsTrueIfTypesAreExact"); + var target = compilation.GetTypeByMetadataName($"{GetType().Namespace}.IsAssignable_ReturnsTrueIfTypesAreExact"); + + // Act + var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(source, target); + + // Assert + Assert.True(isAssignableFrom); + } + + [Fact] + public async Task IsAssignable_ReturnsTrueIfTypeImplementsInterface() + { + // Arrange + var compilation = await GetCompilation(); + var source = compilation.GetTypeByMetadataName($"{GetType().Namespace}.IsAssignable_ReturnsTrueIfTypeImplementsInterface"); + var target = compilation.GetTypeByMetadataName($"{GetType().Namespace}.IsAssignable_ReturnsTrueIfTypeImplementsInterfaceTest"); + + // Act + var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(source, target); + var isAssignableFromDerived = CodeAnalysisExtensions.IsAssignableFrom(target, source); + + // Assert + Assert.True(isAssignableFrom); + Assert.False(isAssignableFromDerived); // Inverse shouldn't be true + } + + [Fact] + public async Task IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterface() + { + // Arrange + var compilation = await GetCompilation(); + var source = compilation.GetTypeByMetadataName($"{GetType().Namespace}.IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterface"); + var target = compilation.GetTypeByMetadataName($"{GetType().Namespace}.IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterfaceTest"); + + // Act + var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(source, target); + var isAssignableFromDerived = CodeAnalysisExtensions.IsAssignableFrom(target, source); + + // Assert + Assert.True(isAssignableFrom); + Assert.False(isAssignableFromDerived); // Inverse shouldn't be true + } + + private Task GetCompilation([CallerMemberName] string testMethod = "") + { + var testSource = MvcTestSource.Read(GetType().Name, testMethod); + var project = DiagnosticProject.Create(GetType().Assembly, new[] { testSource.Source }); + + return project.GetCompilationAsync(); + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageHandlerMethod.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageHandlerMethod.cs index 45ef30ce92..c070495950 100644 --- a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageHandlerMethod.cs +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/AttributesShouldNotBeAppliedToPageModelAnalyzerTest/DiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageHandlerMethod.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.RazorPages; -namespace Microsoft.AspNetCore.Mvc.Analyzers.Test +namespace Microsoft.AspNetCore.Mvc.Analyzers { public class DiagnosticsAreReturned_IfAllowAnonymousIsAppliedToPageHandlerMethod : PageModel { diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsFalseIfSymbolDoesNotHaveAttribute.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsFalseIfSymbolDoesNotHaveAttribute.cs new file mode 100644 index 0000000000..db5c15882f --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsFalseIfSymbolDoesNotHaveAttribute.cs @@ -0,0 +1,19 @@ +using System; + +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public class HasAttribute_ReturnsFalseIfTypeDoesNotHaveAttribute : Attribute { } + + [Controller] + public class HasAttribute_ReturnsFalseIfTypeDoesNotHaveAttributeTest + { + [NonAction] + public void SomeMethod() + { + + } + + [BindProperty] + public string SomeProperty { get; set; } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnMethods.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnMethods.cs new file mode 100644 index 0000000000..4dd452410e --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnMethods.cs @@ -0,0 +1,12 @@ +using System; + +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public class HasAttribute_ReturnsTrueForAttributesOnMethodsAttribute : Attribute { } + + public class HasAttribute_ReturnsTrueForAttributesOnMethodsTest + { + [HasAttribute_ReturnsTrueForAttributesOnMethodsAttribute] + public void SomeMethod() { } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnOverriddenMethods.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnOverriddenMethods.cs new file mode 100644 index 0000000000..64ef7b87b9 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnOverriddenMethods.cs @@ -0,0 +1,17 @@ +using System; + +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public class HasAttribute_ReturnsTrueForAttributesOnOverriddenMethodsAttribute : Attribute { } + + public class HasAttribute_ReturnsTrueForAttributesOnOverriddenMethodsBase + { + [HasAttribute_ReturnsTrueForAttributesOnOverriddenMethodsAttribute] + public virtual void SomeMethod() { } + } + + public class HasAttribute_ReturnsTrueForAttributesOnOverriddenMethodsTest : HasAttribute_ReturnsTrueForAttributesOnOverriddenMethodsBase + { + public override void SomeMethod() { } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnOverridenProperties.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnOverridenProperties.cs new file mode 100644 index 0000000000..872f35fbfb --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnOverridenProperties.cs @@ -0,0 +1,17 @@ +using System; + +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public class HasAttribute_ReturnsTrueForAttributesOnOverriddenPropertiesAttribute : Attribute { } + + public class HasAttribute_ReturnsTrueForAttributesOnOverriddenPropertiesBase + { + [HasAttribute_ReturnsTrueForAttributesOnOverriddenPropertiesAttribute] + public virtual string SomeProperty { get; set; } + } + + public class HasAttribute_ReturnsTrueForAttributesOnOverriddenProperties : HasAttribute_ReturnsTrueForAttributesOnOverriddenPropertiesBase + { + public override string SomeProperty { get; set; } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnProperties.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnProperties.cs new file mode 100644 index 0000000000..7b36527ddb --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForAttributesOnProperties.cs @@ -0,0 +1,12 @@ +using System; + +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public class HasAttribute_ReturnsTrueForAttributesOnPropertiesAttribute : Attribute { } + + public class HasAttribute_ReturnsTrueForAttributesOnProperties + { + [HasAttribute_ReturnsTrueForAttributesOnPropertiesAttribute] + public string SomeProperty { get; set; } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForInterfaceContractOnAttribute.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForInterfaceContractOnAttribute.cs new file mode 100644 index 0000000000..25a966df8e --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueForInterfaceContractOnAttribute.cs @@ -0,0 +1,17 @@ +using System; + +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public interface IHasAttribute_ReturnsTrueForInterfaceContractOnAttribute { } + + public class HasAttribute_ReturnsTrueForInterfaceContractOnAttribute : Attribute, IHasAttribute_ReturnsTrueForInterfaceContractOnAttribute { } + + [HasAttribute_ReturnsTrueForInterfaceContractOnAttribute] + public class HasAttribute_ReturnsTrueForInterfaceContractOnAttributeTest + { + } + + public class HasAttribute_ReturnsTrueForInterfaceContractOnAttributeDerived : HasAttribute_ReturnsTrueForInterfaceContractOnAttributeTest + { + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueIfBaseTypeHasAttribute.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueIfBaseTypeHasAttribute.cs new file mode 100644 index 0000000000..39851099c2 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueIfBaseTypeHasAttribute.cs @@ -0,0 +1,7 @@ +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + [Controller] + public class HasAttribute_ReturnsTrueIfBaseTypeHasAttributeBase { } + + public class HasAttribute_ReturnsTrueIfBaseTypeHasAttribute : HasAttribute_ReturnsTrueIfBaseTypeHasAttributeBase { } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueIfTypeHasAttribute.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueIfTypeHasAttribute.cs new file mode 100644 index 0000000000..31c6cf70cc --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/HasAttribute_ReturnsTrueIfTypeHasAttribute.cs @@ -0,0 +1,5 @@ +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + [Controller] + public class HasAttribute_ReturnsTrueIfTypeHasAttribute { } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsFalseForDifferentTypes.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsFalseForDifferentTypes.cs new file mode 100644 index 0000000000..ceef09cde4 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsFalseForDifferentTypes.cs @@ -0,0 +1,10 @@ +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public class IsAssignable_ReturnsFalseForDifferentTypesA + { + } + + public class IsAssignable_ReturnsFalseForDifferentTypesB + { + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterface.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterface.cs new file mode 100644 index 0000000000..60d8aecb48 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterface.cs @@ -0,0 +1,18 @@ +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public interface IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterface + { + } + + public class IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterfaceA : IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterface + { + } + + public class IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterfaceB : IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterfaceA + { + } + + public class IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterfaceTest : IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterfaceB + { + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfTypeImplementsInterface.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfTypeImplementsInterface.cs new file mode 100644 index 0000000000..a60d9fa56d --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfTypeImplementsInterface.cs @@ -0,0 +1,9 @@ +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public interface IsAssignable_ReturnsTrueIfTypeImplementsInterface + { + } + + public class IsAssignable_ReturnsTrueIfTypeImplementsInterfaceTest : IsAssignable_ReturnsTrueIfTypeImplementsInterface { } + +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfTypeIsBaseClass.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfTypeIsBaseClass.cs new file mode 100644 index 0000000000..8ed1087a79 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfTypeIsBaseClass.cs @@ -0,0 +1,10 @@ +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public class IsAssignable_ReturnsTrueIfTypeIsBaseClassBase + { + } + + public class IsAssignable_ReturnsTrueIfTypeIsBaseClass : IsAssignable_ReturnsTrueIfTypeIsBaseClassBase + { + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfTypesAreExact.cs b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfTypesAreExact.cs new file mode 100644 index 0000000000..e47fa67dcc --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Analyzers.Test/TestFiles/CodeAnalysisExtensionsTest/IsAssignable_ReturnsTrueIfTypesAreExact.cs @@ -0,0 +1,6 @@ +namespace Microsoft.AspNetCore.Mvc.Analyzers +{ + public class IsAssignable_ReturnsTrueIfTypesAreExact + { + } +}