Skip to content

Commit 9f8c8ed

Browse files
CopilotYunchuWang
andcommitted
Optimize assembly scanning to avoid double traversal
Removed ShouldScanAssembly and ContainsDurableSymbols methods that caused the namespace tree to be traversed twice (once to check if assembly has Durable symbols, then again to collect function names). Now directly calls ScanNamespaceForFunctions which does all the work in a single pass. IsSystemAssembly already filters out the vast majority of irrelevant assemblies. Co-authored-by: YunchuWang <[email protected]>
1 parent e94bcd5 commit 9f8c8ed

File tree

1 file changed

+2
-82
lines changed

1 file changed

+2
-82
lines changed

src/Analyzers/Activities/FunctionNotFoundAnalyzer.cs

Lines changed: 2 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ static void ScanReferencedAssemblies(
360360
CancellationToken cancellationToken)
361361
{
362362
// Scan all referenced assemblies for activities and orchestrators
363-
// Skip system assemblies and assemblies without Durable symbols for performance
363+
// Skip system assemblies for performance
364364
foreach (MetadataReference reference in compilation.References)
365365
{
366366
cancellationToken.ThrowIfCancellationRequested();
@@ -375,12 +375,7 @@ static void ScanReferencedAssemblies(
375375
continue;
376376
}
377377

378-
if (!ShouldScanAssembly(assembly, knownSymbols))
379-
{
380-
continue;
381-
}
382-
383-
// Scan this assembly
378+
// Scan this assembly - if it doesn't contain Durable functions, nothing will be added
384379
ScanNamespaceForFunctions(
385380
assembly.GlobalNamespace,
386381
knownSymbols,
@@ -409,81 +404,6 @@ static bool IsSystemAssembly(IAssemblySymbol assembly)
409404
return false;
410405
}
411406

412-
static bool ShouldScanAssembly(IAssemblySymbol assembly, KnownTypeSymbols knownSymbols)
413-
{
414-
// Check if assembly contains any Durable Task symbols using semantic lookup
415-
// This is more robust than checking assembly references
416-
return ContainsDurableSymbols(assembly.GlobalNamespace, knownSymbols);
417-
}
418-
419-
static bool ContainsDurableSymbols(INamespaceSymbol namespaceSymbol, KnownTypeSymbols knownSymbols)
420-
{
421-
// Check types in this namespace for Durable Task symbols
422-
foreach (INamedTypeSymbol typeSymbol in namespaceSymbol.GetTypeMembers())
423-
{
424-
// Check if type derives from TaskActivity
425-
if (knownSymbols.TaskActivityBase != null && DerivesFrom(typeSymbol, knownSymbols.TaskActivityBase))
426-
{
427-
return true;
428-
}
429-
430-
// Check if type implements ITaskOrchestrator
431-
if (knownSymbols.TaskOrchestratorInterface != null &&
432-
ImplementsInterface(typeSymbol, knownSymbols.TaskOrchestratorInterface))
433-
{
434-
return true;
435-
}
436-
437-
// Check methods for Durable Task attributes
438-
foreach (ISymbol member in typeSymbol.GetMembers())
439-
{
440-
if (member is not IMethodSymbol methodSymbol)
441-
{
442-
continue;
443-
}
444-
445-
// Check for ActivityTrigger attribute
446-
if (knownSymbols.ActivityTriggerAttribute != null &&
447-
methodSymbol.ContainsAttributeInAnyMethodArguments(knownSymbols.ActivityTriggerAttribute))
448-
{
449-
return true;
450-
}
451-
452-
// Check for OrchestrationTrigger attribute
453-
if (knownSymbols.FunctionOrchestrationAttribute != null &&
454-
methodSymbol.ContainsAttributeInAnyMethodArguments(knownSymbols.FunctionOrchestrationAttribute))
455-
{
456-
return true;
457-
}
458-
}
459-
}
460-
461-
// Recursively check nested namespaces
462-
foreach (INamespaceSymbol nestedNamespace in namespaceSymbol.GetNamespaceMembers())
463-
{
464-
if (ContainsDurableSymbols(nestedNamespace, knownSymbols))
465-
{
466-
return true;
467-
}
468-
}
469-
470-
return false;
471-
}
472-
473-
static bool DerivesFrom(INamedTypeSymbol typeSymbol, INamedTypeSymbol baseType)
474-
{
475-
INamedTypeSymbol? current = typeSymbol.BaseType;
476-
while (current != null)
477-
{
478-
if (SymbolEqualityComparer.Default.Equals(current.OriginalDefinition, baseType))
479-
{
480-
return true;
481-
}
482-
current = current.BaseType;
483-
}
484-
return false;
485-
}
486-
487407
static void ScanNamespaceForFunctions(
488408
INamespaceSymbol namespaceSymbol,
489409
KnownTypeSymbols knownSymbols,

0 commit comments

Comments
 (0)