@@ -4,8 +4,10 @@ import {getPropertyNameText} from "./utils/utils.js";
44
55export enum Ui5TypeInfoKind {
66 Module ,
7- Class ,
87 Namespace ,
8+ Class ,
9+ Constructor ,
10+ ConstructorParameter ,
911 ManagedObjectSettings ,
1012 MetadataProperty ,
1113 MetadataEvent ,
@@ -20,9 +22,9 @@ export enum Ui5TypeInfoKind {
2022 EnumMember ,
2123}
2224
23- export type Ui5TypeInfo = Ui5ModuleTypeInfo | Ui5ClassTypeInfo | Ui5NamespaceTypeInfo |
24- Ui5MetadataTypeInfo | Ui5FunctionTypeInfo | Ui5MethodTypeInfo | Ui5PropertyTypeInfo |
25- Ui5EnumTypeInfo | Ui5EnumMemberTypeInfo | Ui5ManagedObjectSettingsTypeInfo ;
25+ export type Ui5TypeInfo = Ui5ModuleTypeInfo | Ui5NamespaceTypeInfo | Ui5ClassTypeInfo | Ui5ConstructorTypeInfo |
26+ Ui5ConstructorParameterTypeInfo | Ui5MetadataTypeInfo | Ui5FunctionTypeInfo | Ui5MethodTypeInfo |
27+ Ui5PropertyTypeInfo | Ui5EnumTypeInfo | Ui5EnumMemberTypeInfo | Ui5ManagedObjectSettingsTypeInfo ;
2628
2729export interface BaseUi5TypeInfo {
2830 kind : Ui5TypeInfoKind ;
@@ -74,7 +76,7 @@ interface Ui5MethodTypeInfo extends BaseUi5TypeInfo {
7476interface Ui5PropertyTypeInfo extends BaseUi5TypeInfo {
7577 kind : Ui5TypeInfoKind . Property | Ui5TypeInfoKind . StaticProperty ;
7678 name : string ;
77- parent : Ui5ClassTypeInfo ;
79+ parent : Ui5ClassTypeInfo | Ui5ConstructorTypeInfo | Ui5ConstructorParameterTypeInfo ;
7880}
7981
8082interface Ui5EnumTypeInfo extends BaseUi5TypeInfo {
@@ -89,6 +91,18 @@ interface Ui5EnumMemberTypeInfo extends BaseUi5TypeInfo {
8991 parent : Ui5EnumTypeInfo ;
9092}
9193
94+ interface Ui5ConstructorTypeInfo extends BaseUi5TypeInfo {
95+ kind : Ui5TypeInfoKind . Constructor ;
96+ name : string ;
97+ parent : Ui5ClassTypeInfo ;
98+ }
99+
100+ interface Ui5ConstructorParameterTypeInfo extends BaseUi5TypeInfo {
101+ kind : Ui5TypeInfoKind . ConstructorParameter ;
102+ name : string ; // e.g. "mParameters"
103+ parent : Ui5ConstructorTypeInfo ;
104+ }
105+
92106function isManagedObjectSettingsInterfaceName ( name : string ) : boolean {
93107 // This check is based on the naming convention when generating the Interface for ManagedObject settings:
94108 // $<ClassName>Settings
@@ -257,29 +271,39 @@ function createMangedObjectSettingsTypeInfo(node: ts.Declaration, moduleName: st
257271
258272function createClassTypeInfo (
259273 node : ts . Declaration , parent : Ui5ModuleTypeInfo | Ui5NamespaceTypeInfo
260- ) : Ui5MethodTypeInfo | Ui5PropertyTypeInfo | Ui5ClassTypeInfo | undefined {
274+ ) : Ui5MethodTypeInfo | Ui5PropertyTypeInfo | Ui5ClassTypeInfo | Ui5ConstructorParameterTypeInfo | undefined {
261275 if ( ts . isClassDeclaration ( node ) && node . name ) {
262276 return {
263277 kind : Ui5TypeInfoKind . Class ,
264278 name : node . name . text ,
265279 parent,
266280 } ;
267281 }
268- if ( ! ts . isInterfaceDeclaration ( node . parent ) && ! ts . isClassDeclaration ( node . parent ) ) {
269- return ;
282+ let classNode = node . parent ;
283+ const skippedNodes = [ ] ;
284+ while ( ! ts . isInterfaceDeclaration ( classNode ) && ! ts . isClassDeclaration ( classNode ) ) {
285+ if ( ! classNode . parent ) {
286+ return ;
287+ }
288+ skippedNodes . unshift ( classNode ) ;
289+ classNode = classNode . parent ;
270290 }
271- if ( ! node . parent . name ) {
291+ if ( ! classNode . name ) {
272292 // Class name can be undefined in `export default class { ... }`. But we generally don't expect
273293 // to encounter this case in the UI5 types so we can safely ignore it and keeps our types greedy.
274294 return ;
275295 }
276296 const classTypeInfo : Ui5ClassTypeInfo = {
277297 kind : Ui5TypeInfoKind . Class ,
278- name : node . parent . name . text ,
298+ name : classNode . name . text ,
279299 parent,
280300 } ;
281301
282302 if ( ts . isMethodSignature ( node ) || ts . isMethodDeclaration ( node ) ) {
303+ if ( skippedNodes . length ) {
304+ throw new Error (
305+ `Unexpected nested method declaration: ${ skippedNodes . map ( ( n ) => n . getText ( ) ) . join ( " -> " ) } ` ) ;
306+ }
283307 const name = getPropertyNameText ( node . name ) ;
284308 if ( ! name ) {
285309 // We need a name for methods and properties
@@ -291,16 +315,43 @@ function createClassTypeInfo(
291315 parent : classTypeInfo ,
292316 } ;
293317 }
294- if ( ts . isPropertySignature ( node ) || ts . isPropertyDeclaration ( node ) ) {
318+ if ( ts . isPropertySignature ( node ) || ts . isPropertyDeclaration ( node ) || ts . isParameter ( node ) ) {
319+ let parent = classTypeInfo as Ui5ClassTypeInfo | Ui5ConstructorTypeInfo | Ui5ConstructorParameterTypeInfo ;
320+ for ( const skippedNode of skippedNodes ) {
321+ if ( ts . isConstructorDeclaration ( skippedNode ) ) {
322+ parent = {
323+ kind : Ui5TypeInfoKind . Constructor ,
324+ name : "constructor" ,
325+ parent,
326+ } as Ui5ConstructorTypeInfo ;
327+ } else if ( ts . isParameter ( skippedNode ) ) {
328+ parent = {
329+ kind : Ui5TypeInfoKind . ConstructorParameter ,
330+ name : skippedNode . name . getText ( ) ,
331+ parent,
332+ } as Ui5ConstructorParameterTypeInfo ;
333+ }
334+ }
335+ if ( ! ts . isPropertyName ( node . name ) ) {
336+ return ;
337+ }
295338 const name = getPropertyNameText ( node . name ) ;
296339 if ( ! name ) {
297340 // We need a name for methods and properties
298341 return undefined ;
299342 }
343+ if ( ts . isParameter ( node ) ) {
344+ return {
345+ kind : Ui5TypeInfoKind . ConstructorParameter ,
346+ name,
347+ parent : parent as Ui5ConstructorTypeInfo ,
348+ } ;
349+ }
350+ // PropertySignature or PropertyDeclaration
300351 return {
301352 kind : hasStaticModifier ( node ) ? Ui5TypeInfoKind . StaticProperty : Ui5TypeInfoKind . Property ,
302353 name,
303- parent : classTypeInfo ,
354+ parent,
304355 } ;
305356 }
306357}
0 commit comments