Skip to content

Commit 4e8b57a

Browse files
committed
Add analyzer for SupportsDeferredBindingAttribute (#1367)
1 parent cce053d commit 4e8b57a

14 files changed

Lines changed: 241 additions & 28 deletions

DotNetWorker.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Kafka", "
7070
EndProject
7171
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdk.Analyzers", "sdk\Sdk.Analyzers\Sdk.Analyzers.csproj", "{055D602D-D2B3-416B-AC59-1972D832032A}"
7272
EndProject
73-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdk.Analyzers.Tests", "test\Sdk.Analyzers.Tests\Sdk.Analyzers.Tests\Sdk.Analyzers.Tests.csproj", "{A75EA1E1-2801-460C-87C0-DE6A82D30851}"
73+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdk.Analyzers.Tests", "test\Sdk.Analyzers.Tests\Sdk.Analyzers.Tests.csproj", "{A75EA1E1-2801-460C-87C0-DE6A82D30851}"
7474
EndProject
7575
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{083592CA-7DAB-44CE-8979-44FAFA46AEC3}"
7676
EndProject

sdk/Sdk.Analyzers/Constants.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ internal static class Types
99
{
1010
public const string WorkerFunctionAttribute = "Microsoft.Azure.Functions.Worker.FunctionAttribute";
1111
public const string WebJobsBindingAttribute = "Microsoft.Azure.WebJobs.Description.BindingAttribute";
12-
12+
public const string SupportsDeferredBindingAttribute = "Microsoft.Azure.Functions.Worker.Extensions.Abstractions.SupportsDeferredBindingAttribute";
13+
public const string InputBindingAttribute = "Microsoft.Azure.Functions.Worker.Extensions.Abstractions.InputBindingAttribute";
14+
public const string TriggerBindingAttribute = "Microsoft.Azure.Functions.Worker.Extensions.Abstractions.TriggerBindingAttribute";
15+
1316
// System types
1417
internal const string TaskType = "System.Threading.Tasks.Task";
1518
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Immutable;
6+
using Microsoft.CodeAnalysis;
7+
using Microsoft.CodeAnalysis.Diagnostics;
8+
9+
namespace Microsoft.Azure.Functions.Worker.Sdk.Analyzers
10+
{
11+
[DiagnosticAnalyzer(LanguageNames.CSharp)]
12+
public class DeferredBindingAttributeNotSupported : DiagnosticAnalyzer
13+
{
14+
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(DiagnosticDescriptors.DeferredBindingAttributeNotSupported); } }
15+
16+
public override void Initialize(AnalysisContext context)
17+
{
18+
context.EnableConcurrentExecution();
19+
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze);
20+
context.RegisterSymbolAction(AnalyzeMethod, SymbolKind.NamedType);
21+
}
22+
23+
private static void AnalyzeMethod(SymbolAnalysisContext symbolAnalysisContext)
24+
{
25+
var symbol = (INamedTypeSymbol)symbolAnalysisContext.Symbol;
26+
27+
var attributes = symbol.GetAttributes();
28+
29+
if (attributes.IsEmpty)
30+
{
31+
return;
32+
}
33+
34+
foreach (var attribute in attributes)
35+
{
36+
if (attribute.IsSupportsDeferredBindingAttribute() && !IsInputOrTriggerBinding(symbol))
37+
{
38+
var location = Location.Create(attribute.ApplicationSyntaxReference.SyntaxTree, attribute.ApplicationSyntaxReference.Span);
39+
var diagnostic = Diagnostic.Create(DiagnosticDescriptors.DeferredBindingAttributeNotSupported, location, attribute.AttributeClass.Name);
40+
symbolAnalysisContext.ReportDiagnostic(diagnostic);
41+
}
42+
}
43+
}
44+
45+
private static bool IsInputOrTriggerBinding(INamedTypeSymbol symbol)
46+
{
47+
var baseType = symbol.BaseType?.ToDisplayString();
48+
49+
if (string.Equals(baseType,Constants.Types.InputBindingAttribute, StringComparison.Ordinal)
50+
|| string.Equals(baseType,Constants.Types.TriggerBindingAttribute, StringComparison.Ordinal))
51+
{
52+
return true;
53+
}
54+
55+
return false;
56+
}
57+
}
58+
}
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

4-
using System;
5-
using System.Collections.Generic;
6-
using System.Text;
74
using Microsoft.CodeAnalysis;
85

96
namespace Microsoft.Azure.Functions.Worker.Sdk.Analyzers
@@ -16,13 +13,17 @@ private static DiagnosticDescriptor Create(string id, string title,string messag
1613
return new DiagnosticDescriptor(id, title, messageFormat, category, severity, isEnabledByDefault: true, helpLinkUri: helpLink);
1714
}
1815

19-
public static DiagnosticDescriptor WebJobsAttributesAreNotSuppoted { get; }
16+
public static DiagnosticDescriptor WebJobsAttributesAreNotSupported { get; }
2017
= Create(id: "AZFW0001", title: "Invalid binding attributes", messageFormat: "The attribute '{0}' is a WebJobs attribute and not supported in the .NET Worker (Isolated Process).",
2118
category: Constants.DiagnosticsCategories.Usage, severity: DiagnosticSeverity.Error);
22-
19+
2320
public static DiagnosticDescriptor AsyncVoidReturnType { get; }
2421
= Create(id: "AZFW0002", title: "Avoid async void methods", messageFormat: "Do not use void as the return type for async methods. Use Task instead.",
2522
category: Constants.DiagnosticsCategories.Usage, severity: DiagnosticSeverity.Error);
2623

24+
public static DiagnosticDescriptor DeferredBindingAttributeNotSupported{ get; }
25+
= Create(id: "AZFW0003", title: "Invalid class attribute", messageFormat: "The attribute '{0}' can only be used on trigger and input binding attributes.",
26+
category: Constants.DiagnosticsCategories.Usage, severity: DiagnosticSeverity.Error);
27+
2728
}
2829
}

sdk/Sdk.Analyzers/AttributeDataExtensions.cs renamed to sdk/Sdk.Analyzers/Extensions/AttributeDataExtensions.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public static bool IsWebJobAttribute(this AttributeData attributeData)
2222
{
2323
return false;
2424
}
25-
25+
2626
foreach (var attribute in attributeAttributes)
2727
{
2828
if (string.Equals(attribute.AttributeClass?.ToDisplayString(), Constants.Types.WebJobsBindingAttribute,
@@ -34,4 +34,21 @@ public static bool IsWebJobAttribute(this AttributeData attributeData)
3434

3535
return false;
3636
}
37+
38+
/// <summary>
39+
/// Checks if an attribute is the SupportsDeferredBinding attribute.
40+
/// </summary>
41+
/// <param name="attributeData">The attribute to check.</param>
42+
/// <returns>A boolean value indicating whether the attribute is a SupportsDeferredBinding attribute.</returns>
43+
public static bool IsSupportsDeferredBindingAttribute(this AttributeData attributeData)
44+
{
45+
if (string.Equals(attributeData.AttributeClass?.ToDisplayString(),
46+
Constants.Types.SupportsDeferredBindingAttribute,
47+
StringComparison.Ordinal))
48+
{
49+
return true;
50+
}
51+
52+
return false;
53+
}
3754
}
File renamed without changes.
File renamed without changes.
File renamed without changes.

sdk/Sdk.Analyzers/WebJobsAttributesNotSupported.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Microsoft.Azure.Functions.Worker.Sdk.Analyzers
1010
[DiagnosticAnalyzer(LanguageNames.CSharp)]
1111
public class WebJobsAttributesNotSupported : DiagnosticAnalyzer
1212
{
13-
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(DiagnosticDescriptors.WebJobsAttributesAreNotSuppoted); } }
13+
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(DiagnosticDescriptors.WebJobsAttributesAreNotSupported); } }
1414

1515
public override void Initialize(AnalysisContext context)
1616
{
@@ -34,7 +34,7 @@ public override void Initialize(AnalysisContext context)
3434
foreach (var attribute in webjobsAttributes)
3535
{
3636
var location = Location.Create(attribute.ApplicationSyntaxReference.SyntaxTree, attribute.ApplicationSyntaxReference.Span);
37-
c.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.WebJobsAttributesAreNotSuppoted, location, attribute.AttributeClass.Name));
37+
c.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.WebJobsAttributesAreNotSupported, location, attribute.AttributeClass.Name));
3838
}
3939
}
4040
}, SymbolKind.Method);

sdk/release_notes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
- <entry>
1010

11-
### Microsoft.Azure.Functions.Worker.Sdk.Analyzers <version> (delete if not updated)
11+
### Microsoft.Azure.Functions.Worker.Sdk.Analyzers <version>
1212

13-
- <entry>
13+
- Add analyzer for SupportsDeferredBindingAttribute #1367
1414

1515
### Microsoft.Azure.Functions.Worker.Sdk.Generators <version>
1616

0 commit comments

Comments
 (0)