Skip to content

Commit 979fc78

Browse files
authored
Adding call signature customization support. (Azure#27653)
### Packages impacted by this PR dev-tool ### Issues associated with this PR This change adds support for customizing interface call signatures. It also fixes an issue with the property removal functionality. ### Describe the problem that is addressed by this PR ### What are the possible designs available to address the problem? If there are more than one possible design, why was the one in this PR chosen? ### Are there test cases added in this PR? _(If not, why?)_ ### Provide a list of related PRs _(if any)_ ### Command used to generate this PR:**_(Applicable only to SDK release request PRs)_ ### Checklists - [ ] Added impacted package name to the issue description - [ ] Does this PR needs any fixes in the SDK Generator?** _(If so, create an Issue in the [Autorest/typescript](https://github.com/Azure/autorest.typescript) repository and link it here)_ - [ ] Added a changelog (if necessary)
1 parent 2719dcf commit 979fc78

File tree

2 files changed

+78
-5
lines changed

2 files changed

+78
-5
lines changed

common/tools/dev-tool/src/util/customization/helpers/annotations.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT license
33

4-
import { PropertySignature } from "ts-morph";
4+
import { CallSignatureDeclaration, PropertySignature } from "ts-morph";
55
import { Declaration } from "../common";
66

77
export type Annotation = "Remove";
88
export function getAnnotation(
9-
declaration: Declaration | PropertySignature
9+
declaration: Declaration | PropertySignature | CallSignatureDeclaration
1010
): Annotation | undefined {
1111
// Check if the property has a `// @azsdk-remove` comment
1212
const leadingCommentRanges = declaration.getLeadingCommentRanges();
@@ -21,8 +21,7 @@ export function getAnnotation(
2121
if (annotation === "@azsdk-remove") {
2222
return "Remove";
2323
}
24-
25-
return undefined;
2624
}
2725
}
26+
return undefined;
2827
}

common/tools/dev-tool/src/util/customization/interfaces.ts

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT license
33

4-
import { InterfaceDeclaration, SourceFile } from "ts-morph";
4+
import { CallSignatureDeclaration, InterfaceDeclaration, SourceFile, Type } from "ts-morph";
55
import { getAnnotation } from "./helpers/annotations";
66

77
export function augmentInterfaces(
@@ -31,6 +31,12 @@ export function augmentInterface(
3131

3232
// Merge the properties from the custom interface into the original interface
3333
mergeProperties(customInterface, originalInterface);
34+
35+
// Remove any call signatures marked with // @azsdk-remove
36+
removeCallSignatures(customInterface, originalInterface);
37+
38+
// Merge the call signatures from the custom interface into the original interface
39+
mergeCallSignatures(customInterface, originalInterface);
3440
}
3541

3642
export function mergeProperties(
@@ -39,6 +45,10 @@ export function mergeProperties(
3945
) {
4046
const customProperties = customInterface.getProperties();
4147
for (const customProperty of customProperties) {
48+
if (getAnnotation(customProperty) === "Remove") {
49+
/* If the property has a `// @azsdk-remove` comment, we don't need to re-add it */
50+
continue;
51+
}
4252
const propertyName = customProperty.getName();
4353
const originalProperty = originalInterface.getProperty(propertyName);
4454

@@ -68,3 +78,67 @@ export function removeProperties(
6878
}
6979
}
7080
}
81+
82+
function findCallSignature(
83+
interfaceDeclaration: InterfaceDeclaration,
84+
callSignature: CallSignatureDeclaration
85+
): CallSignatureDeclaration | undefined {
86+
function typeEquals(a: Type, b: Type) {
87+
// Need to handle cases where the type is imported
88+
const aStr = a?.getText()?.replace(/import\(\".+\"\)\./, "");
89+
const bStr = b?.getText()?.replace(/import\(\".+\"\)\./, "");
90+
return aStr && bStr && aStr === bStr;
91+
}
92+
return interfaceDeclaration.getCallSignature((signature) => {
93+
if (signature.getParameters().length !== callSignature.getParameters().length) {
94+
return false;
95+
}
96+
signature.getReturnTypeNode;
97+
if (!typeEquals(signature.getReturnType(), callSignature.getReturnType())) {
98+
return false;
99+
}
100+
101+
for (let i = 0; i < signature.getParameters().length; i++) {
102+
if (
103+
!typeEquals(
104+
signature.getParameters()[i].getType(),
105+
callSignature.getParameters()[i].getType()
106+
)
107+
) {
108+
return false;
109+
}
110+
}
111+
return true;
112+
});
113+
}
114+
115+
export function mergeCallSignatures(
116+
customInterface: InterfaceDeclaration,
117+
originalInterface: InterfaceDeclaration
118+
) {
119+
const customCallSignatures = customInterface.getCallSignatures();
120+
for (const customCallSignature of customCallSignatures) {
121+
if (getAnnotation(customCallSignature) === "Remove") {
122+
/* If the call signature has a `// @azsdk-remove` comment, we don't need to re-add it */
123+
continue;
124+
}
125+
const originalCallSignature = findCallSignature(originalInterface, customCallSignature);
126+
if (originalCallSignature) {
127+
originalCallSignature.remove();
128+
}
129+
originalInterface.addCallSignature(customCallSignature.getStructure());
130+
}
131+
}
132+
133+
export function removeCallSignatures(
134+
customInterface: InterfaceDeclaration,
135+
originalInterface: InterfaceDeclaration
136+
) {
137+
const customCallSignatures = customInterface.getCallSignatures();
138+
for (const customCallSignature of customCallSignatures) {
139+
// Check if the signature has a `// @azsdk-remove` comment
140+
if (getAnnotation(customCallSignature) === "Remove") {
141+
findCallSignature(originalInterface, customCallSignature)?.remove();
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)