diff --git a/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs b/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs index b6e47266f..5ba6d02c7 100644 --- a/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs +++ b/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs @@ -626,7 +626,14 @@ private bool TryGetAttributeProperties(AttributeData attributeData, Location? at } else { - attrProperties[namedArgument.Key] = namedArgument.Value.Value; + if (TryParseValueByType(namedArgument.Value, out object? argValue)) + { + attrProperties[namedArgument.Key] = argValue; + } + else + { + // TODO: Log diagnostic error + } } } } @@ -657,14 +664,14 @@ private bool TryGetAttributeProperties(AttributeData attributeData, Location? at return true; } - private bool TryLoadConstructorArguments(AttributeData attributeData, IDictionary dict, Location? attribLocation) + private bool TryLoadConstructorArguments(AttributeData attributeData, IDictionary arguments, Location? attributeLocation) { IMethodSymbol? attribMethodSymbol = attributeData.AttributeConstructor; // Check if the attribute constructor has any parameters if (attribMethodSymbol is null) { - _context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.SymbolNotFound, attribLocation, nameof(attribMethodSymbol))); + _context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.SymbolNotFound, attributeLocation, nameof(attribMethodSymbol))); return false; } @@ -677,44 +684,51 @@ private bool TryLoadConstructorArguments(AttributeData attributeData, IDictionar var arg = attributeData.ConstructorArguments[i]; - switch (arg.Kind) + if (TryParseValueByType(arg, out object? argValue)) { - case TypedConstantKind.Error: - break; + arguments[argumentName] = argValue; + } + else + { + // TODO: Log diagnostic error + } + } - case TypedConstantKind.Primitive: - dict[argumentName] = arg.Value; - break; + return true; + } - case TypedConstantKind.Enum: - var enumValue = arg.Type!.GetMembers() - .FirstOrDefault(m => m is IFieldSymbol field - && field.ConstantValue is object value - && value.Equals(arg.Value)); + private bool TryParseValueByType(TypedConstant attributeArg, out object? argValue) + { + argValue = null; - if (enumValue is null) - { - return false; - } + switch (attributeArg.Kind) + { + case TypedConstantKind.Primitive: + argValue = attributeArg.Value; + break; - // we want just the enumValue symbol's name (Admin, Anonymous, Function) - dict[argumentName] = enumValue.Name; - break; + case TypedConstantKind.Enum: + var enumValue = attributeArg.Type!.GetMembers() + .FirstOrDefault(m => m is IFieldSymbol field + && field.ConstantValue is object value + && value.Equals(attributeArg.Value)); - case TypedConstantKind.Type: - break; + if (enumValue is null) + { + return false; + } - case TypedConstantKind.Array: - var arrayValues = arg.Values.Select(a => a.Value?.ToString()).ToArray(); - dict[argumentName] = arrayValues; - break; + // we want just the enumValue symbol's name (ex: Admin, Anonymous, Function) + argValue = enumValue.Name; + break; - default: - break; - } + case TypedConstantKind.Array: + var arrayValues = attributeArg.Values.Select(a => a.Value?.ToString()).ToArray(); + argValue = arrayValues; + break; } - return true; + return argValue is not null; } /// diff --git a/sdk/release_notes.md b/sdk/release_notes.md index 8b1885c82..5a99a0a84 100644 --- a/sdk/release_notes.md +++ b/sdk/release_notes.md @@ -14,4 +14,4 @@ ### Microsoft.Azure.Functions.Worker.Sdk.Generators -- \ No newline at end of file +- Parse named arguments by type (#1877) \ No newline at end of file diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/StorageBindingTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/StorageBindingTests.cs index 59f37ec6d..14524c18b 100644 --- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/StorageBindingTests.cs +++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/StorageBindingTests.cs @@ -156,7 +156,7 @@ public string QueueToBlob( [Function("BlobToQueueFunction")] [QueueOutput("queue2")] public object BlobToQueue( - [BlobTrigger("container2/%file%")] string blob) + [BlobTrigger("container2/%file%", Source = BlobTriggerSource.EventGrid)] string blob) { throw new NotImplementedException(); } @@ -206,7 +206,7 @@ public Task> GetFunctionMetadataAsync(string d metadataList.Add(Function0); var Function1RawBindings = new List(); Function1RawBindings.Add(@"{""name"":""$return"",""type"":""Queue"",""direction"":""Out"",""queueName"":""queue2""}"); - Function1RawBindings.Add(@"{""name"":""blob"",""type"":""BlobTrigger"",""direction"":""In"",""properties"":{""supportsDeferredBinding"":""True""},""path"":""container2/%file%"",""dataType"":""String""}"); + Function1RawBindings.Add(@"{""name"":""blob"",""type"":""BlobTrigger"",""direction"":""In"",""properties"":{""supportsDeferredBinding"":""True""},""path"":""container2/%file%"",""source"":""EventGrid"",""dataType"":""String""}"); var Function1 = new DefaultFunctionMetadata {