Skip to content

Commit 9786732

Browse files
CopilotYunchuWang
andcommitted
Resolve merge conflicts with main branch
- Added DurableEventTypeInfo support from main branch - Updated Initialize method to include durableEventAttributes provider - Updated Execute method signature to include allEvents parameter - Added GetDurableEventTypeInfo method - Added DurableEventTypeInfo class - Preserved projectType parameter functionality - All 45 tests passing Co-authored-by: YunchuWang <12449837+YunchuWang@users.noreply.github.com>
1 parent cbdc3b9 commit 9786732

File tree

1 file changed

+92
-4
lines changed

1 file changed

+92
-4
lines changed

src/Generators/DurableTaskSourceGenerator.cs

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
4949
transform: static (ctx, _) => GetDurableTaskTypeInfo(ctx))
5050
.Where(static info => info != null)!;
5151

52+
// Create providers for DurableEvent attributes
53+
IncrementalValuesProvider<DurableEventTypeInfo> durableEventAttributes = context.SyntaxProvider
54+
.CreateSyntaxProvider(
55+
predicate: static (node, _) => node is AttributeSyntax,
56+
transform: static (ctx, _) => GetDurableEventTypeInfo(ctx))
57+
.Where(static info => info != null)!;
58+
5259
// Create providers for Durable Functions
5360
IncrementalValuesProvider<DurableFunction> durableFunctions = context.SyntaxProvider
5461
.CreateSyntaxProvider(
@@ -65,15 +72,23 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
6572
});
6673

6774
// Collect all results and check if Durable Functions is referenced
68-
IncrementalValueProvider<(Compilation, ImmutableArray<DurableTaskTypeInfo>, ImmutableArray<DurableFunction>, string?)> compilationAndTasks =
75+
IncrementalValueProvider<(Compilation, ImmutableArray<DurableTaskTypeInfo>, ImmutableArray<DurableEventTypeInfo>, ImmutableArray<DurableFunction>, string?)> compilationAndTasks =
6976
durableTaskAttributes.Collect()
77+
.Combine(durableEventAttributes.Collect())
7078
.Combine(durableFunctions.Collect())
7179
.Combine(context.CompilationProvider)
7280
.Combine(projectTypeProvider)
73-
.Select((x, _) => (x.Left.Right, x.Left.Left.Left, x.Left.Left.Right, x.Right));
81+
// Roslyn's IncrementalValueProvider.Combine creates nested tuple pairs: ((Left, Right), Right)
82+
// After multiple .Combine() calls, we unpack the nested structure:
83+
// x.Right = projectType (string?)
84+
// x.Left.Right = Compilation
85+
// x.Left.Left.Left.Left = DurableTaskAttributes (orchestrators, activities, entities)
86+
// x.Left.Left.Left.Right = DurableEventAttributes (events)
87+
// x.Left.Left.Right = DurableFunctions (Azure Functions metadata)
88+
.Select((x, _) => (x.Left.Right, x.Left.Left.Left.Left, x.Left.Left.Left.Right, x.Left.Left.Right, x.Right));
7489

7590
// Generate the source
76-
context.RegisterSourceOutput(compilationAndTasks, static (spc, source) => Execute(spc, source.Item1, source.Item2, source.Item3, source.Item4));
91+
context.RegisterSourceOutput(compilationAndTasks, static (spc, source) => Execute(spc, source.Item1, source.Item2, source.Item3, source.Item4, source.Item5));
7792
}
7893

7994
static DurableTaskTypeInfo? GetDurableTaskTypeInfo(GeneratorSyntaxContext context)
@@ -170,6 +185,49 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
170185
return new DurableTaskTypeInfo(className, taskName, inputType, outputType, kind);
171186
}
172187

188+
static DurableEventTypeInfo? GetDurableEventTypeInfo(GeneratorSyntaxContext context)
189+
{
190+
AttributeSyntax attribute = (AttributeSyntax)context.Node;
191+
192+
ITypeSymbol? attributeType = context.SemanticModel.GetTypeInfo(attribute.Name).Type;
193+
if (attributeType?.ToString() != "Microsoft.DurableTask.DurableEventAttribute")
194+
{
195+
return null;
196+
}
197+
198+
// DurableEventAttribute can be applied to both class and struct (record)
199+
TypeDeclarationSyntax? typeDeclaration = attribute.Parent?.Parent as TypeDeclarationSyntax;
200+
if (typeDeclaration == null)
201+
{
202+
return null;
203+
}
204+
205+
// Verify that the attribute is being used on a non-abstract type
206+
if (typeDeclaration.Modifiers.Any(SyntaxKind.AbstractKeyword))
207+
{
208+
return null;
209+
}
210+
211+
if (context.SemanticModel.GetDeclaredSymbol(typeDeclaration) is not ITypeSymbol eventType)
212+
{
213+
return null;
214+
}
215+
216+
string eventName = eventType.Name;
217+
218+
if (attribute.ArgumentList?.Arguments.Count > 0)
219+
{
220+
ExpressionSyntax expression = attribute.ArgumentList.Arguments[0].Expression;
221+
Optional<object?> constantValue = context.SemanticModel.GetConstantValue(expression);
222+
if (constantValue.HasValue && constantValue.Value is string value)
223+
{
224+
eventName = value;
225+
}
226+
}
227+
228+
return new DurableEventTypeInfo(eventName, eventType);
229+
}
230+
173231
static DurableFunction? GetDurableFunction(GeneratorSyntaxContext context)
174232
{
175233
MethodDeclarationSyntax method = (MethodDeclarationSyntax)context.Node;
@@ -186,10 +244,11 @@ static void Execute(
186244
SourceProductionContext context,
187245
Compilation compilation,
188246
ImmutableArray<DurableTaskTypeInfo> allTasks,
247+
ImmutableArray<DurableEventTypeInfo> allEvents,
189248
ImmutableArray<DurableFunction> allFunctions,
190249
string? projectType)
191250
{
192-
if (allTasks.IsDefaultOrEmpty && allFunctions.IsDefaultOrEmpty)
251+
if (allTasks.IsDefaultOrEmpty && allEvents.IsDefaultOrEmpty && allFunctions.IsDefaultOrEmpty)
193252
{
194253
return;
195254
}
@@ -565,5 +624,34 @@ static string GetRenderedTypeExpression(ITypeSymbol? symbol)
565624
return expression;
566625
}
567626
}
627+
628+
class DurableEventTypeInfo
629+
{
630+
public DurableEventTypeInfo(string eventName, ITypeSymbol eventType)
631+
{
632+
this.TypeName = GetRenderedTypeExpression(eventType);
633+
this.EventName = eventName;
634+
}
635+
636+
public string TypeName { get; }
637+
public string EventName { get; }
638+
639+
static string GetRenderedTypeExpression(ITypeSymbol? symbol)
640+
{
641+
if (symbol == null)
642+
{
643+
return "object";
644+
}
645+
646+
string expression = symbol.ToString();
647+
if (expression.StartsWith("System.", StringComparison.Ordinal)
648+
&& symbol.ContainingNamespace.Name == "System")
649+
{
650+
expression = expression.Substring("System.".Length);
651+
}
652+
653+
return expression;
654+
}
655+
}
568656
}
569657
}

0 commit comments

Comments
 (0)