in sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs [403:454]
private bool TryGetReturnTypeBindings(IMethodSymbol method, bool hasHttpTrigger, bool hasMethodOutputBinding, out IList<IDictionary<string, object>>? bindingsList)
{
ITypeSymbol? returnTypeSymbol = method.ReturnType;
bindingsList = new List<IDictionary<string, object>>();
if (returnTypeSymbol is null)
{
_context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.SymbolNotFound, Location.None, nameof(returnTypeSymbol)));
bindingsList = null;
return false;
}
if (!SymbolEqualityComparer.Default.Equals(returnTypeSymbol, _knownTypes.VoidType) &&
!SymbolEqualityComparer.Default.Equals(returnTypeSymbol.OriginalDefinition, _knownTypes.TaskType) ||
// For HTTP triggers, include the return binding even if the return type is void or Task.
hasHttpTrigger)
{
// If there is a Task<T> return type, inspect T, the inner type.
if (SymbolEqualityComparer.Default.Equals(returnTypeSymbol.OriginalDefinition, _knownTypes.TaskOfTType))
{
if (returnTypeSymbol is INamedTypeSymbol namedTypeSymbol)
{
if (namedTypeSymbol.IsGenericType)
{
returnTypeSymbol = namedTypeSymbol.TypeArguments.FirstOrDefault();// Generic task should only have one type argument
}
}
if (returnTypeSymbol is null) // need this check here b/c return type symbol takes on a new value from the inner argument type above
{
_context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.SymbolNotFound, Location.None, nameof(returnTypeSymbol)));
bindingsList = null;
return false;
}
}
if (SymbolEqualityComparer.Default.Equals(returnTypeSymbol, _knownFunctionMetadataTypes.HttpResponseData))
{
bindingsList.Add(GetHttpReturnBinding(Constants.FunctionMetadataBindingProps.ReturnBindingName));
}
else
{
if (!TryGetReturnTypePropertyBindings(returnTypeSymbol, hasHttpTrigger, hasMethodOutputBinding, out bindingsList))
{
bindingsList = null;
return false;
}
}
}
return true;
}