Skip to content

Commit ed0bf16

Browse files
authored
Convert type literal arguments in interface method signatures (#67)
1 parent 7a406a8 commit ed0bf16

File tree

2 files changed

+75
-21
lines changed

2 files changed

+75
-21
lines changed

type-generation/src/astToIR.ts

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -754,9 +754,12 @@ export class Converter {
754754
for (const param of decl.getParameters()) {
755755
const spread = !!param.getDotDotDotToken();
756756
const optional = !!param.hasQuestionToken();
757+
const name = param.getName();
758+
this.pushNameContext(name);
757759
const type = this.typeToIR(param.getTypeNode()!, optional);
760+
this.popNameContext();
758761
const pyParam: ParamIR = {
759-
name: param.getName(),
762+
name,
760763
type,
761764
isOptional: optional,
762765
};
@@ -896,7 +899,14 @@ export class Converter {
896899
signatures: Signature[],
897900
isStatic?: boolean,
898901
): CallableIR {
899-
const sigs = signatures.flatMap((sig) => this.sigToIRDestructure(sig));
902+
this.pushNameContext(name);
903+
const sigs = signatures.flatMap((sig, idx) => {
904+
this.pushNameContext(`Sig${idx}`);
905+
const result = this.sigToIRDestructure(sig);
906+
this.popNameContext();
907+
return result;
908+
});
909+
this.popNameContext();
900910

901911
const result: CallableIR = {
902912
kind: "callable",
@@ -1091,25 +1101,25 @@ export class Converter {
10911101
const typeArgs = typeParams.map((param) => simpleType(param));
10921102
const concreteBases = [{ name: ifaceName, typeArgs }];
10931103
const constructors = classDecl.getConstructors();
1094-
1095-
return [
1096-
this.interfaceToIR(
1097-
ifaceName,
1098-
bases,
1099-
[...methods, ...properties],
1100-
[],
1101-
[],
1102-
typeParams,
1103-
),
1104-
this.interfaceToIR(
1105-
name,
1106-
concreteBases,
1107-
[],
1108-
[...constructors, ...staticMethods, ...staticProperties],
1109-
[],
1110-
typeParams,
1111-
),
1112-
];
1104+
this.nameContext = [name];
1105+
const ifaceIR = this.interfaceToIR(
1106+
ifaceName,
1107+
bases,
1108+
[...methods, ...properties],
1109+
[],
1110+
[],
1111+
typeParams,
1112+
);
1113+
const concreteIR = this.interfaceToIR(
1114+
name,
1115+
concreteBases,
1116+
[],
1117+
[...constructors, ...staticMethods, ...staticProperties],
1118+
[],
1119+
typeParams,
1120+
);
1121+
this.nameContext = undefined;
1122+
return [ifaceIR, concreteIR];
11131123
}
11141124

11151125
getBasesOfDecls(

type-generation/tests/a.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,50 @@ describe("emit", () => {
17971797
`).trim(),
17981798
);
17991799
});
1800+
describe("type literals", () => {
1801+
it("type literal in class property", () => {
1802+
const res = emitFile(`
1803+
declare class T {
1804+
a: {x: string, y: boolean};
1805+
}
1806+
`);
1807+
assert.strictEqual(
1808+
removeTypeIgnores(res.slice(1).join("\n\n")),
1809+
dedent(`
1810+
class T_iface(Protocol):
1811+
a: T__a_iface = ...
1812+
1813+
class T(T_iface, _JsObject):
1814+
pass
1815+
1816+
class T__a_iface(Protocol):
1817+
x: str = ...
1818+
y: bool = ...
1819+
`).trim(),
1820+
);
1821+
});
1822+
it("type literal in class method signature", () => {
1823+
const res = emitFile(`
1824+
declare class T {
1825+
f(a: {x: string, y: boolean}, b: boolean): void;
1826+
}
1827+
`);
1828+
assert.strictEqual(
1829+
removeTypeIgnores(res.slice(1).join("\n\n")),
1830+
dedent(`
1831+
class T_iface(Protocol):
1832+
def f(self, a: T__f__Sig0__a_iface, b: bool, /) -> None: ...
1833+
1834+
class T(T_iface, _JsObject):
1835+
pass
1836+
1837+
class T__f__Sig0__a_iface(Protocol):
1838+
x: str = ...
1839+
y: bool = ...
1840+
`).trim(),
1841+
);
1842+
});
1843+
});
18001844
describe("adjustments", () => {
18011845
it("setTimeout", () => {
18021846
const res = emitIRNoTypeIgnores(convertBuiltinFunction("setTimeout"));

0 commit comments

Comments
 (0)