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
7 changes: 6 additions & 1 deletion sdk/Sdk.Generators/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ namespace Microsoft.Azure.Functions.Worker.Sdk.Generators
{
internal static class Constants
{
internal static class ExecutionModel
{
internal const string Isolated = "isolated";
}

internal static class Languages
{
internal const string DotnetIsolated = "dotnet-isolated";
}

internal static class BuildProperties
{
internal const string FunctionsExecutionModel = "build_property.FunctionsExecutionModel";
Comment thread
jviau marked this conversation as resolved.
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";
internal const string EnablePlaceholder = "build_property.FunctionsEnableExecutorSourceGen";
Expand Down
5 changes: 5 additions & 0 deletions sdk/Sdk.Generators/ExtensionStartupRunnerGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public class ExtensionStartupRunnerGenerator : ISourceGenerator

public void Execute(GeneratorExecutionContext context)
{
if (!context.IsRunningInAzureFunctionProject())
{
return;
}

var extensionStartupTypeNames = GetExtensionStartupTypes(context);

if (!extensionStartupTypeNames.Any())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using Microsoft.CodeAnalysis;

namespace Microsoft.Azure.Functions.Worker.Sdk.Generators
{
internal static class GeneratorExecutionContextExtensions
{
/// <summary>
/// Returns true if the source generator is running in the context of an "Azure Function" project.
/// </summary>
internal static bool IsRunningInAzureFunctionProject(this GeneratorExecutionContext context)
{
if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(Constants.BuildProperties.FunctionsExecutionModel, out var value))
{
return string.Equals(value, Constants.ExecutionModel.Isolated);
}

return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ public void Initialize(GeneratorInitializationContext context)

public void Execute(GeneratorExecutionContext context)
{
if (!context.IsRunningInAzureFunctionProject())
{
return;
}

if (!ShouldExecuteGeneration(context))
{
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public partial class FunctionMetadataProviderGenerator : ISourceGenerator

public void Execute(GeneratorExecutionContext context)
{
if (!context.IsRunningInAzureFunctionProject())
{
return;
}

if (context.SyntaxReceiver is not FunctionMethodSyntaxReceiver receiver || receiver.CandidateMethods.Count == 0)
{
return;
Expand Down
4 changes: 2 additions & 2 deletions sdk/Sdk.Generators/Sdk.Generators.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<IncludeBuildOutput>false</IncludeBuildOutput>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<MinorProductVersion>1</MinorProductVersion>
<PatchProductVersion>5</PatchProductVersion>
<VersionSuffix></VersionSuffix>
<PatchProductVersion>6</PatchProductVersion>
<VersionSuffix>-preview1</VersionSuffix>
<IsRoslynComponent>true</IsRoslynComponent>
</PropertyGroup>

Expand Down
3 changes: 2 additions & 1 deletion sdk/Sdk/Sdk.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

<PropertyGroup>
<MinorProductVersion>16</MinorProductVersion>
<PatchProductVersion>3</PatchProductVersion>
<PatchProductVersion>4</PatchProductVersion>
<VersionSuffix>-preview1</VersionSuffix>
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<PackageId>Microsoft.Azure.Functions.Worker.Sdk</PackageId>
<Description>This package provides development time support for the Azure Functions .NET Worker.</Description>
Expand Down
2 changes: 2 additions & 0 deletions sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
<!--Our source generators rely on the FunctionsExecutionModel property.-->
<FunctionsExecutionModel>isolated</FunctionsExecutionModel>
<_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
</PropertyGroup>
Expand All @@ -27,6 +28,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
<CompilerVisibleProperty Include="FunctionsAutoRegisterGeneratedMetadataProvider" />
<CompilerVisibleProperty Include="FunctionsGeneratedCodeNamespace" />
<CompilerVisibleProperty Include="TargetFrameworkIdentifier" />
<CompilerVisibleProperty Include="FunctionsExecutionModel" />
</ItemGroup>
<!--
***********************************************************************************************
Expand Down
15 changes: 4 additions & 11 deletions sdk/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@
- My change description (#PR/#issue)
-->

### Microsoft.Azure.Functions.Worker.Sdk 1.16.3 (meta package)
### Microsoft.Azure.Functions.Worker.Sdk 1.16.4-preview1 (meta package)

- Update worker.config generation to accurate worker executable name (#1053)
- Default to optimized function executor.
- Update Microsoft.Azure.Functions.Worker.Sdk.Generators dependency to 1.1.5
- Update Microsoft.Azure.Functions.Worker.Sdk.Generators dependency to 1.1.6-preview1

### Microsoft.Azure.Functions.Worker.Sdk.Generators 1.1.5
### Microsoft.Azure.Functions.Worker.Sdk.Generators 1.1.6-preview1

- Adding support for executing functions from referenced assemblies in the optimized function executor (#2089)
- 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)
- Add `CompilerGeneratedAttribute`` to generated code (#2104)
- Avoid executing source generators outside of an Azure Functions project. (#2119)
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
using Xunit;
namespace Microsoft.Azure.Functions.SdkGeneratorTests
{
public class ExtensionStartupRunnerGeneratorTests
public partial class ExtensionStartupRunnerGeneratorTests
{
const string InputCode = """
public class Foo
Expand Down
48 changes: 48 additions & 0 deletions test/Sdk.Generator.Tests/ExtensionStartup/NotGeneratedTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Threading.Tasks;
using Microsoft.Azure.Functions.Tests.WorkerExtensionsSample;
using Microsoft.Azure.Functions.Worker.Sdk.Generators;
using Microsoft.CodeAnalysis.CSharp;
using Xunit;
namespace Microsoft.Azure.Functions.SdkGeneratorTests
{
public partial class ExtensionStartupRunnerGeneratorTests
{
public sealed class NotGeneratedTests
{
const string InputCode = """
public class Foo
{
}
""";

[Theory]
[InlineData(LanguageVersion.CSharp7_3)]
[InlineData(LanguageVersion.CSharp8)]
[InlineData(LanguageVersion.CSharp9)]
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
public async Task NotGeneratedWhenNotRunningInAnAzureFunctionsProject(LanguageVersion languageVersion)
{
var referencedExtensionAssemblies = new[]
{
typeof(SampleExtensionStartup).Assembly,
};

string? expectedGeneratedFileName = null;
string? expectedOutput = null;

await TestHelpers.RunTestAsync<ExtensionStartupRunnerGenerator>(
referencedExtensionAssemblies,
InputCode,
expectedGeneratedFileName,
expectedOutput,
languageVersion: languageVersion,
runInsideAzureFunctionProject: false);
}
}
}
}
74 changes: 74 additions & 0 deletions test/Sdk.Generator.Tests/FunctionExecutor/NotGeneratedTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Sdk.Generators;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Xunit;

namespace Microsoft.Azure.Functions.SdkGeneratorTests
{
public partial class FunctionExecutorGeneratorTests
{
public sealed class NotGeneratedTests
{
private readonly Assembly[] _referencedAssemblies = new[]
{
typeof(HttpTriggerAttribute).Assembly,
typeof(FunctionAttribute).Assembly,
typeof(LoggingServiceCollectionExtensions).Assembly,
typeof(ServiceProviderServiceExtensions).Assembly,
typeof(ServiceCollection).Assembly,
typeof(ILogger).Assembly,
typeof(IConfiguration).Assembly,
typeof(HostBuilder).Assembly,
typeof(IHostBuilder).Assembly
};

[Theory]
[InlineData(LanguageVersion.CSharp7_3)]
[InlineData(LanguageVersion.CSharp8)]
[InlineData(LanguageVersion.CSharp9)]
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
public async Task NotGeneratedWhenNotRunningInAnAzureFunctionsProject(LanguageVersion languageVersion)
{
string inputCode = """
using System;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;

namespace MyCompany.MyApp.Functions
{
public static class HttpTriggerSimple
{
[Function(nameof(HttpTriggerSimple))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req)
{
throw new NotImplementedException();
}
}
}
""";
string? expectedGeneratedFileName = null;
string? expectedOutput = null;

await TestHelpers.RunTestAsync<FunctionExecutorGenerator>(
_referencedAssemblies,
inputCode,
expectedGeneratedFileName,
expectedOutput,
languageVersion: languageVersion,
runInsideAzureFunctionProject: false);
}

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Sdk.Generators;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Xunit;

namespace Microsoft.Azure.Functions.SdkGeneratorTests
{
public partial class FunctionMetadataProviderGeneratorTests
{
public sealed class NotGeneratedTests
{
private readonly Assembly[] _referencedExtensionAssemblies = new[]
{
typeof(HttpTriggerAttribute).Assembly, typeof(FunctionAttribute).Assembly,
typeof(LoggingServiceCollectionExtensions).Assembly,
typeof(ServiceProviderServiceExtensions).Assembly, typeof(ServiceCollection).Assembly,
typeof(ILogger).Assembly, typeof(IConfiguration).Assembly, typeof(HostBuilder).Assembly,
typeof(IHostBuilder).Assembly
};

[Theory]
[InlineData(LanguageVersion.CSharp7_3)]
[InlineData(LanguageVersion.CSharp8)]
[InlineData(LanguageVersion.CSharp9)]
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
public async Task NotGeneratedWhenNotRunningInAnAzureFunctionsProject(LanguageVersion languageVersion)
{
string inputCode = """
using System;
using System.Collections.Generic;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;

namespace MyCompany.MyApp.Functions
{
public static class HttpTriggerSimple
{
[Function(nameof(HttpTriggerSimple))]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req)
{
throw new NotImplementedException();
}
}
}
""";

string? expectedGeneratedFileName = null;
string? expectedOutput = null;

await TestHelpers.RunTestAsync<FunctionMetadataProviderGenerator>(
_referencedExtensionAssemblies,
inputCode,
expectedGeneratedFileName,
expectedOutput,
languageVersion: languageVersion,
runInsideAzureFunctionProject: false);
}
}
}
}
9 changes: 8 additions & 1 deletion test/Sdk.Generator.Tests/TestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public static Task RunTestAsync<TSourceGenerator>(
List<DiagnosticResult>? expectedDiagnosticResults = null,
IDictionary<string, string>? buildPropertiesDictionary = null,
string? generatedCodeNamespace = null,
LanguageVersion? languageVersion = null) where TSourceGenerator : ISourceGenerator, new()
LanguageVersion? languageVersion = null,
bool runInsideAzureFunctionProject = true) where TSourceGenerator : ISourceGenerator, new()
{
CSharpSourceGeneratorVerifier<TSourceGenerator>.Test test = new()
{
Expand All @@ -60,6 +61,12 @@ public static Task RunTestAsync<TSourceGenerator>(
build_property.FunctionsEnableMetadataSourceGen = {true}
build_property.FunctionsGeneratedCodeNamespace = {generatedCodeNamespace ?? "TestProject"}";

if (runInsideAzureFunctionProject)
{
config += $@"
build_property.FunctionsExecutionModel = isolated";
}

// Add test specific MSBuild properties.
if (buildPropertiesDictionary is not null)
{
Expand Down