Skip to content

Commit e573aab

Browse files
authored
fix(rosetta): python identifiers mishandle identifier translations with capital letters (#4644)
Fixes aws/aws-cdk#29138 Our python translation currently translates `sizeInMBs` to `size_in_mbs` for the python examples. However, the actual property is named `size_in_m_bs`. This is because we are currently handling identifiers with the regex `[^A-Z][A-Z]`, which misses the `MB` pair. I cannot see a use case where we would want to handle _identifiers_ this way (as opposed to interface names ala `IInterface`), so I've changed the logic. --- By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache 2.0 license]. [Apache 2.0 license]: https://www.apache.org/licenses/LICENSE-2.0
1 parent a71b0ee commit e573aab

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

packages/jsii-rosetta/lib/languages/python.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export class PythonVisitor extends DefaultVisitor<PythonLanguageContext> {
111111
* Bump this when you change something in the implementation to invalidate
112112
* existing cached translations.
113113
*/
114-
public static readonly VERSION = '2';
114+
public static readonly VERSION = '3';
115115

116116
public readonly language = TargetLanguage.PYTHON;
117117
public readonly defaultContext = {};
@@ -818,7 +818,7 @@ function mangleIdentifier(originalIdentifier: string) {
818818
return originalIdentifier;
819819
}
820820
// Turn into snake-case
821-
const cased = originalIdentifier.replace(/[^A-Z][A-Z]/g, (m) => `${m[0].slice(0, 1)}_${m.slice(1).toLowerCase()}`);
821+
const cased = originalIdentifier.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`);
822822
return IDENTIFIER_KEYWORDS.includes(cased) ? `${cased}_` : cased;
823823
}
824824

packages/jsii-rosetta/test/translate.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,33 @@ test('declarations are translated correctly in all jsii languages', () => {
218218
assembly.cleanup();
219219
}
220220
});
221+
222+
test('handling capital letters in identifiers', () => {
223+
// Create an assembly in a temp directory
224+
const assembly = TestJsiiModule.fromSource(
225+
{
226+
'index.ts': `
227+
export interface InterfaceA {
228+
readonly sizeInMBs: Number;
229+
}
230+
`,
231+
},
232+
{
233+
name: 'my_assembly',
234+
jsii: DUMMY_JSII_CONFIG,
235+
},
236+
);
237+
try {
238+
const ts = assembly.translateHere(
239+
["import * as masm from 'my_assembly';", 'declare let intA: masm.InterfaceA;', 'intA = { sizeInMBs: 3 };'].join('\n'),
240+
);
241+
242+
expect(ts.get(TargetLanguage.PYTHON)?.source).toEqual(
243+
['import example_test_demo as masm', '# int_a: masm.InterfaceA', 'int_a = masm.InterfaceA(size_in_m_bs=3)'].join('\n'),
244+
);
245+
expect(ts.get(TargetLanguage.JAVA)?.source).toEqual(['import example.test.demo.*;', 'InterfaceA intA;', 'intA = InterfaceA.builder().sizeInMBs(3).build();'].join('\n'));
246+
expect(ts.get(TargetLanguage.CSHARP)?.source).toEqual(['using Example.Test.Demo;', 'InterfaceA intA;', 'intA = new InterfaceA { SizeInMBs = 3 };'].join('\n'));
247+
} finally {
248+
assembly.cleanup();
249+
}
250+
});

0 commit comments

Comments
 (0)