You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Syntax node actions for partial constructors are not called for the defining part #86086
using System.Collections.Concurrent;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
namespace PartialConstructorTestProject;
[TestClass]
public sealed class PartialConstructorTests
{
[TestMethod]
public async Task SyntaxNodeAction_IsCalledForBothPartsOfPartialConstructor()
{
var source = """
public partial class C
{
public partial C(int x);
public partial C(int x) { }
}
""";
var compilation = CSharpCompilation.Create(
"Test",
[CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.Default))],
[MetadataReference.CreateFromFile(typeof(object).Assembly.Location)],
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
Assert.IsEmpty(compilation.GetDiagnostics());
var analyzer = new ConstructorRecordingAnalyzer();
await compilation.WithAnalyzers([analyzer]).GetAnalyzerDiagnosticsAsync();
Assert.AreEqual("3, 4", string.Join(", ", analyzer.VisitedLines.Order())); // Fails here with only 4
}
[DiagnosticAnalyzer(LanguageNames.CSharp)]
private sealed class ConstructorRecordingAnalyzer : DiagnosticAnalyzer
{
private static readonly DiagnosticDescriptor Descriptor = new(
"TEST0001", "Unused", "Unused", "Test", DiagnosticSeverity.Warning, isEnabledByDefault: true);
public ConcurrentBag<int> VisitedLines { get; } = [];
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => [Descriptor];
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSyntaxNodeAction(HandleConstructor, SyntaxKind.ConstructorDeclaration);
}
private void HandleConstructor(SyntaxNodeAnalysisContext c)
{
VisitedLines.Add(c.Node.GetLocation().GetLineSpan().StartLinePosition.Line + 1);
}
}
}
Expected Behavior:
The registered action should be called for both parts.
changed the title [-]Syntax node actions for constructors are not called for the defining part[/-][+]Syntax node actions for partial constructors are not called for the defining part[/+]on Oct 16, 2026
Activity
bjornhellander commentedon Oct 16, 2026
Nodes within the defining parts (like parameters) does not trigger a registered action either.
[-]Syntax node actions for constructors are not called for the defining part[/-][+]Syntax node actions for partial constructors are not called for the defining part[/+]