From 61747b6727a1536cbf8dde58e4253c29634b63e6 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 19 Nov 2021 14:16:50 +0100 Subject: [PATCH] fix(rosetta): enum resolution breaks for properties On some examples in the CDK repository, Rosetta breaks in the `resolveEnumLiteral()` function. The error is `Cannot read property 'kind' of undefined` and occurs somewhere deep in the call stack of TypeScript. It occurs when an enum is being passed as a struct property. --- packages/jsii-rosetta/lib/jsii/jsii-utils.ts | 3 +- .../jsii-rosetta/test/jsii-imports.test.ts | 43 ++++++++++++++++++- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/packages/jsii-rosetta/lib/jsii/jsii-utils.ts b/packages/jsii-rosetta/lib/jsii/jsii-utils.ts index e6f530ee8e..4bd417273e 100644 --- a/packages/jsii-rosetta/lib/jsii/jsii-utils.ts +++ b/packages/jsii-rosetta/lib/jsii/jsii-utils.ts @@ -223,8 +223,7 @@ export function resolveEnumLiteral(typeChecker: ts.TypeChecker, type: ts.Type) { return type; } - const parentDeclaration = type.symbol.declarations?.[0]?.parent; - return fmap(parentDeclaration, typeChecker.getTypeAtLocation) ?? type; + return typeChecker.getBaseTypeOfLiteralType(type); } export function resolvedSymbolAtLocation(typeChecker: ts.TypeChecker, node: ts.Node) { diff --git a/packages/jsii-rosetta/test/jsii-imports.test.ts b/packages/jsii-rosetta/test/jsii-imports.test.ts index 67aec7f362..2d8b9863b3 100644 --- a/packages/jsii-rosetta/test/jsii-imports.test.ts +++ b/packages/jsii-rosetta/test/jsii-imports.test.ts @@ -196,7 +196,14 @@ describe('no submodule', () => { beforeAll(async () => { module = await TestJsiiModule.fromSource( { - 'index.ts': `export enum MyEnum { OPTION_A = 'a', OPTION_B = 'b' }`, + 'index.ts': `export enum MyEnum { OPTION_A = 'a', OPTION_B = 'b' } + + export interface MyProps { readonly prop: MyEnum } + + export function myFun(props: MyProps) { + Array.isArray(props); + } + `, }, { name: 'my_assembly', @@ -273,6 +280,40 @@ describe('no submodule', () => { ]); }); }); + + describe('implicit import', () => { + let trans: TranslatedSnippet; + beforeAll(() => { + trans = module.translateHere( + `import * as masm from 'my_assembly'; + masm.myFun({ prop: masm.MyEnum.OPTION_A }); + `, + ); + }); + + test('to Python', () => { + expectTranslation(trans, TargetLanguage.PYTHON, [ + 'import example_test_demo as masm', + 'masm.my_fun(prop=masm.MyEnum.OPTION_A)', + ]); + }); + + test('to Java', () => { + // eslint-disable-next-line prettier/prettier + expectTranslation(trans, TargetLanguage.JAVA, [ + 'import example.test.demo.*;', + 'myFun(MyProps.builder().prop(MyEnum.OPTION_A).build());', + ]); + }); + + test('to C#', () => { + // eslint-disable-next-line prettier/prettier + expectTranslation(trans, TargetLanguage.CSHARP, [ + 'using Example.Test.Demo;', + 'MyFun(new MyProps { Prop = MyEnum.OPTION_A });', + ]); + }); + }); }); });