@@ -363,14 +363,15 @@ abstract class BaseMethod implements PythonBase {
363
363
if ( this . liftedProp !== undefined ) {
364
364
// Remove our last item.
365
365
pythonParams . pop ( ) ;
366
+ const liftedProperties = this . getLiftedProperties ( resolver ) ;
366
367
367
- if ( this . liftedProp . properties !== undefined && this . liftedProp . properties . length >= 1 ) {
368
+ if ( liftedProperties . length >= 1 ) {
368
369
// All of these parameters are keyword only arguments, so we'll mark them
369
370
// as such.
370
371
pythonParams . push ( "*" ) ;
371
372
372
373
// Iterate over all of our props, and reflect them into our params.
373
- for ( const prop of this . liftedProp . properties ) {
374
+ for ( const prop of liftedProperties ) {
374
375
const paramName = toPythonParameterName ( prop . name ) ;
375
376
const paramType = resolver . resolve ( prop . type , { forwardReferences : false } ) ;
376
377
const paramDefault = prop . type . optional ? "=None" : "" ;
@@ -431,7 +432,7 @@ abstract class BaseMethod implements PythonBase {
431
432
// We need to build up a list of properties, which are mandatory, these are the
432
433
// ones we will specifiy to start with in our dictionary literal.
433
434
const mandatoryPropMembers : string [ ] = [ ] ;
434
- for ( const prop of this . liftedProp ! . properties || [ ] ) {
435
+ for ( const prop of this . getLiftedProperties ( resolver ) ) {
435
436
if ( prop . type . optional ) {
436
437
continue ;
437
438
}
@@ -443,7 +444,7 @@ abstract class BaseMethod implements PythonBase {
443
444
444
445
// Now we'll go through our optional properties, and if they haven't been set
445
446
// we'll add them to our dictionary.
446
- for ( const prop of this . liftedProp ! . properties || [ ] ) {
447
+ for ( const prop of this . getLiftedProperties ( resolver ) ) {
447
448
if ( ! prop . type . optional ) {
448
449
continue ;
449
450
}
@@ -476,6 +477,29 @@ abstract class BaseMethod implements PythonBase {
476
477
477
478
code . line ( `${ methodPrefix } jsii.${ this . jsiiMethod } (${ jsiiMethodParams . join ( ", " ) } , [${ paramNames . join ( ", " ) } ])` ) ;
478
479
}
480
+
481
+ private getLiftedProperties ( resolver : TypeResolver ) : spec . Property [ ] {
482
+ const liftedProperties : spec . Property [ ] = [ ] ;
483
+
484
+ const stack = [ this . liftedProp ] ;
485
+ let current = stack . shift ( ) ;
486
+ while ( current !== undefined ) {
487
+ // Add any interfaces that this interface depends on, to the list.
488
+ if ( current . interfaces !== undefined ) {
489
+ stack . push ( ...current . interfaces . map ( ifc => resolver . dereference ( ifc ) as spec . InterfaceType ) ) ;
490
+ }
491
+
492
+ // Add all of the properties of this interface to our list of properties.
493
+ if ( current . properties !== undefined ) {
494
+ liftedProperties . push ( ...current . properties ) ;
495
+ }
496
+
497
+ // Finally, grab our next item.
498
+ current = stack . shift ( ) ;
499
+ }
500
+
501
+ return liftedProperties ;
502
+ }
479
503
}
480
504
481
505
interface BasePropertyOpts {
@@ -1139,6 +1163,7 @@ class Package {
1139
1163
}
1140
1164
1141
1165
type FindModuleCallback = ( fqn : string ) => spec . Assembly | spec . PackageVersion ;
1166
+ type FindTypeCallback = ( fqn : string ) => spec . Type ;
1142
1167
1143
1168
interface TypeResolverOpts {
1144
1169
forwardReferences ?: boolean ;
@@ -1154,10 +1179,16 @@ class TypeResolver {
1154
1179
private readonly moduleName ?: string ;
1155
1180
private readonly moduleRe : RegExp ;
1156
1181
private readonly findModule : FindModuleCallback ;
1182
+ private readonly findType : FindTypeCallback ;
1157
1183
1158
- constructor ( types : Map < string , PythonType > , findModule : FindModuleCallback , boundTo ?: string , moduleName ?: string ) {
1184
+ constructor ( types : Map < string , PythonType > ,
1185
+ findModule : FindModuleCallback ,
1186
+ findType : FindTypeCallback ,
1187
+ boundTo ?: string ,
1188
+ moduleName ?: string ) {
1159
1189
this . types = types ;
1160
1190
this . findModule = findModule ;
1191
+ this . findType = findType ;
1161
1192
this . moduleName = moduleName ;
1162
1193
this . boundTo = boundTo !== undefined ? this . toPythonFQN ( boundTo ) : boundTo ;
1163
1194
@@ -1174,6 +1205,7 @@ class TypeResolver {
1174
1205
return new TypeResolver (
1175
1206
this . types ,
1176
1207
this . findModule ,
1208
+ this . findType ,
1177
1209
fqn ,
1178
1210
moduleName !== undefined ? moduleName : this . moduleName ,
1179
1211
) ;
@@ -1211,6 +1243,10 @@ class TypeResolver {
1211
1243
return type ;
1212
1244
}
1213
1245
1246
+ public dereference ( typeRef : spec . NamedTypeReference ) : spec . Type {
1247
+ return this . findType ( typeRef . fqn ) ;
1248
+ }
1249
+
1214
1250
public resolve (
1215
1251
typeRef : spec . TypeReference ,
1216
1252
opts : TypeResolverOpts = { forwardReferences : true , ignoreOptional : false } ) : string {
@@ -1381,7 +1417,11 @@ class PythonGenerator extends Generator {
1381
1417
}
1382
1418
1383
1419
protected onEndAssembly ( _assm : spec . Assembly , _fingerprint : boolean ) {
1384
- const resolver = new TypeResolver ( this . types , ( fqn : string ) => this . findModule ( fqn ) ) ;
1420
+ const resolver = new TypeResolver (
1421
+ this . types ,
1422
+ ( fqn : string ) => this . findModule ( fqn ) ,
1423
+ ( fqn : string ) => this . findType ( fqn ) ,
1424
+ ) ;
1385
1425
this . package . write ( this . code , resolver ) ;
1386
1426
}
1387
1427
0 commit comments