private static IEnumerable <GenerateTheoryProperty> FindGenerateTheoryProperties( GeneratorExecutionContext context, IPropertySymbol propertySymbol, INamedTypeSymbol containingType) { var descendants = propertySymbol.DescendantsAndSelf(x => x.OverriddenProperty).ToList(); var attributes = descendants.SelectMany( d => d.GetAttributes() .Where( a => a.HasName(GenerateTheoryAttribute) || a.HasName(GenerateAsyncTheoryAttribute) ) ); foreach (var attributeData in attributes) { Debug.Assert( attributeData.AttributeClass != null, "attributeData.AttributeClass != null" ); var isAsync = attributeData.HasName(GenerateAsyncTheoryAttribute); var expectedInstanceSymbol = isAsync ? IAsyncTestInstance : ITestInstance; var allInterfaces = propertySymbol.Type.DescendantsAndSelf(x => x.AllInterfaces) .Distinct(SymbolEqualityComparer.Default) .OfType <INamedTypeSymbol>() .ToList(); var testInstanceName = allInterfaces .Where( i => i.IsGenericType && i.ConstructUnboundGenericType().Name.Equals("IEnumerable") && i.TypeArguments.Length == 1 && i.TypeArguments.Single() .DescendantsAndSelf(x => x.AllInterfaces) .Any(x => x.Name.Equals(expectedInstanceSymbol)) ) .Select(x => x.TypeArguments.Single().Name) .FirstOrDefault(); if (testInstanceName == null) { const string messageCode = "TG001"; var message = $"Properties implementing {attributeData.AttributeClass.Name} should return IEnumerable<{expectedInstanceSymbol}>"; context.ReportDiagnostic( Diagnostic.Create( new DiagnosticDescriptor( messageCode, message, message, "Testing", DiagnosticSeverity.Error, true ), propertySymbol.Locations.FirstOrDefault() ) ); } else { yield return(new GenerateTheoryProperty( propertySymbol, attributeData, isAsync, testInstanceName, containingType )); } } }