From 475cfaf6d518c50d51e3d88fb7f0f39bbcce5ce2 Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Mon, 25 Sep 2023 08:30:59 -0700 Subject: [PATCH 1/4] Using root namespace for generated types. --- sdk/Sdk.Generators/Constants.cs | 1 + .../ExtensionStartupRunnerGenerator.cs | 10 +-- .../FunctionExecutorGenerator.Emitter.cs | 7 +- .../FunctionExecutorGenerator.cs | 2 +- ...nctionMetadataProviderGenerator.Emitter.cs | 8 ++- .../FunctionMetadataProviderGenerator.cs | 11 ++- sdk/Sdk.Generators/FunctionsUtil.cs | 18 ++++- ...Microsoft.Azure.Functions.Worker.Sdk.props | 1 + .../ExtensionStartupRunnerGeneratorTests.cs | 68 ++++--------------- .../FunctionExecutorGeneratorTests.cs | 21 ++++-- .../AutoConfigureStartupTypeTests.cs | 3 +- .../DependentAssemblyTest.cs | 3 +- .../EventHubsBindingsTests.cs | 18 +++-- .../HttpTriggerTests.cs | 18 +++-- .../IntegratedTriggersAndBindingsTests.cs | 18 +++-- .../NestedTypesTest.cs | 6 +- .../RetryOptionsTests.cs | 6 +- .../StorageBindingTests.cs | 6 +- 18 files changed, 121 insertions(+), 104 deletions(-) diff --git a/sdk/Sdk.Generators/Constants.cs b/sdk/Sdk.Generators/Constants.cs index 95ad3ddea..18e84c3b7 100644 --- a/sdk/Sdk.Generators/Constants.cs +++ b/sdk/Sdk.Generators/Constants.cs @@ -12,6 +12,7 @@ internal static class Languages internal static class BuildProperties { + internal const string GeneratedCodeNamespace = "build_property.FunctionsGeneratedCodeNamespace"; internal const string EnableSourceGen = "build_property.FunctionsEnableMetadataSourceGen"; internal const string EnablePlaceholder = "build_property.FunctionsEnableExecutorSourceGen"; internal const string AutoRegisterGeneratedFunctionsExecutor = "build_property.FunctionsAutoRegisterGeneratedFunctionsExecutor"; diff --git a/sdk/Sdk.Generators/ExtensionStartupRunnerGenerator.cs b/sdk/Sdk.Generators/ExtensionStartupRunnerGenerator.cs index 48b20d456..700f46299 100644 --- a/sdk/Sdk.Generators/ExtensionStartupRunnerGenerator.cs +++ b/sdk/Sdk.Generators/ExtensionStartupRunnerGenerator.cs @@ -69,7 +69,7 @@ public void Execute(GeneratorExecutionContext context) return; } - var source = GenerateExtensionStartupRunner(extensionStartupTypeNames); + var source = GenerateExtensionStartupRunner(context, extensionStartupTypeNames); var sourceText = SourceText.From(source, encoding: Encoding.UTF8); // Add the source code to the compilation @@ -81,18 +81,20 @@ public void Execute(GeneratorExecutionContext context) /// /// The types to add to the configuration/bootstrapping process. /// The generated source code. - internal string GenerateExtensionStartupRunner(IList extensionStartupTypeNames) + internal string GenerateExtensionStartupRunner(GeneratorExecutionContext context, IList extensionStartupTypeNames) { string startupCodeExecutor = GenerateStartupCodeExecutorClass(extensionStartupTypeNames); + var ns = FunctionsUtil.GetNamespaceForGeneratedCode(context); return $$""" // using System; + using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Core; - [assembly: WorkerExtensionStartupCodeExecutorInfo(typeof(Microsoft.Azure.Functions.Worker.WorkerExtensionStartupCodeExecutor))] + [assembly: WorkerExtensionStartupCodeExecutorInfo(typeof({{ns}}.WorkerExtensionStartupCodeExecutor))] - namespace Microsoft.Azure.Functions.Worker + namespace {{ns}} { internal class WorkerExtensionStartupCodeExecutor : WorkerExtensionStartup { diff --git a/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.Emitter.cs b/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.Emitter.cs index 7dc051d6e..abf0e51bf 100644 --- a/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.Emitter.cs +++ b/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.Emitter.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Threading; +using Microsoft.CodeAnalysis; namespace Microsoft.Azure.Functions.Worker.Sdk.Generators { @@ -13,7 +13,7 @@ public partial class FunctionExecutorGenerator { internal static class Emitter { - internal static string Emit(IEnumerable functions, bool includeAutoRegistrationCode, CancellationToken cancellationToken) + internal static string Emit(GeneratorExecutionContext context, IEnumerable functions, bool includeAutoRegistrationCode) { string result = $$""" @@ -23,9 +23,10 @@ internal static string Emit(IEnumerable functions, bool incl using System.Collections.Generic; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Context.Features; using Microsoft.Azure.Functions.Worker.Invocation; - namespace Microsoft.Azure.Functions.Worker + namespace {{FunctionsUtil.GetNamespaceForGeneratedCode(context)}} { internal class DirectFunctionExecutor : IFunctionExecutor { diff --git a/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.cs b/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.cs index b886b96ec..4bbea665f 100644 --- a/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.cs +++ b/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.cs @@ -38,7 +38,7 @@ public void Execute(GeneratorExecutionContext context) var shouldIncludeAutoGeneratedAttributes = ShouldIncludeAutoGeneratedAttributes(context); - var text = Emitter.Emit(functions, shouldIncludeAutoGeneratedAttributes, context.CancellationToken); + var text = Emitter.Emit(context, functions, shouldIncludeAutoGeneratedAttributes); context.AddSource(Constants.FileNames.GeneratedFunctionExecutor, SourceText.From(text, Encoding.UTF8)); } diff --git a/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Emitter.cs b/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Emitter.cs index 193a4e870..63016583a 100644 --- a/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Emitter.cs +++ b/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Emitter.cs @@ -5,6 +5,7 @@ using System.Text; using System.Text.Json; using System.Threading; +using Microsoft.CodeAnalysis; namespace Microsoft.Azure.Functions.Worker.Sdk.Generators { @@ -18,9 +19,9 @@ internal sealed class Emitter DictionaryKeyPolicy = JsonNamingPolicy.CamelCase }; - public string Emit(IReadOnlyList funcMetadata, bool includeAutoRegistrationCode, CancellationToken cancellationToken) + public string Emit(GeneratorExecutionContext context, IReadOnlyList funcMetadata, bool includeAutoRegistrationCode) { - string functionMetadataInfo = AddFunctionMetadataInfo(funcMetadata, cancellationToken); + string functionMetadataInfo = AddFunctionMetadataInfo(funcMetadata, context.CancellationToken); return $$""" // @@ -29,11 +30,12 @@ public string Emit(IReadOnlyList funcMetadata, bool i using System.Collections.Immutable; using System.Text.Json; using System.Threading.Tasks; + using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; - namespace Microsoft.Azure.Functions.Worker + namespace {{FunctionsUtil.GetNamespaceForGeneratedCode(context)}} { public class GeneratedFunctionMetadataProvider : IFunctionMetadataProvider { diff --git a/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.cs b/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.cs index 96b722e20..665bf2f44 100644 --- a/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.cs +++ b/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Collections.Immutable; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; @@ -49,7 +48,7 @@ public void Execute(GeneratorExecutionContext context) Emitter e = new(); var shouldIncludeAutoGeneratedAttributes = ShouldIncludeAutoGeneratedAttributes(context); - string result = e.Emit(functionMetadataInfo, shouldIncludeAutoGeneratedAttributes, context.CancellationToken); + string result = e.Emit(context, functionMetadataInfo, shouldIncludeAutoGeneratedAttributes); context.AddSource(Constants.FileNames.GeneratedFunctionMetadata, SourceText.From(result, Encoding.UTF8)); } @@ -63,7 +62,7 @@ public void Initialize(GeneratorInitializationContext context) { context.RegisterForSyntaxNotifications(() => new FunctionMethodSyntaxReceiver()); } - + private static bool ShouldIncludeAutoGeneratedAttributes(GeneratorExecutionContext context) { if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue( @@ -77,15 +76,13 @@ private static bool ShouldIncludeAutoGeneratedAttributes(GeneratorExecutionConte private IEnumerable GetEntryAssemblyFunctions(List candidateMethods, GeneratorExecutionContext context) { - IList? entryAssemblyFuncs = new List(); - foreach (MethodDeclarationSyntax method in candidateMethods) { var model = context.Compilation.GetSemanticModel(method.SyntaxTree); - if (FunctionsUtil.IsValidFunctionMethod(context, context.Compilation, model, method)) + if (FunctionsUtil.IsValidFunctionMethod(context, context.Compilation, model, method)) { - IMethodSymbol? methodSymbol = (IMethodSymbol) model.GetDeclaredSymbol(method)!; + IMethodSymbol? methodSymbol = (IMethodSymbol)model.GetDeclaredSymbol(method)!; yield return methodSymbol; } } diff --git a/sdk/Sdk.Generators/FunctionsUtil.cs b/sdk/Sdk.Generators/FunctionsUtil.cs index 429400f27..7d82af381 100644 --- a/sdk/Sdk.Generators/FunctionsUtil.cs +++ b/sdk/Sdk.Generators/FunctionsUtil.cs @@ -4,9 +4,6 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis; using System.Linq; -using System.Reflection.Metadata.Ecma335; -using System.Data; -using System; namespace Microsoft.Azure.Functions.Worker.Sdk.Generators { @@ -77,5 +74,20 @@ internal static string GetFullyQualifiedMethodName(IMethodSymbol method) var fullyQualifiedClassName = method.ContainingSymbol.ToDisplayString(); return $"{fullyQualifiedClassName}.{method.Name}"; } + + /// + /// Gets the namespace value to be used for the auto generated types. + /// + internal static string GetNamespaceForGeneratedCode(GeneratorExecutionContext context) + { + // If csproj has the msbuild property specified, use it's value. + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(Constants.BuildProperties.GeneratedCodeNamespace, out var namespaceValue)) + { + return namespaceValue; + } + + // Use root namespace. + return context.Compilation.Assembly.Name; + } } } diff --git a/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.props b/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.props index bac53404a..d24ff04fb 100644 --- a/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.props +++ b/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.props @@ -25,6 +25,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and +