Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions DotNetWorker.sln
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Http.AspN
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Http.AspNetCore.Analyzers", "extensions\Worker.Extensions.Http.AspNetCore.Analyzers\Worker.Extensions.Http.AspNetCore.Analyzers.csproj", "{7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DependentAssemblyWithFunctions.NetStandard", "test\DependentAssemblyWithFunctions.NetStandard\DependentAssemblyWithFunctions.NetStandard.csproj", "{198DA072-F94F-4585-A744-97B3DAC21686}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -336,14 +338,18 @@ Global
{AB6E1E7A-0D2C-4086-9487-566887C1E753}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB6E1E7A-0D2C-4086-9487-566887C1E753}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB6E1E7A-0D2C-4086-9487-566887C1E753}.Release|Any CPU.Build.0 = Release|Any CPU
{7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Release|Any CPU.Build.0 = Release|Any CPU
{D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Release|Any CPU.Build.0 = Release|Any CPU
{7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Release|Any CPU.Build.0 = Release|Any CPU
{198DA072-F94F-4585-A744-97B3DAC21686}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{198DA072-F94F-4585-A744-97B3DAC21686}.Debug|Any CPU.Build.0 = Debug|Any CPU
{198DA072-F94F-4585-A744-97B3DAC21686}.Release|Any CPU.ActiveCfg = Release|Any CPU
{198DA072-F94F-4585-A744-97B3DAC21686}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -404,6 +410,7 @@ Global
{AB6E1E7A-0D2C-4086-9487-566887C1E753} = {B5821230-6E0A-4535-88A9-ED31B6F07596}
{D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4} = {AA4D318D-101B-49E7-A4EC-B34165AEDB33}
{7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
{198DA072-F94F-4585-A744-97B3DAC21686} = {B5821230-6E0A-4535-88A9-ED31B6F07596}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {497D2ED4-A13E-4BCA-8D29-F30CA7D0EA4A}
Expand Down
1 change: 1 addition & 0 deletions sdk/Sdk.Generators/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ internal static class Languages

internal static class BuildProperties
{
internal const string MSBuildTargetFrameworkIdentifier = "build_property.TargetFrameworkIdentifier";
internal const string MSBuildRootNamespace = "build_property.RootNamespace";
internal const string GeneratedCodeNamespace = "build_property.FunctionsGeneratedCodeNamespace";
internal const string EnableSourceGen = "build_property.FunctionsEnableMetadataSourceGen";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public Parser(GeneratorExecutionContext context)
/// Takes in candidate methods from the user compilation and parses them to return function metadata info as GeneratorFunctionMetadata.
/// </summary>
/// <param name="methods">List of candidate methods from the syntax receiver.</param>
public IReadOnlyList<GeneratorFunctionMetadata> GetFunctionMetadataInfo(List<IMethodSymbol> methods)
/// <param name="parsingContext">An instance of <see cref="FunctionsMetadataParsingContext"/>. Optional.</param>
Comment thread
kshyju marked this conversation as resolved.
public IReadOnlyList<GeneratorFunctionMetadata> GetFunctionMetadataInfo(List<IMethodSymbol> methods, FunctionsMetadataParsingContext? parsingContext = null)
{
var result = ImmutableArray.CreateBuilder<GeneratorFunctionMetadata>();

Expand All @@ -49,14 +50,13 @@ public IReadOnlyList<GeneratorFunctionMetadata> GetFunctionMetadataInfo(List<IMe
{
CancellationToken.ThrowIfCancellationRequested();

string? funcName = null;
if (!FunctionsUtil.TryGetFunctionName(method, Compilation, out funcName))
if (!FunctionsUtil.TryGetFunctionName(method, Compilation, out var funcName))
{
_context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.SymbolNotFound, Location.None, method.Name)); // would only reach here if the function attribute or method was not loaded, resulting in failure to retrieve name
}

var assemblyName = method.ContainingAssembly.Name;
var scriptFile = Path.Combine(assemblyName + ".dll");
var scriptFile = $"{assemblyName}{parsingContext?.ScriptFileExtension ?? ".dll"}";

var newFunction = new GeneratorFunctionMetadata
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand All @@ -18,6 +19,10 @@ namespace Microsoft.Azure.Functions.Worker.Sdk.Generators
[Generator]
public partial class FunctionMetadataProviderGenerator : ISourceGenerator
{
private const string NetFxTargetFrameworkIdentifierValue = ".NETFramework";
private const string ExecutableFileExtension = ".exe";
private const string DynamicLinkLibraryFileExtension = ".dll";

public void Execute(GeneratorExecutionContext context)
{
if (context.SyntaxReceiver is not FunctionMethodSyntaxReceiver receiver || receiver.CandidateMethods.Count == 0)
Expand All @@ -37,10 +42,17 @@ public void Execute(GeneratorExecutionContext context)
// attempt to parse user compilation
var p = new Parser(context);

var entryAssemblyFuncs = GetEntryAssemblyFunctions(receiver.CandidateMethods, context);
var dependentFuncs = GetDependentAssemblyFunctions(context);
var entryAssemblyFunctionSymbols = GetEntryAssemblyFunctions(receiver.CandidateMethods, context);
var dependentAssemblyFunctionSymbols = GetDependentAssemblyFunctions(context);

var entryAssemblyParsingContext = new FunctionsMetadataParsingContext
{
ScriptFileExtension = GetScriptFileExtensionForEntryPointAssemblyFunctions(context)
};
var entryAssemblyFunctions = p.GetFunctionMetadataInfo(entryAssemblyFunctionSymbols.ToList(), entryAssemblyParsingContext);
var dependentAssemblyFunctions = p.GetFunctionMetadataInfo(dependentAssemblyFunctionSymbols.ToList());

IReadOnlyList<GeneratorFunctionMetadata> functionMetadataInfo = p.GetFunctionMetadataInfo(entryAssemblyFuncs.Concat(dependentFuncs).ToList());
IReadOnlyList<GeneratorFunctionMetadata> functionMetadataInfo = entryAssemblyFunctions.Concat(dependentAssemblyFunctions).ToList();

// Proceed to generate the file if function metadata info was successfully returned
if (functionMetadataInfo.Count > 0)
Expand All @@ -63,6 +75,14 @@ public void Initialize(GeneratorInitializationContext context)
context.RegisterForSyntaxNotifications(() => new FunctionMethodSyntaxReceiver());
}

// For dependent assemblies, it will be always "dll". We only need to find out for entry point assembly.
private static string GetScriptFileExtensionForEntryPointAssemblyFunctions(GeneratorExecutionContext context)
{
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(Constants.BuildProperties.MSBuildTargetFrameworkIdentifier, out var value);

return string.Equals(value, NetFxTargetFrameworkIdentifierValue, StringComparison.OrdinalIgnoreCase) ? ExecutableFileExtension : DynamicLinkLibraryFileExtension;
}

private static bool ShouldIncludeAutoGeneratedAttributes(GeneratorExecutionContext context)
{
if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.;

namespace Microsoft.Azure.Functions.Worker.Sdk.Generators
{
internal sealed class FunctionsMetadataParsingContext
{
internal string? ScriptFileExtension { get; set; }
}
}
1 change: 1 addition & 0 deletions sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.props
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
<CompilerVisibleProperty Include="FunctionsAutoRegisterGeneratedFunctionsExecutor" />
<CompilerVisibleProperty Include="FunctionsAutoRegisterGeneratedMetadataProvider" />
<CompilerVisibleProperty Include="FunctionsGeneratedCodeNamespace" />
<CompilerVisibleProperty Include="TargetFrameworkIdentifier" />
</ItemGroup>
<!--
***********************************************************************************************
Expand Down
3 changes: 2 additions & 1 deletion sdk/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@

### Microsoft.Azure.Functions.Worker.Sdk.Generators 1.1.5
- Update worker.config generation to accurate worker executable name (#1053)
- Fix incorrect value of `ScriptFile` property in function metadata for .Net Framework function apps (#2103)
- Generate valid namespace when root namespace contains `-` (#2097)
- Bug fix for scenarios with `$return` output binding and `HttpTrigger` breaking output-binding rules (#2098)
- Bug fix for scenarios with `$return` output binding and `HttpTrigger` breaking output-binding rules (#2098)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.19.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;

namespace DependentAssemblyWithFunctions.NetStandard
{
public sealed class NetStandardClassLibraryClass1
{
private readonly ILogger _logger;

public NetStandardClassLibraryClass1(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<NetStandardClassLibraryClass1>();
}

[Function("NetStandardClassLibraryClass1Function1")]
public HttpResponseData Run1([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
{
_logger.LogInformation("NetStandardClassLibraryClass1Function1");
throw new NotImplementedException();
}

[Function("NetStandardClassLibraryClass1Function2Async")]
public Task<HttpResponseData> Run2([HttpTrigger(AuthorizationLevel.Admin, "get", "post")] HttpRequestData req)
{
_logger.LogInformation("NetStandardClassLibraryClass1Function2Async");
throw new NotImplementedException();
}
}
}
Loading