Пример #1
0
    private static void AnalyzeMethodBody(OperationAnalysisContext context)
    {
        IMethodBodyBaseOperation operation = ((IMethodBodyBaseOperation)context.Operation);
        Compilation compilation            = context.Compilation;

        TypeSet exceptions = TypeSet.Empty
                             .Add(GetIgnoredExceptions(compilation))
                             .Add(operation.GetDocumentedExceptions());

        context.ReportUndocumentedExceptions(
            descriptorForThrow: Descriptors.DocumentThrownExceptions,
            descriptorForInvocation: Descriptors.DocumentCalleeExceptions,
            documented: exceptions,
            exceptions: operation.GetExceptionalOperations(compilation)
            );
    }
Пример #2
0
    private static void AnalyzeConstructorBody(OperationAnalysisContext context)
    {
        IConstructorBodyOperation operation = ((IConstructorBodyOperation)context.Operation);
        Compilation compilation             = context.Compilation;

        TypeSet exceptions = GetIgnoredExceptionSet(compilation);

        IMethodSymbol symbol = operation.GetSymbol();

        if (symbol.IsStatic)
        {
            foreach (CrefSyntax cref in operation.GetDeclarationSyntax().GetDocumentedExceptions())
            {
                Diagnostic diagnostic = Diagnostic.Create(
                    descriptor: Descriptors.StaticConstructorsShouldNotThrowExceptions,
                    location: cref.Ancestors().OfType <XmlNodeSyntax>().FirstOrDefault()?.GetLocation()
                    );

                context.ReportDiagnostic(diagnostic);
            }

            context.ReportUndocumentedExceptions(
                descriptorForThrow: Descriptors.StaticConstructorsShouldNotThrowExceptions,
                descriptorForInvocation: Descriptors.StaticConstructorsShouldCatchCalleeExceptions,
                documented: exceptions,
                exceptions: operation.GetExceptionalOperations(compilation)
                );
        }
        else
        {
            exceptions = exceptions.Add(operation.GetDocumentedExceptions());

            context.ReportUndocumentedExceptions(
                descriptorForThrow: Descriptors.DocumentThrownExceptions,
                descriptorForInvocation: Descriptors.DocumentCalleeExceptions,
                documented: exceptions,
                exceptions: operation.GetExceptionalOperations(compilation)
                );

            if (operation.Initializer is null)
            {
                //
                // HACK: Implicit/compiler-generated calls to parameterless base-class constructors are
                //       not included in the operation hierarchy and need to be handled explicitly.
                //
                if (
                    (symbol is IMethodSymbol constructor) && !constructor.IsStatic &&
                    (constructor.ContainingType is INamedTypeSymbol type) && (type.TypeKind == TypeKind.Class) &&
                    (type.BaseType is INamedTypeSymbol baseType) &&
                    (baseType.GetParameterlessInstanceConstructor() is IMethodSymbol baseParameterlessConstructor)
                    )
                {
                    Location location = operation.GetDeclarationSyntax().GetIdentifierLocations().First();

                    //
                    // TODO: better diagnostic message which refers to the implicit parameterless constructor call
                    //
                    context.ReportUndocumentedExceptions(
                        descriptorForThrow: Descriptors.DocumentThrownExceptions,
                        descriptorForInvocation: Descriptors.DocumentCalleeExceptions,
                        documented: exceptions,
                        exceptions: baseParameterlessConstructor
                        .GetDocumentedExceptions(compilation)
                        .Select(exception => new ExceptionalOperation(location, baseParameterlessConstructor, exception))
                        );
                }
            }
        }
    }