Skip to content

Commit 5c0fec1

Browse files
stephentoubCopilot
andauthored
Hide deprecated APIs where supported (#1293)
Add EditorBrowsable(Never) to generated and hand-authored C# deprecated APIs, and add doc(hidden) to generated Rust deprecated APIs so they are hidden from rustdoc while remaining deprecated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 74d12ed commit 5c0fec1

5 files changed

Lines changed: 54 additions & 20 deletions

File tree

dotnet/src/Generated/SessionEvents.cs

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dotnet/src/Types.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ protected CopilotClientOptions(CopilotClientOptions? other)
157157
/// <summary>
158158
/// Obsolete. This option has no effect.
159159
/// </summary>
160+
[EditorBrowsable(EditorBrowsableState.Never)]
160161
[Obsolete("AutoRestart has no effect and will be removed in a future release.")]
161162
public bool AutoRestart { get; set; }
162163
/// <summary>
@@ -537,14 +538,17 @@ public class ToolInvocation
537538
public static PermissionRequestResultKind NoResult { get; } = new("no-result");
538539

539540
/// <summary>Deprecated. Use <see cref="Rejected"/> instead.</summary>
541+
[EditorBrowsable(EditorBrowsableState.Never)]
540542
[Obsolete("Use Rejected instead.")]
541543
public static PermissionRequestResultKind DeniedInteractivelyByUser => Rejected;
542544

543545
/// <summary>Deprecated. Use <see cref="UserNotAvailable"/> instead.</summary>
546+
[EditorBrowsable(EditorBrowsableState.Never)]
544547
[Obsolete("Use UserNotAvailable instead.")]
545548
public static PermissionRequestResultKind DeniedCouldNotRequestFromUser => UserNotAvailable;
546549

547550
/// <summary>Deprecated. Use <see cref="UserNotAvailable"/> instead.</summary>
551+
[EditorBrowsable(EditorBrowsableState.Never)]
548552
[Obsolete("Use UserNotAvailable instead.")]
549553
public static PermissionRequestResultKind DeniedByRules => UserNotAvailable;
550554

rust/src/generated/session_events.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,7 @@ pub struct AssistantMessageData {
11191119
#[serde(skip_serializing_if = "Option::is_none")]
11201120
pub output_tokens: Option<f64>,
11211121
/// Tool call ID of the parent tool invocation when this event originates from a sub-agent
1122+
#[doc(hidden)]
11221123
#[deprecated]
11231124
#[serde(skip_serializing_if = "Option::is_none")]
11241125
pub parent_tool_call_id: Option<String>,
@@ -1162,6 +1163,7 @@ pub struct AssistantMessageDeltaData {
11621163
/// Message ID this delta belongs to, matching the corresponding assistant.message event
11631164
pub message_id: String,
11641165
/// Tool call ID of the parent tool invocation when this event originates from a sub-agent
1166+
#[doc(hidden)]
11651167
#[deprecated]
11661168
#[serde(skip_serializing_if = "Option::is_none")]
11671169
pub parent_tool_call_id: Option<String>,
@@ -1261,6 +1263,7 @@ pub struct AssistantUsageData {
12611263
#[serde(skip_serializing_if = "Option::is_none")]
12621264
pub output_tokens: Option<f64>,
12631265
/// Parent tool call ID when this usage originates from a sub-agent
1266+
#[doc(hidden)]
12641267
#[deprecated]
12651268
#[serde(skip_serializing_if = "Option::is_none")]
12661269
pub parent_tool_call_id: Option<String>,
@@ -1345,6 +1348,7 @@ pub struct ToolExecutionStartData {
13451348
#[serde(skip_serializing_if = "Option::is_none")]
13461349
pub mcp_tool_name: Option<String>,
13471350
/// Tool call ID of the parent tool invocation when this event originates from a sub-agent
1351+
#[doc(hidden)]
13481352
#[deprecated]
13491353
#[serde(skip_serializing_if = "Option::is_none")]
13501354
pub parent_tool_call_id: Option<String>,
@@ -1547,6 +1551,7 @@ pub struct ToolExecutionCompleteData {
15471551
#[serde(skip_serializing_if = "Option::is_none")]
15481552
pub model: Option<String>,
15491553
/// Tool call ID of the parent tool invocation when this event originates from a sub-agent
1554+
#[doc(hidden)]
15501555
#[deprecated]
15511556
#[serde(skip_serializing_if = "Option::is_none")]
15521557
pub parent_tool_call_id: Option<String>,

scripts/codegen/csharp.ts

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ const COPYRIGHT = `/*-----------------------------------------------------------
355355
*--------------------------------------------------------------------------------------------*/`;
356356

357357
const EXPERIMENTAL_ATTRIBUTE = "[Experimental(Diagnostics.Experimental)]";
358+
const EDITOR_BROWSABLE_NEVER_ATTRIBUTE = "[EditorBrowsable(EditorBrowsableState.Never)]";
358359
const OBSOLETE_ATTRIBUTE = `[Obsolete("This member is deprecated and will be removed in a future version.")]`;
359360
const STRING_ENUM_RESERVED_MEMBER_NAMES = new Set(["Value", "Equals", "GetHashCode", "ToString", "Converter"]);
360361

@@ -366,6 +367,21 @@ function pushExperimentalAttribute(lines: string[], indent = ""): void {
366367
lines.push(experimentalAttribute(indent));
367368
}
368369

370+
function obsoleteAttributes(indent = ""): string[] {
371+
return [
372+
`${indent}${EDITOR_BROWSABLE_NEVER_ATTRIBUTE}`,
373+
`${indent}${OBSOLETE_ATTRIBUTE}`,
374+
];
375+
}
376+
377+
function obsoleteAttributeBlock(indent = ""): string {
378+
return obsoleteAttributes(indent).join("\n");
379+
}
380+
381+
function pushObsoleteAttributes(lines: string[], indent = ""): void {
382+
lines.push(...obsoleteAttributes(indent));
383+
}
384+
369385
// ══════════════════════════════════════════════════════════════════════════════
370386
// SESSION EVENTS
371387
// ══════════════════════════════════════════════════════════════════════════════
@@ -404,7 +420,7 @@ function getOrCreateEnum(
404420
const lines: string[] = [];
405421
lines.push(...xmlDocEnumComment(description, ""));
406422
if (experimental) pushExperimentalAttribute(lines);
407-
if (deprecated) lines.push(OBSOLETE_ATTRIBUTE);
423+
if (deprecated) pushObsoleteAttributes(lines);
408424
lines.push(`[JsonConverter(typeof(Converter))]`);
409425
lines.push(`[DebuggerDisplay("{Value,nq}")]`);
410426
lines.push(`public readonly struct ${enumName} : IEquatable<${enumName}>`);
@@ -616,7 +632,7 @@ function generateFlattenedBooleanDiscriminatedClass(
616632
lines.push("");
617633
lines.push(...xmlDocPropertyComment(info.schema.description, propName, " "));
618634
lines.push(...emitDataAnnotations(info.schema, " "));
619-
if (isSchemaDeprecated(info.schema)) lines.push(` ${OBSOLETE_ATTRIBUTE}`);
635+
if (isSchemaDeprecated(info.schema)) pushObsoleteAttributes(lines, " ");
620636
if (isDurationProperty(info.schema)) lines.push(` [JsonConverter(typeof(MillisecondsTimeSpanConverter))]`);
621637
if (!isReq) lines.push(` [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]`);
622638
lines.push(` [JsonPropertyName("${propName}")]`);
@@ -696,7 +712,7 @@ function generateDerivedClass(
696712

697713
lines.push(...xmlDocCommentWithFallback(schema.description, `The <c>${escapeXml(discriminatorValue)}</c> variant of <see cref="${baseClassName}"/>.`, ""));
698714
if (isSchemaExperimental(schema)) pushExperimentalAttribute(lines);
699-
if (isSchemaDeprecated(schema)) lines.push(OBSOLETE_ATTRIBUTE);
715+
if (isSchemaDeprecated(schema)) pushObsoleteAttributes(lines);
700716
lines.push(`public partial class ${className} : ${baseClassName}`);
701717
lines.push(`{`);
702718
lines.push(` /// <inheritdoc />`);
@@ -715,7 +731,7 @@ function generateDerivedClass(
715731

716732
lines.push(...xmlDocPropertyComment((propSchema as JSONSchema7).description, propName, " "));
717733
lines.push(...emitDataAnnotations(propSchema as JSONSchema7, " "));
718-
if (isSchemaDeprecated(propSchema as JSONSchema7)) lines.push(` ${OBSOLETE_ATTRIBUTE}`);
734+
if (isSchemaDeprecated(propSchema as JSONSchema7)) pushObsoleteAttributes(lines, " ");
719735
if (isDurationProperty(propSchema as JSONSchema7)) lines.push(` [JsonConverter(typeof(MillisecondsTimeSpanConverter))]`);
720736
if (!isReq) lines.push(` [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]`);
721737
lines.push(` [JsonPropertyName("${propName}")]`);
@@ -928,7 +944,7 @@ function generateNestedClass(
928944
const lines: string[] = [];
929945
lines.push(...xmlDocCommentWithFallback(schema.description, `Nested data type for <c>${className}</c>.`, ""));
930946
if (isSchemaExperimental(schema)) pushExperimentalAttribute(lines);
931-
if (isSchemaDeprecated(schema)) lines.push(OBSOLETE_ATTRIBUTE);
947+
if (isSchemaDeprecated(schema)) pushObsoleteAttributes(lines);
932948
lines.push(`public partial class ${className}`, `{`);
933949

934950
for (const [propName, propSchema] of Object.entries(schema.properties || {}).sort(([a], [b]) => a.localeCompare(b))) {
@@ -940,7 +956,7 @@ function generateNestedClass(
940956

941957
lines.push(...xmlDocPropertyComment(prop.description, propName, " "));
942958
lines.push(...emitDataAnnotations(prop, " "));
943-
if (isSchemaDeprecated(prop)) lines.push(` ${OBSOLETE_ATTRIBUTE}`);
959+
if (isSchemaDeprecated(prop)) pushObsoleteAttributes(lines, " ");
944960
if (isDurationProperty(prop)) lines.push(` [JsonConverter(typeof(MillisecondsTimeSpanConverter))]`);
945961
if (!isReq) lines.push(` [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]`);
946962
lines.push(` [JsonPropertyName("${propName}")]`);
@@ -1070,7 +1086,7 @@ function generateDataClass(variant: EventVariant, knownTypes: Map<string, string
10701086
pushExperimentalAttribute(lines);
10711087
}
10721088
if (isSchemaDeprecated(variant.dataSchema)) {
1073-
lines.push(OBSOLETE_ATTRIBUTE);
1089+
pushObsoleteAttributes(lines);
10741090
}
10751091
lines.push(`public partial class ${variant.dataClassName}`, `{`);
10761092

@@ -1082,7 +1098,7 @@ function generateDataClass(variant: EventVariant, knownTypes: Map<string, string
10821098

10831099
lines.push(...xmlDocPropertyComment((propSchema as JSONSchema7).description, propName, " "));
10841100
lines.push(...emitDataAnnotations(propSchema as JSONSchema7, " "));
1085-
if (isSchemaDeprecated(propSchema as JSONSchema7)) lines.push(` ${OBSOLETE_ATTRIBUTE}`);
1101+
if (isSchemaDeprecated(propSchema as JSONSchema7)) pushObsoleteAttributes(lines, " ");
10861102
if (isDurationProperty(propSchema as JSONSchema7)) lines.push(` [JsonConverter(typeof(MillisecondsTimeSpanConverter))]`);
10871103
if (!isReq) lines.push(` [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]`);
10881104
lines.push(` [JsonPropertyName("${propName}")]`);
@@ -1114,7 +1130,7 @@ function emitSessionEventEnvelopeProperty(
11141130

11151131
lines.push(...xmlDocPropertyComment(property.schema.description, property.name, " "));
11161132
lines.push(...emitDataAnnotations(property.schema, " "));
1117-
if (isSchemaDeprecated(property.schema)) lines.push(` ${OBSOLETE_ATTRIBUTE}`);
1133+
if (isSchemaDeprecated(property.schema)) pushObsoleteAttributes(lines, " ");
11181134
if (isDurationProperty(property.schema)) lines.push(` [JsonConverter(typeof(MillisecondsTimeSpanConverter))]`);
11191135
if (!property.required) lines.push(` [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]`);
11201136
lines.push(` [JsonPropertyName("${property.name}")]`);
@@ -1447,7 +1463,7 @@ function emitRpcClass(
14471463
pushExperimentalAttribute(lines);
14481464
}
14491465
if (isSchemaDeprecated(schema) || isSchemaDeprecated(effectiveSchema)) {
1450-
lines.push(OBSOLETE_ATTRIBUTE);
1466+
pushObsoleteAttributes(lines);
14511467
}
14521468
lines.push(`${visibility} sealed class ${className}`, `{`);
14531469

@@ -1462,7 +1478,7 @@ function emitRpcClass(
14621478

14631479
lines.push(...xmlDocPropertyComment(prop.description, propName, " "));
14641480
lines.push(...emitDataAnnotations(prop, " "));
1465-
if (isSchemaDeprecated(prop)) lines.push(` ${OBSOLETE_ATTRIBUTE}`);
1481+
if (isSchemaDeprecated(prop)) pushObsoleteAttributes(lines, " ");
14661482
if (isDurationProperty(prop)) lines.push(` [JsonConverter(typeof(MillisecondsTimeSpanConverter))]`);
14671483
lines.push(` [JsonPropertyName("${propName}")]`);
14681484

@@ -1562,7 +1578,7 @@ function emitServerApiClass(className: string, node: Record<string, unknown>, cl
15621578
pushExperimentalAttribute(lines);
15631579
}
15641580
if (groupDeprecated) {
1565-
lines.push(OBSOLETE_ATTRIBUTE);
1581+
pushObsoleteAttributes(lines);
15661582
}
15671583
lines.push(`public sealed class ${className}`);
15681584
lines.push(`{`);
@@ -1648,7 +1664,7 @@ function emitServerInstanceMethod(
16481664
pushExperimentalAttribute(lines, indent);
16491665
}
16501666
if (method.deprecated && !groupDeprecated) {
1651-
lines.push(`${indent}${OBSOLETE_ATTRIBUTE}`);
1667+
pushObsoleteAttributes(lines, indent);
16521668
}
16531669

16541670
const sigParams: string[] = [];
@@ -1772,7 +1788,7 @@ function emitSessionMethod(key: string, method: RpcMethod, lines: string[], clas
17721788
pushExperimentalAttribute(lines, indent);
17731789
}
17741790
if (method.deprecated && !groupDeprecated) {
1775-
lines.push(`${indent}${OBSOLETE_ATTRIBUTE}`);
1791+
pushObsoleteAttributes(lines, indent);
17761792
}
17771793
const sigParams: string[] = [];
17781794
const bodyAssignments = [`SessionId = _sessionId`];
@@ -1810,7 +1826,7 @@ function emitSessionApiClass(className: string, node: Record<string, unknown>, c
18101826
const groupExperimental = isNodeFullyExperimental(node);
18111827
const groupDeprecated = isNodeFullyDeprecated(node);
18121828
const experimentalAttr = groupExperimental ? `${experimentalAttribute()}\n` : "";
1813-
const deprecatedAttr = groupDeprecated ? `${OBSOLETE_ATTRIBUTE}\n` : "";
1829+
const deprecatedAttr = groupDeprecated ? `${obsoleteAttributeBlock()}\n` : "";
18141830
const subGroups = Object.entries(node).filter(([, v]) => typeof v === "object" && v !== null && !isRpcMethod(v));
18151831

18161832
const lines = [`/// <summary>Provides session-scoped ${displayName} APIs.</summary>`, `${experimentalAttr}${deprecatedAttr}public sealed class ${className}`, `{`, ` private readonly JsonRpc _rpc;`, ` private readonly string _sessionId;`, ""];
@@ -1895,7 +1911,7 @@ function emitClientSessionApiRegistration(clientSchema: Record<string, unknown>,
18951911
pushExperimentalAttribute(lines);
18961912
}
18971913
if (groupDeprecated) {
1898-
lines.push(OBSOLETE_ATTRIBUTE);
1914+
pushObsoleteAttributes(lines);
18991915
}
19001916
lines.push(`public interface ${interfaceName}`);
19011917
lines.push(`{`);
@@ -1909,7 +1925,7 @@ function emitClientSessionApiRegistration(clientSchema: Record<string, unknown>,
19091925
pushExperimentalAttribute(lines, " ");
19101926
}
19111927
if (method.deprecated && !groupDeprecated) {
1912-
lines.push(` ${OBSOLETE_ATTRIBUTE}`);
1928+
pushObsoleteAttributes(lines, " ");
19131929
}
19141930
if (hasParams) {
19151931
lines.push(` ${taskType} ${clientHandlerMethodName(method.rpcMethod)}(${paramsTypeName(method)} request, CancellationToken cancellationToken = default);`);

scripts/codegen/rust.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ const EXTERNAL_SCHEMA_RUST_TYPE_MODULE: Record<string, Record<string, string>> =
5858
},
5959
};
6060

61+
function rustDeprecatedAttributes(indent = ""): string[] {
62+
return [`${indent}#[doc(hidden)]`, `${indent}#[deprecated]`];
63+
}
64+
6165
/**
6266
* JSON property names that should be emitted as a hand-authored newtype rather
6367
* than `String`. The newtype is `#[serde(transparent)]`, so the wire format is
@@ -700,7 +704,7 @@ function emitRustStruct(
700704
}
701705
pushRustExperimentalDocs(lines, isSchemaExperimental(schema));
702706
if (isSchemaDeprecated(schema)) {
703-
lines.push("#[deprecated]");
707+
lines.push(...rustDeprecatedAttributes());
704708
}
705709

706710
// Resolve field types up-front so we can decide whether `Default` can be
@@ -745,7 +749,7 @@ function emitRustStruct(
745749
}
746750
}
747751
if (isSchemaDeprecated(prop)) {
748-
lines.push(" #[deprecated]");
752+
lines.push(...rustDeprecatedAttributes(" "));
749753
}
750754

751755
// Determine if an explicit rename is needed. `rename_all = "camelCase"` on
@@ -1492,7 +1496,7 @@ function emitNamespaceMethod(
14921496

14931497
const docs: string[] = [];
14941498
docs.push(` /// Wire method: \`${wireMethod}\`.`);
1495-
if (method.deprecated) docs.push(` #[deprecated]`);
1499+
if (method.deprecated) docs.push(...rustDeprecatedAttributes(" "));
14961500
const stability = method.stability;
14971501
if (stability === "experimental") {
14981502
docs.push(` ///`);

0 commit comments

Comments
 (0)