in sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs [456:535]
private bool TryGetReturnTypePropertyBindings(ITypeSymbol returnTypeSymbol, bool hasHttpTrigger, bool hasMethodOutputBinding, out IList<IDictionary<string, object>>? bindingsList)
{
var members = returnTypeSymbol.GetMembers();
var foundHttpOutput = false;
var returnTypeHasOutputBindings = false;
bindingsList = new List<IDictionary<string, object>>(); // initialize this without size, because it will be difficult to predict how many bindings we can find here in the user code.
foreach (var prop in returnTypeSymbol.GetMembers().Where(a => a is IPropertySymbol))
{
if (prop is null)
{
_context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.SymbolNotFound, Location.None, nameof(prop)));
bindingsList = null;
return false;
}
// Check for HttpResponseData type for legacy apps
if (prop is IPropertySymbol property
&& (SymbolEqualityComparer.Default.Equals(property.Type, _knownFunctionMetadataTypes.HttpResponseData)))
{
if (foundHttpOutput)
{
_context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.MultipleHttpResponseTypes, Location.None, new object[] { returnTypeSymbol.Name }));
bindingsList = null;
return false;
}
foundHttpOutput = true;
bindingsList.Add(GetHttpReturnBinding(prop.Name));
continue;
}
var propAttributes = prop.GetAttributes();
if (propAttributes.Length > 0)
{
var bindingAttributes = propAttributes.Where(p => p.AttributeClass!.IsOrDerivedFrom(_knownFunctionMetadataTypes.BindingAttribute));
if (bindingAttributes.Count() > 1)
{
_context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.MultipleBindingsGroupedTogether, Location.None, new object[] { "Property", prop.Name.ToString() }));
bindingsList = null;
return false;
}
// Check if this property has an HttpResultAttribute on it
if (HasHttpResultAttribute(prop))
{
if (foundHttpOutput)
{
_context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.MultipleHttpResponseTypes, Location.None, new object[] { returnTypeSymbol.Name }));
bindingsList = null;
return false;
}
foundHttpOutput = true;
bindingsList.Add(GetHttpReturnBinding(prop.Name));
}
else if (bindingAttributes.Any())
{
if (!TryCreateBindingDictionary(bindingAttributes.FirstOrDefault(), prop.Name, prop.Locations.FirstOrDefault(), out IDictionary<string, object>? bindings))
{
bindingsList = null;
return false;
}
bindingsList.Add(bindings!);
returnTypeHasOutputBindings = true;
}
}
}
if (hasHttpTrigger && !foundHttpOutput && !hasMethodOutputBinding && !returnTypeHasOutputBindings)
{
bindingsList.Add(GetHttpReturnBinding(Constants.FunctionMetadataBindingProps.ReturnBindingName));
}
return true;
}