internal static IEnumerable <IMethodSymbol> GetInitializationConstructors(this ISymbolInitializerOperation @this) { INamedTypeSymbol?type = null; Boolean isStatic = false; foreach (ISymbol symbol in @this.GetInitializedMembers()) { type = symbol.ContainingType; isStatic = symbol.IsStatic; if (!(type is null)) { break; } } if (type is null) { return(Enumerable.Empty <IMethodSymbol>()); } else { return(isStatic ? type.StaticConstructors : type.GetInstanceInitializationConstructors()); } }
private void AnalyzeSymbolInitializer(OperationAnalysisContext context) { ISymbolInitializerOperation operation = ((ISymbolInitializerOperation)context.Operation); Compilation compilation = context.Compilation; ISymbol initializedMember = operation.GetInitializedMembers().First(); IEnumerable <ExceptionalOperation> initializerExceptions = operation.GetExceptionalOperations(compilation); if (initializedMember.IsStatic) { foreach (ExceptionalOperation initializerException in initializerExceptions) { context.ReportDiagnostic(Diagnostic.Create( Descriptors.StaticInitializersShouldNotThrowExceptions, initializerException.Location )); } } else { IEnumerable <IMethodSymbol> initializationConstructors = operation.GetInitializationConstructors(); TypeSet documentedExceptionsInAllInitializationConstructors = TypeSet.Universal; foreach (IMethodSymbol constructor in initializationConstructors) { TypeSet documentedExceptions = constructor.GetDocumentedExceptionSet(compilation); documentedExceptionsInAllInitializationConstructors &= documentedExceptions; foreach (ExceptionalOperation exception in initializerExceptions) { ITypeSymbol exceptionType = exception.Type; if (!documentedExceptions.Contains(exceptionType)) { foreach (Location location in constructor.Locations) { context.ReportDiagnostic(Diagnostic.Create( Descriptors.DocumentInstanceMemberInitializerExceptions, location, exceptionType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat), initializedMember.Name )); } } } } // For each exception that isn't documented in all the right places, add an additional diagnostic at the throw/invocation site foreach (ExceptionalOperation exception in initializerExceptions) { Boolean documentedInAllInitializationConstructors = documentedExceptionsInAllInitializationConstructors.Contains(exception.Type); if (!documentedInAllInitializationConstructors) { context.ReportUndocumentedException( descriptorForThrow: Descriptors.DocumentInstanceMemberInitializerThrownExceptions, descriptorForInvocation: Descriptors.DocumentInstanceMemberInitializerCalleeExceptions, exception: exception ); } } } }