Skip to content

Commit

Permalink
Fixes #3239.
Browse files Browse the repository at this point in the history
  • Loading branch information
tjprescott committed May 22, 2024
1 parent 8c61fa3 commit 7c1374d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 27 deletions.
54 changes: 31 additions & 23 deletions packages/versioning/src/versioning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
Type,
Union,
UnionVariant,
compilerAssert,
getNamespaceFullName,
} from "@typespec/compiler";
import {
Expand Down Expand Up @@ -782,6 +781,26 @@ export enum Availability {
Removed = "Removed",
}

function getParentAddedVersion(
program: Program,
type: Type,
versions: Version[]
): Version | undefined {
let parentMap: Map<string, Availability> | undefined = undefined;
if (type.kind === "ModelProperty" && type.model !== undefined) {
parentMap = getAvailabilityMap(program, type.model);
} else if (type.kind === "Operation" && type.interface !== undefined) {
parentMap = getAvailabilityMap(program, type.interface);
}
if (parentMap === undefined) return undefined;
for (const [key, value] of parentMap.entries()) {
if (value === Availability.Added) {
return versions.find((x) => x.name === key);
}
}
return undefined;
}

export function getAvailabilityMap(
program: Program,
type: Type
Expand All @@ -792,7 +811,8 @@ export function getAvailabilityMap(
// if unversioned then everything exists
if (allVersions === undefined) return undefined;

const added = getAddedOnVersions(program, type) ?? [];
const parentAdded = getParentAddedVersion(program, type, allVersions);
let added = getAddedOnVersions(program, type) ?? [];
const removed = getRemovedOnVersions(program, type) ?? [];
const typeChanged = getTypeChangedFrom(program, type);
const returnTypeChanged = getReturnTypeChangedFrom(program, type);
Expand All @@ -807,27 +827,15 @@ export function getAvailabilityMap(
)
return undefined;

let parentMap: Map<string, Availability> | undefined = undefined;
if (type.kind === "ModelProperty" && type.model !== undefined) {
parentMap = getAvailabilityMap(program, type.model);
} else if (type.kind === "Operation" && type.interface !== undefined) {
parentMap = getAvailabilityMap(program, type.interface);
}

// implicitly, all versioned things are assumed to have been added at
// v1 if not specified
if (!added.length) {
if (parentMap !== undefined) {
parentMap.forEach((key, value) => {
if (key === Availability.Added.valueOf()) {
const match = allVersions.find((x) => x.name === value);
compilerAssert(match !== undefined, "Version not found");
added.push(match);
}
});
} else {
added.push(allVersions[0]);
}
if (!added.length && !parentAdded) {
// no version information on the item or its parent implicitly means it has always been available
added.push(allVersions[0]);
} else if (!added.length && parentAdded) {
// if no version info on type but is on parent, inherit that parent's "added" version
added.push(parentAdded);
} else if (added.length && parentAdded) {
// if "added" info on both the type and parent, combine them
added = [parentAdded, ...added];
}

// something isn't available by default
Expand Down
13 changes: 9 additions & 4 deletions packages/versioning/test/versioning.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,14 +289,16 @@ describe("versioning: logic", () => {
`@added(Versions.v2)
model Test {
a: int32;
@removed(Versions.v3) b: int32;
@removed(Versions.v3)
@added(Versions.v4)
b: int32;
}
`
);

assertHasProperties(v2, ["a", "b"]);
assertHasProperties(v3, ["a"]);
assertHasProperties(v4, ["a"]);
assertHasProperties(v4, ["a", "b"]);

assertModelProjectsTo(
[
Expand Down Expand Up @@ -1402,12 +1404,15 @@ describe("versioning: logic", () => {
`@added(Versions.v2)
interface Test {
allVersions(): void;
@removed(Versions.v3) version2Only(): void;
@removed(Versions.v3)
@added(Versions.v4)
foo(): void;
}
`
);
assertHasOperations(v2, ["allVersions", "version2Only"]);
assertHasOperations(v2, ["allVersions", "foo"]);
assertHasOperations(v3, ["allVersions"]);
assertHasOperations(v4, ["allVersions", "foo"]);
assertInterfaceProjectsTo(
[
[v2, "v2"],
Expand Down

0 comments on commit 7c1374d

Please sign in to comment.