private void InitializeWorker(CompilationStartAnalysisContext compilationStartAnalysisContext, ApiControllerSymbolCache symbolCache) { compilationStartAnalysisContext.RegisterOperationAction(operationStartContext => { var method = (IMethodSymbol)operationStartContext.ContainingSymbol; if (!ApiControllerFacts.IsApiControllerAction(symbolCache, method)) { return; } var declaredResponseMetadata = SymbolApiResponseMetadataProvider.GetDeclaredResponseMetadata(symbolCache, method); var hasUnreadableStatusCodes = !ActualApiResponseMetadataFactory.TryGetActualResponseMetadata(symbolCache, (IMethodBodyOperation)operationStartContext.Operation, operationStartContext.CancellationToken, out var actualResponseMetadata); var hasUndocumentedStatusCodes = false; foreach (var actualMetadata in actualResponseMetadata) { var location = actualMetadata.ReturnOperation.ReturnedValue.Syntax.GetLocation(); if (!DeclaredApiResponseMetadata.Contains(declaredResponseMetadata, actualMetadata)) { hasUndocumentedStatusCodes = true; if (actualMetadata.IsDefaultResponse) { operationStartContext.ReportDiagnostic(Diagnostic.Create( ApiDiagnosticDescriptors.API1001_ActionReturnsUndocumentedSuccessResult, location)); } else { operationStartContext.ReportDiagnostic(Diagnostic.Create( ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode, location, actualMetadata.StatusCode)); } } } if (hasUndocumentedStatusCodes || hasUnreadableStatusCodes) { // If we produced analyzer warnings about undocumented status codes, don't attempt to determine // if there are documented status codes that are missing from the method body. return; } for (var i = 0; i < declaredResponseMetadata.Count; i++) { var declaredMetadata = declaredResponseMetadata[i]; if (!Contains(actualResponseMetadata, declaredMetadata)) { operationStartContext.ReportDiagnostic(Diagnostic.Create( ApiDiagnosticDescriptors.API1002_ActionDoesNotReturnDocumentedStatusCode, method.Locations[0], declaredMetadata.StatusCode)); } } }, OperationKind.MethodBody); }
private void InitializeWorker(CompilationStartAnalysisContext compilationStartAnalysisContext, ApiControllerSymbolCache symbolCache) { compilationStartAnalysisContext.RegisterSyntaxNodeAction(syntaxNodeContext => { var cancellationToken = syntaxNodeContext.CancellationToken; var methodSyntax = (MethodDeclarationSyntax)syntaxNodeContext.Node; var semanticModel = syntaxNodeContext.SemanticModel; var method = semanticModel.GetDeclaredSymbol(methodSyntax, syntaxNodeContext.CancellationToken); if (!ApiControllerFacts.IsApiControllerAction(symbolCache, method)) { return; } var declaredResponseMetadata = SymbolApiResponseMetadataProvider.GetDeclaredResponseMetadata(symbolCache, method); var hasUnreadableStatusCodes = !ActualApiResponseMetadataFactory.TryGetActualResponseMetadata(symbolCache, semanticModel, methodSyntax, cancellationToken, out var actualResponseMetadata); var hasUndocumentedStatusCodes = false; foreach (var actualMetadata in actualResponseMetadata) { var location = actualMetadata.ReturnStatement.GetLocation(); if (!DeclaredApiResponseMetadata.Contains(declaredResponseMetadata, actualMetadata)) { hasUndocumentedStatusCodes = true; if (actualMetadata.IsDefaultResponse) { syntaxNodeContext.ReportDiagnostic(Diagnostic.Create( ApiDiagnosticDescriptors.API1001_ActionReturnsUndocumentedSuccessResult, location)); } else { syntaxNodeContext.ReportDiagnostic(Diagnostic.Create( ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode, location, actualMetadata.StatusCode)); } } } if (hasUndocumentedStatusCodes || hasUnreadableStatusCodes) { // If we produced analyzer warnings about undocumented status codes, don't attempt to determine // if there are documented status codes that are missing from the method body. return; } for (var i = 0; i < declaredResponseMetadata.Count; i++) { var declaredMetadata = declaredResponseMetadata[i]; if (!Contains(actualResponseMetadata, declaredMetadata)) { syntaxNodeContext.ReportDiagnostic(Diagnostic.Create( ApiDiagnosticDescriptors.API1002_ActionDoesNotReturnDocumentedStatusCode, methodSyntax.Identifier.GetLocation(), declaredMetadata.StatusCode)); } } }, SyntaxKind.MethodDeclaration); }