From af5ad70b277e88cccbea61e8d15b97ecc529b907 Mon Sep 17 00:00:00 2001 From: Travis Prescott Date: Wed, 18 Oct 2023 10:06:12 -0700 Subject: [PATCH] Update targets for Versioning decorators (#2580) Fix #2497. Clarifies which TypeSpec types these decorators can _actually_ be used on by-design. **BREAKING CHANGE** This is a breaking change because if unsupported elements were previously decorated with these (i.e. Namespaces) those will now throw an error. --- ...ioning-narrowTargets_2023-10-17-21-22.json | 10 +++ .../versioning/reference/decorators.md | 10 +-- packages/versioning/README.md | 10 +-- packages/versioning/lib/decorators.tsp | 47 ++++++++++++-- packages/versioning/src/versioning.ts | 65 ++++++++++++++++--- 5 files changed, 117 insertions(+), 25 deletions(-) create mode 100644 common/changes/@typespec/versioning/versioning-narrowTargets_2023-10-17-21-22.json diff --git a/common/changes/@typespec/versioning/versioning-narrowTargets_2023-10-17-21-22.json b/common/changes/@typespec/versioning/versioning-narrowTargets_2023-10-17-21-22.json new file mode 100644 index 0000000000..090f6f6544 --- /dev/null +++ b/common/changes/@typespec/versioning/versioning-narrowTargets_2023-10-17-21-22.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@typespec/versioning", + "comment": "Update targets for `@added`, `@removed`, `@renamedFrom`, `@madeOptional` and `@typeChangedFrom` to more clearly communicate where they can be used.", + "type": "none" + } + ], + "packageName": "@typespec/versioning" +} \ No newline at end of file diff --git a/docs/standard-library/versioning/reference/decorators.md b/docs/standard-library/versioning/reference/decorators.md index a9e9040218..1f752c8b5a 100644 --- a/docs/standard-library/versioning/reference/decorators.md +++ b/docs/standard-library/versioning/reference/decorators.md @@ -18,7 +18,7 @@ Identifies when the target was added. #### Target -`(intrinsic) unknown` +`union Model | ModelProperty | Operation | Enum | EnumMember | Union | UnionVariant | Scalar | Interface` #### Parameters @@ -53,7 +53,7 @@ Identifies when a target was made optional. #### Target -`(intrinsic) unknown` +`ModelProperty` #### Parameters @@ -82,7 +82,7 @@ Identifies when the target was removed. #### Target -`(intrinsic) unknown` +`union Model | ModelProperty | Operation | Enum | EnumMember | Union | UnionVariant | Scalar | Interface` #### Parameters @@ -117,7 +117,7 @@ Identifies when the target has been renamed. #### Target -`(intrinsic) unknown` +`union Model | ModelProperty | Operation | Enum | EnumMember | Union | UnionVariant | Scalar | Interface` #### Parameters @@ -162,7 +162,7 @@ Identifies when the target type changed. #### Target -`(intrinsic) unknown` +`ModelProperty` #### Parameters diff --git a/packages/versioning/README.md b/packages/versioning/README.md index d775c43330..22d0b9eca8 100644 --- a/packages/versioning/README.md +++ b/packages/versioning/README.md @@ -67,7 +67,7 @@ Identifies when the target was added. ##### Target -`(intrinsic) unknown` +`union Model | ModelProperty | Operation | Enum | EnumMember | Union | UnionVariant | Scalar | Interface` ##### Parameters @@ -102,7 +102,7 @@ Identifies when a target was made optional. ##### Target -`(intrinsic) unknown` +`ModelProperty` ##### Parameters @@ -131,7 +131,7 @@ Identifies when the target was removed. ##### Target -`(intrinsic) unknown` +`union Model | ModelProperty | Operation | Enum | EnumMember | Union | UnionVariant | Scalar | Interface` ##### Parameters @@ -166,7 +166,7 @@ Identifies when the target has been renamed. ##### Target -`(intrinsic) unknown` +`union Model | ModelProperty | Operation | Enum | EnumMember | Union | UnionVariant | Scalar | Interface` ##### Parameters @@ -211,7 +211,7 @@ Identifies when the target type changed. ##### Target -`(intrinsic) unknown` +`ModelProperty` ##### Parameters diff --git a/packages/versioning/lib/decorators.tsp b/packages/versioning/lib/decorators.tsp index ef0239b48b..e8b8d42929 100644 --- a/packages/versioning/lib/decorators.tsp +++ b/packages/versioning/lib/decorators.tsp @@ -71,7 +71,19 @@ namespace TypeSpec { * } * ``` */ - extern dec added(target: unknown, version: EnumMember); + extern dec added( + target: + | Model + | ModelProperty + | Operation + | Enum + | EnumMember + | Union + | UnionVariant + | Scalar + | Interface, + version: EnumMember + ); /** * Identifies when the target was removed. @@ -93,7 +105,19 @@ namespace TypeSpec { * } * ``` */ - extern dec removed(target: unknown, version: EnumMember); + extern dec removed( + target: + | Model + | ModelProperty + | Operation + | Enum + | EnumMember + | Union + | UnionVariant + | Scalar + | Interface, + version: EnumMember + ); /** * Identifies when the target has been renamed. @@ -106,7 +130,20 @@ namespace TypeSpec { * op newName(): void; * ``` */ - extern dec renamedFrom(target: unknown, version: EnumMember, oldName: valueof string); + extern dec renamedFrom( + target: + | Model + | ModelProperty + | Operation + | Enum + | EnumMember + | Union + | UnionVariant + | Scalar + | Interface, + version: EnumMember, + oldName: valueof string + ); /** * Identifies when a target was made optional. @@ -122,14 +159,14 @@ namespace TypeSpec { * } * ``` */ - extern dec madeOptional(target: unknown, version: EnumMember); + extern dec madeOptional(target: ModelProperty, version: EnumMember); /** * Identifies when the target type changed. * @param version The version that the target type changed in. * @param oldType The previous type of the target. */ - extern dec typeChangedFrom(target: unknown, version: EnumMember, oldType: unknown); + extern dec typeChangedFrom(target: ModelProperty, version: EnumMember, oldType: unknown); /** * Identifies when the target type changed. diff --git a/packages/versioning/src/versioning.ts b/packages/versioning/src/versioning.ts index 8ebf12a27a..ae7a2155d2 100644 --- a/packages/versioning/src/versioning.ts +++ b/packages/versioning/src/versioning.ts @@ -4,14 +4,19 @@ import { Enum, EnumMember, getNamespaceFullName, + Model, ModelProperty, Namespace, ObjectType, Operation, Program, ProjectionApplication, + Scalar, Type, + Union, + UnionVariant, } from "@typespec/compiler"; +import { Interface } from "readline"; import { createStateSymbol, reportDiagnostic } from "./lib.js"; import { Version, VersionResolution } from "./types.js"; import { TimelineMoment, VersioningTimeline } from "./versioning-timeline.js"; @@ -46,7 +51,20 @@ function checkIsVersion( return version; } -export function $added(context: DecoratorContext, t: Type, v: EnumMember) { +export function $added( + context: DecoratorContext, + t: + | Model + | ModelProperty + | Operation + | Enum + | EnumMember + | Union + | UnionVariant + | Scalar + | Interface, + v: EnumMember +) { const { program } = context; const version = checkIsVersion(context.program, v, context.getArgumentTarget(0)!); @@ -55,15 +73,28 @@ export function $added(context: DecoratorContext, t: Type, v: EnumMember) { } // retrieve statemap to update or create a new one - const record = program.stateMap(addedOnKey).get(t) ?? new Array(); + const record = program.stateMap(addedOnKey).get(t as Type) ?? new Array(); record.push(version); // ensure that records are stored in ascending order (record as Version[]).sort((a, b) => a.index - b.index); - program.stateMap(addedOnKey).set(t, record); + program.stateMap(addedOnKey).set(t as Type, record); } -export function $removed(context: DecoratorContext, t: Type, v: EnumMember) { +export function $removed( + context: DecoratorContext, + t: + | Model + | ModelProperty + | Operation + | Enum + | EnumMember + | Union + | UnionVariant + | Scalar + | Interface, + v: EnumMember +) { const { program } = context; const version = checkIsVersion(context.program, v, context.getArgumentTarget(0)!); @@ -72,12 +103,12 @@ export function $removed(context: DecoratorContext, t: Type, v: EnumMember) { } // retrieve statemap to update or create a new one - const record = program.stateMap(removedOnKey).get(t) ?? new Array(); + const record = program.stateMap(removedOnKey).get(t as Type) ?? new Array(); record.push(version); // ensure that records are stored in ascending order (record as Version[]).sort((a, b) => a.index - b.index); - program.stateMap(removedOnKey).set(t, record); + program.stateMap(removedOnKey).set(t as Type, record); } /** @@ -147,7 +178,21 @@ interface RenamedFrom { oldName: string; } -export function $renamedFrom(context: DecoratorContext, t: Type, v: EnumMember, oldName: string) { +export function $renamedFrom( + context: DecoratorContext, + t: + | Model + | ModelProperty + | Operation + | Enum + | EnumMember + | Union + | UnionVariant + | Scalar + | Interface, + v: EnumMember, + oldName: string +) { const { program } = context; const version = checkIsVersion(context.program, v, context.getArgumentTarget(0)!); if (!version) { @@ -157,17 +202,17 @@ export function $renamedFrom(context: DecoratorContext, t: Type, v: EnumMember, if (oldName === "") { reportDiagnostic(program, { code: "invalid-renamed-from-value", - target: t, + target: t as Type, }); } // retrieve statemap to update or create a new one - const record = getRenamedFrom(program, t) ?? []; + const record = getRenamedFrom(program, t as Type) ?? []; record.push({ version: version, oldName: oldName }); // ensure that records are stored in ascending order record.sort((a, b) => a.version.index - b.version.index); - program.stateMap(renamedFromKey).set(t, record); + program.stateMap(renamedFromKey).set(t as Type, record); } export function $madeOptional(context: DecoratorContext, t: ModelProperty, v: EnumMember) {