public static bool IsApiControllerAction(ApiControllerSymbolCache symbolCache, IMethodSymbol method) { if (method == null) { return(false); } if (method.ReturnsVoid || method.ReturnType.TypeKind == TypeKind.Error) { return(false); } if (!MvcFacts.IsController(method.ContainingType, symbolCache.ControllerAttribute, symbolCache.NonControllerAttribute)) { return(false); } if (!method.ContainingType.HasAttribute(symbolCache.IApiBehaviorMetadata, inherit: true) && !method.ContainingAssembly.HasAttribute(symbolCache.IApiBehaviorMetadata)) { return(false); } if (!MvcFacts.IsControllerAction(method, symbolCache.NonActionAttribute, symbolCache.IDisposableDispose)) { return(false); } return(true); }
private void IsControllerReturnsTrue(Type type) { var compilation = GetIsControllerCompilation(); var typeSymbol = compilation.GetTypeByMetadataName(type.FullName); // Act var isController = MvcFacts.IsController(typeSymbol); // Assert Assert.True(isController); }
private void IsActionReturnsTrue(Type type, string methodName) { var compilation = GetIsControllerActionCompilation(); var disposableDispose = GetDisposableDispose(compilation); var typeSymbol = compilation.GetTypeByMetadataName(type.FullName); var method = (IMethodSymbol)typeSymbol.GetMembers(methodName).First(); // Act var isControllerAction = MvcFacts.IsControllerAction(method, disposableDispose); // Assert Assert.True(isControllerAction); }
public void IsAction_ReturnsTrueForNotDisposableDisposeOnTypeWithImplicitImplementation() { var compilation = GetIsControllerActionCompilation(); var disposableDispose = GetDisposableDispose(compilation); var typeSymbol = compilation.GetTypeByMetadataName(typeof(NotDisposableWithDisposeThatIsNotInterfaceContract).FullName); var method = typeSymbol.GetMembers(nameof(IDisposable.Dispose)).OfType <IMethodSymbol>().First(f => !f.ReturnsVoid); // Act var isControllerAction = MvcFacts.IsControllerAction(method, disposableDispose); // Assert Assert.True(isControllerAction); }
private async Task IsControllerReturnsTrue(Type type) { var compilation = await GetIsControllerCompilation(); var controllerAttribute = compilation.GetTypeByMetadataName(ControllerAttribute); var nonControllerAttribute = compilation.GetTypeByMetadataName(NonControllerAttribute); var typeSymbol = compilation.GetTypeByMetadataName(type.FullName); // Act var isController = MvcFacts.IsController(typeSymbol, controllerAttribute, nonControllerAttribute); // Assert Assert.True(isController); }
private async Task IsActionReturnsFalse(Type type, string methodName) { var compilation = await GetIsControllerActionCompilation(); var nonActionAttribute = compilation.GetTypeByMetadataName(NonActionAttribute); var disposableDispose = GetDisposableDispose(compilation); var typeSymbol = compilation.GetTypeByMetadataName(type.FullName); var method = (IMethodSymbol)typeSymbol.GetMembers(methodName).First(); // Act var isControllerAction = MvcFacts.IsControllerAction(method, nonActionAttribute, disposableDispose); // Assert Assert.False(isControllerAction); }
private void CanBeControllerReturnsTrue(Type type) { var compilation = GetIsControllerCompilation(); var syntaxTree = compilation.GetTypeByMetadataName(type.FullName).DeclaringSyntaxReferences.Single().SyntaxTree; var typeName = type.IsGenericType ? type.Name.Substring(0, type.Name.IndexOf('`')) : type.Name; var typeDeclarationSyntax = syntaxTree.GetRoot().DescendantNodes() .OfType <TypeDeclarationSyntax>() .First(node => node.Identifier.ToString() == typeName); // Act var canBeController = MvcFacts.CanBeController(typeDeclarationSyntax); // Assert Assert.True(canBeController); }
private static void InitializeWorker(CompilationStartAnalysisContext compilationStartAnalysisContext, SymbolCache symbolCache) { compilationStartAnalysisContext.RegisterSymbolAction(symbolAnalysisContext => { var method = (IMethodSymbol)symbolAnalysisContext.Symbol; if (method.MethodKind != MethodKind.Ordinary) { return; } if (method.Parameters.Length == 0) { return; } if (!MvcFacts.IsController(method.ContainingType, symbolCache.ControllerAttribute, symbolCache.NonControllerAttribute) || !MvcFacts.IsControllerAction(method, symbolCache.NonActionAttribute, symbolCache.IDisposableDispose)) { return; } if (method.ContainingType.HasAttribute(symbolCache.IApiBehaviorMetadata, inherit: true)) { // The issue of parameter name collision with properties affects complex model-bound types // and not input formatting. Ignore ApiController instances since they default to formatting. return; } for (var i = 0; i < method.Parameters.Length; i++) { var parameter = method.Parameters[i]; if (IsProblematicParameter(symbolCache, parameter)) { var location = parameter.Locations.Length != 0 ? parameter.Locations[0] : Location.None; symbolAnalysisContext.ReportDiagnostic( Diagnostic.Create( DiagnosticDescriptors.MVC1004_ParameterNameCollidesWithTopLevelProperty, location, parameter.Type.Name, parameter.Name)); } } }, SymbolKind.Method); }