|
1 | 1 | import * as Path from 'path'; |
2 | 2 | import { ClassDeclaration, TSInterfaceDeclaration } from '@typescript-eslint/types/dist/ts-estree'; |
3 | | -import { AST, TSESTreeOptions, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; |
| 3 | +import { AST, AST_NODE_TYPES, TSESTreeOptions } from '@typescript-eslint/typescript-estree'; |
4 | 4 | import { ResolutionContext } from '../resolution/ResolutionContext'; |
5 | | -import { ClassLoaded, ClassReference, ClassReferenceLoaded, InterfaceLoaded } from './ClassIndex'; |
| 5 | +import { ClassLoaded, ClassReference, ClassReferenceLoaded, GenericTypes, InterfaceLoaded } from './ClassIndex'; |
6 | 6 | import { CommentLoader } from './CommentLoader'; |
7 | 7 |
|
8 | 8 | /** |
@@ -77,45 +77,53 @@ export class ClassLoader { |
77 | 77 |
|
78 | 78 | // If the class has been exported in this file, return directly |
79 | 79 | if (classReference.localName in exportedClasses) { |
| 80 | + const declaration = exportedClasses[classReference.localName]; |
80 | 81 | return <any> this.enhanceLoadedWithComment(<ClassLoaded> { |
81 | 82 | type: 'class', |
82 | 83 | ...classReference, |
83 | | - declaration: exportedClasses[classReference.localName], |
| 84 | + declaration, |
84 | 85 | ast, |
85 | | - abstract: exportedClasses[classReference.localName].abstract, |
| 86 | + abstract: declaration.abstract, |
| 87 | + generics: this.collectGenericTypes(declaration), |
86 | 88 | }); |
87 | 89 | } |
88 | 90 |
|
89 | 91 | // If the class has been declared in this file, return directly |
90 | 92 | if (classReference.localName in declaredClasses) { |
| 93 | + const declaration = declaredClasses[classReference.localName]; |
91 | 94 | return <any> this.enhanceLoadedWithComment(<ClassLoaded> { |
92 | 95 | type: 'class', |
93 | 96 | ...classReference, |
94 | | - declaration: declaredClasses[classReference.localName], |
| 97 | + declaration, |
95 | 98 | ast, |
96 | | - abstract: declaredClasses[classReference.localName].abstract, |
| 99 | + abstract: declaration.abstract, |
| 100 | + generics: this.collectGenericTypes(declaration), |
97 | 101 | }); |
98 | 102 | } |
99 | 103 |
|
100 | 104 | // Only consider interfaces if explicitly enabled |
101 | 105 | if (considerInterfaces) { |
102 | 106 | // If the interface has been exported in this file, return directly |
103 | 107 | if (classReference.localName in exportedInterfaces) { |
| 108 | + const declaration = exportedInterfaces[classReference.localName]; |
104 | 109 | return <any> this.enhanceLoadedWithComment(<InterfaceLoaded> { |
105 | 110 | type: 'interface', |
106 | 111 | ...classReference, |
107 | | - declaration: exportedInterfaces[classReference.localName], |
| 112 | + declaration, |
108 | 113 | ast, |
| 114 | + generics: this.collectGenericTypes(declaration), |
109 | 115 | }); |
110 | 116 | } |
111 | 117 |
|
112 | 118 | // If the interface has been declared in this file, return directly |
113 | 119 | if (classReference.localName in declaredInterfaces) { |
| 120 | + const declaration = declaredInterfaces[classReference.localName]; |
114 | 121 | return <any> this.enhanceLoadedWithComment(<InterfaceLoaded> { |
115 | 122 | type: 'interface', |
116 | 123 | ...classReference, |
117 | | - declaration: declaredInterfaces[classReference.localName], |
| 124 | + declaration, |
118 | 125 | ast, |
| 126 | + generics: this.collectGenericTypes(declaration), |
119 | 127 | }); |
120 | 128 | } |
121 | 129 | } |
@@ -143,6 +151,20 @@ export class ClassLoader { |
143 | 151 | throw new Error(`Could not load ${considerInterfaces ? 'class or interface' : 'class'} ${classReference.localName} from ${classReference.fileName}`); |
144 | 152 | } |
145 | 153 |
|
| 154 | + /** |
| 155 | + * Create a hash of generic types in the given class declaration. |
| 156 | + * @param classDeclaration A class or interface declaration. |
| 157 | + */ |
| 158 | + public collectGenericTypes(classDeclaration: ClassDeclaration | TSInterfaceDeclaration): GenericTypes { |
| 159 | + const genericTypes: GenericTypes = {}; |
| 160 | + if (classDeclaration.typeParameters) { |
| 161 | + for (const param of classDeclaration.typeParameters.params) { |
| 162 | + genericTypes[param.name.name] = { type: param.constraint }; |
| 163 | + } |
| 164 | + } |
| 165 | + return genericTypes; |
| 166 | + } |
| 167 | + |
146 | 168 | /** |
147 | 169 | * Annotate the given loaded class or interface with a comment if it is present on the declaration. |
148 | 170 | * @param classLoaded A loaded class or interface. |
|
0 commit comments