Skip to content

Use new Slice-Compiler-Definitions (Mostly Diagnostics)#4615

Merged
InsertCreativityHere merged 13 commits into
icerpc:mainfrom
InsertCreativityHere:use-new-slicec-diagnostics
May 26, 2026
Merged

Use new Slice-Compiler-Definitions (Mostly Diagnostics)#4615
InsertCreativityHere merged 13 commits into
icerpc:mainfrom
InsertCreativityHere:use-new-slicec-diagnostics

Conversation

@InsertCreativityHere
Copy link
Copy Markdown
Member

@InsertCreativityHere InsertCreativityHere commented May 12, 2026

This PR pulls in 2 changes from slicec:

  • Switching Options from a Dictionary<string, string> to a Sequence<CodeGeneratorOption>
  • The new API for reporting diagnostics

The first is pretty straightforward, I just updated the decoding logic and the signatures that used it.
Instead of a Dictionary<string, string>, I chose a KeyValuePair<string, string>[].
If there is a better choice of type, please let me know. I am not a master of C# type conventions!

The second involved creating a new wrapper type Diagnostic, with a handful of factory functions on it to create specific types of diagnostics. The validation (duplicate files and attributes) was updated to use these factory functions, instead of the old API which just took a string and a level.


Alot of the diff is just generated code. I promise this PR isn't as scary as it looks ;-;

@InsertCreativityHere InsertCreativityHere force-pushed the use-new-slicec-diagnostics branch from d330702 to 4240c24 Compare May 22, 2026 15:47
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the C# Slice generator/plugin protocol to align with the new Compiler::Diagnostic/DiagnosticKind model (and option representation) introduced upstream in slicec (#776), and re-enables C# attribute validation with richer, source-aware diagnostics.

Changes:

  • Switch generator request “options” from Dictionary<string, string> to a sequence of key/value options and update the generator pipeline signatures accordingly.
  • Replace the old DiagnosticLevel/string-message diagnostics with structured compiler diagnostics (DiagnosticKind, DiagnosticNote, source, notes) and update response encoding.
  • Re-enable C# attribute validation and update CsAttributeValidator to emit the new structured diagnostics (with per-attribute source paths and notes).

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/ZeroC.Slice.Generator.Tests/VariantEnumTests.slice Removes variant-enum attribute test input tied to the old behavior.
tests/ZeroC.Slice.Generator.Tests/VariantEnumTests.cs Removes reflection-based attribute assertion that no longer applies.
src/ZeroC.Slice.Symbols/Generator.cs Updates request decoding / response encoding for new options + diagnostics protocol.
src/ZeroC.Slice.Symbols/Diagnostic.cs Reworks diagnostics to map to Compiler.DiagnosticKind + notes and adds helper factories.
src/ZeroC.Slice.Symbols/DiagnosticLevel.cs Removes the old severity enum in favor of DiagnosticKind.
src/ZeroC.Slice.Symbols/Compiler/SyntaxElements.cs Regenerated compiler model (version bump).
src/ZeroC.Slice.Symbols/Compiler/DocComment.cs Regenerated compiler model (version bump).
src/ZeroC.Slice.Symbols/Compiler/Diagnostics.cs Adds generated C# types for new compiler diagnostics protocol.
src/ZeroC.Slice.Symbols/Compiler/CodeGenerator.cs Updates generated protocol types (options now CodeGeneratorOption sequence; old diagnostics removed).
src/ZeroC.Slice.Generator/GeneratorDriver.cs Re-enables attribute validation and updates error handling to use new diagnostics.
src/ZeroC.Slice.Generator/CSAttributeValidator.cs Emits structured diagnostics with sources/notes and updated validation rules.
src/IceRpc.Slice.BuildTelemetry/Program.cs Updates generator callback signature for new options representation.
slice/Ice/ReplyStatus.ice Vendors upstream ReplyStatus.NotSupported.
slice/Compiler/Diagnostics.slice Adds Slice definitions for new compiler diagnostics.
slice/Compiler/CodeGenerator.slice Updates options typealias and removes legacy diagnostics from this protocol file.
slice.toml Updates sync instructions and upstream revisions for vendored Slice sources.

Comment thread src/ZeroC.Slice.Symbols/Generator.cs Outdated
Comment thread src/ZeroC.Slice.Symbols/Diagnostic.cs
Comment thread src/ZeroC.Slice.Generator/GeneratorDriver.cs
Comment thread src/IceRpc.Slice.BuildTelemetry/Program.cs
Comment thread src/ZeroC.Slice.Symbols/Diagnostic.cs Outdated
Comment thread src/ZeroC.Slice.Symbols/Diagnostic.cs Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Comment thread src/ZeroC.Slice.Generator/GeneratorDriver.cs
Comment thread src/IceRpc.Slice.BuildTelemetry/Program.cs
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was just synchronized with slicec; don't need to review it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was just synchronized with slicec; don't need to review it.

Comment thread slice/Ice/ReplyStatus.ice
["swift:identifier:invalidData"]
InvalidData,

/// The caller is not authorized to access the requested resource.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For completeness, I also updated the commit IDs for ice and icerpc-slice.
Apparently the *.ice files were slightly out of date.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires update to the C# code as well.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I will update this too while I'm at it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also create an issue to make this update in a follow-up PR.

static async Task<GeneratorResponse> BuildResponseAsync(
ImmutableList<SliceFile> symbolFiles,
Dictionary<string, string> options)
KeyValuePair<string, string>[] additionalOptions)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new mapping for the additional options you provide a plugin.

@@ -37,8 +37,8 @@ internal static List<Diagnostic> Validate(ImmutableList<SliceFile> files)

foreach (SliceFile file in files)
{
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We pass along the file-name/scoped-identifier to report it back to slicec as a DiagnosticSource.

}
}

[Test]
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was incorrectly testing that we allowed cs::attribute on variants.

Task<GeneratorResponse>
TransformAsync(ImmutableList<SliceFile> symbolFiles, KeyValuePair<string, string>[] additionalOptions)
{
// Validate CS attributes before generation.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're actually performing the C# attribute validation now!

Comment on lines 56 to +57
{
diagnostics.Add(new Diagnostic
{
Level = DiagnosticLevel.Error,
Message =
$"Multiple source files have the same file name '{fileName}': " +
$"'{previousPath}' and '{file.Path}'. " +
"Generated files are written to a common directory, so source files must have unique file names.",
});
string message = $"Multiple source files have the same file name '{fileName}': '{previousPath}' and '{file.Path}'. " +
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, this fixes the bug you had the other day @bernardnormier.

@@ -3,14 +3,67 @@
namespace ZeroC.Slice.Symbols;

/// <summary>Represents a diagnostic message produced during code generation.</summary>
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new API for Diagnostics.
This is the handwritten domain type for Symbols, not generated code.

It's no longer readonly since you can conditionally attach notes to it, further describing the error.

Comment thread src/ZeroC.Slice.Symbols/Generator.cs Outdated
count => new Dictionary<string, string>(count),
(ref decoder) => decoder.DecodeString(),
(ref decoder) => decoder.DecodeString());
KeyValuePair<string, string>[] additionalOptions = decoder.DecodeSequence((ref decoder) =>
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I settled on KeyValuePair, since that's the correct semantics here, and I used an array since that's what we used for the SliceFile arguments.

If there's a better type for me to use here, please let me know!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would either define a new struct in Symbols or use a tuple with named fields.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to (string key, string value).

@InsertCreativityHere InsertCreativityHere marked this pull request as ready for review May 22, 2026 18:35
Comment on lines +19 to +23
{
Kind = new Compiler.DiagnosticKind.Error(message),
Source = source,
Notes = [],
};
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this style confusing, I would indent this, to better distinguish from a

Suggested change
{
Kind = new Compiler.DiagnosticKind.Error(message),
Source = source,
Notes = [],
};
{
Kind = new Compiler.DiagnosticKind.Error(message),
Source = source,
Notes = [],
};

and same for others below.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix!
My knowledge about C# formatting has definitely been degraded over the years...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.Net format complains about the indented syntax and tells me to dedent it:
https://github.com/icerpc/icerpc-csharp/actions/runs/26453087442/job/77879180269?pr=4615

// TODO: enable validation once slicec correctly handles the diagnostics reported by the
// generators.
var diagnostics = new List<Diagnostic>();
List<Diagnostic> diagnostics = CsAttributeValidator.Validate(symbolFiles);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assigned #4498 to you, given that you already fixed it here!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, I didn't even see it yet! 😆
Should really look through the remaining audits sometime.

Comment thread slice/Ice/ReplyStatus.ice
["swift:identifier:invalidData"]
InvalidData,

/// The caller is not authorized to access the requested resource.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires update to the C# code as well.

Comment thread src/ZeroC.Slice.Symbols/Generator.cs Outdated
count => new Dictionary<string, string>(count),
(ref decoder) => decoder.DecodeString(),
(ref decoder) => decoder.DecodeString());
KeyValuePair<string, string>[] additionalOptions = decoder.DecodeSequence((ref decoder) =>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would either define a new struct in Symbols or use a tuple with named fields.

Copy link
Copy Markdown
Member

@externl externl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

Comment thread slice/Ice/ReplyStatus.ice
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is better to do this in its own PR, seems totally unrelated.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I undid this and will redo it in my next PR.

But I'm not sure if I agree with the premise. It feels safer to pro-actively sync Slice sources to catch things like here where NotSupported seems to of been forgotten. If every PR only updates the minimum sources it needs, I worry we will never properly synchronize these files and things will fall out of alignment.

Maybe there's a way to update our vendored files action to better warn us about when files get out of sync?
As it stands right now, the verify check doesn't seem very useful to me TBH.

@InsertCreativityHere InsertCreativityHere changed the title Use new Slice-Compiler-Definition Diagnostics Use new Slice-Compiler-Definitions (Mostly Diagnostics) May 26, 2026
@InsertCreativityHere InsertCreativityHere merged commit e185631 into icerpc:main May 26, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants