6
6
SignatureReflection ,
7
7
} from "../../models/reflections/index" ;
8
8
import { ReferenceType , Type } from "../../models/types/index" ;
9
- import { zip } from "../../utils/array" ;
9
+ import { filterMap , zip } from "../../utils/array" ;
10
10
import { Component , ConverterComponent } from "../components" ;
11
11
import { Context } from "../context" ;
12
12
import { Converter } from "../converter" ;
@@ -18,6 +18,9 @@ import { copyComment } from "../utils/reflections";
18
18
*/
19
19
@Component ( { name : "implements" } )
20
20
export class ImplementsPlugin extends ConverterComponent {
21
+ private resolved = new WeakSet < Reflection > ( ) ;
22
+ private postponed = new WeakMap < Reflection , Set < DeclarationReflection > > ( ) ;
23
+
21
24
/**
22
25
* Create a new ImplementsPlugin instance.
23
26
*/
@@ -53,101 +56,96 @@ export class ImplementsPlugin extends ConverterComponent {
53
56
return ;
54
57
}
55
58
56
- interfaceReflection . children . forEach (
57
- ( interfaceMember : DeclarationReflection ) => {
58
- if ( ! ( interfaceMember instanceof DeclarationReflection ) ) {
59
- return ;
60
- }
59
+ interfaceReflection . children . forEach ( ( interfaceMember ) => {
60
+ let classMember : DeclarationReflection | undefined ;
61
61
62
- let classMember : DeclarationReflection | undefined ;
62
+ if ( ! classReflection . children ) {
63
+ return ;
64
+ }
63
65
64
- if ( ! classReflection . children ) {
65
- return ;
66
+ for (
67
+ let index = 0 , count = classReflection . children . length ;
68
+ index < count ;
69
+ index ++
70
+ ) {
71
+ const child = classReflection . children [ index ] ;
72
+ if ( child . name !== interfaceMember . name ) {
73
+ continue ;
66
74
}
67
-
68
- for (
69
- let index = 0 , count = classReflection . children . length ;
70
- index < count ;
71
- index ++
72
- ) {
73
- const child = classReflection . children [ index ] ;
74
- if ( child . name !== interfaceMember . name ) {
75
- continue ;
76
- }
77
- if (
78
- child . flags . isStatic !== interfaceMember . flags . isStatic
79
- ) {
80
- continue ;
81
- }
82
-
83
- classMember = child ;
84
- break ;
75
+ if ( child . flags . isStatic !== interfaceMember . flags . isStatic ) {
76
+ continue ;
85
77
}
86
78
87
- if ( ! classMember ) {
88
- return ;
89
- }
79
+ classMember = child ;
80
+ break ;
81
+ }
90
82
91
- const interfaceMemberName =
92
- interfaceReflection . name + "." + interfaceMember . name ;
93
- classMember . implementationOf = new ReferenceType (
94
- interfaceMemberName ,
95
- interfaceMember ,
96
- context . project
97
- ) ;
98
- copyComment ( classMember , interfaceMember ) ;
83
+ if ( ! classMember ) {
84
+ return ;
85
+ }
99
86
100
- if (
101
- interfaceMember . kindOf ( ReflectionKind . Property ) &&
102
- classMember . kindOf ( ReflectionKind . Accessor )
103
- ) {
104
- if ( classMember . getSignature ) {
105
- copyComment ( classMember . getSignature , interfaceMember ) ;
106
- classMember . getSignature . implementationOf =
107
- classMember . implementationOf ;
108
- }
109
- if ( classMember . setSignature ) {
110
- copyComment ( classMember . setSignature , interfaceMember ) ;
111
- classMember . setSignature . implementationOf =
112
- classMember . implementationOf ;
113
- }
87
+ const interfaceMemberName =
88
+ interfaceReflection . name + "." + interfaceMember . name ;
89
+ classMember . implementationOf = new ReferenceType (
90
+ interfaceMemberName ,
91
+ interfaceMember ,
92
+ context . project
93
+ ) ;
94
+ copyComment ( classMember , interfaceMember ) ;
95
+
96
+ if (
97
+ interfaceMember . kindOf ( ReflectionKind . Property ) &&
98
+ classMember . kindOf ( ReflectionKind . Accessor )
99
+ ) {
100
+ if ( classMember . getSignature ) {
101
+ copyComment ( classMember . getSignature , interfaceMember ) ;
102
+ classMember . getSignature . implementationOf =
103
+ classMember . implementationOf ;
104
+ }
105
+ if ( classMember . setSignature ) {
106
+ copyComment ( classMember . setSignature , interfaceMember ) ;
107
+ classMember . setSignature . implementationOf =
108
+ classMember . implementationOf ;
114
109
}
110
+ }
115
111
116
- if (
117
- interfaceMember . kindOf ( ReflectionKind . FunctionOrMethod ) &&
118
- interfaceMember . signatures &&
119
- classMember . signatures
120
- ) {
121
- for ( const [ clsSig , intSig ] of zip (
122
- classMember . signatures ,
123
- interfaceMember . signatures
124
- ) ) {
125
- if ( clsSig . implementationOf ) {
126
- clsSig . implementationOf = new ReferenceType (
127
- clsSig . implementationOf . name ,
128
- intSig ,
129
- context . project
130
- ) ;
131
- }
132
- copyComment ( clsSig , intSig ) ;
112
+ if (
113
+ interfaceMember . kindOf ( ReflectionKind . FunctionOrMethod ) &&
114
+ interfaceMember . signatures &&
115
+ classMember . signatures
116
+ ) {
117
+ for ( const [ clsSig , intSig ] of zip (
118
+ classMember . signatures ,
119
+ interfaceMember . signatures
120
+ ) ) {
121
+ if ( clsSig . implementationOf ) {
122
+ clsSig . implementationOf = new ReferenceType (
123
+ clsSig . implementationOf . name ,
124
+ intSig ,
125
+ context . project
126
+ ) ;
133
127
}
128
+ copyComment ( clsSig , intSig ) ;
134
129
}
135
130
}
136
- ) ;
131
+ } ) ;
137
132
}
138
133
139
134
private analyzeInheritance (
140
135
context : Context ,
141
136
reflection : DeclarationReflection
142
137
) {
143
- const extendedTypes = ( reflection . extendedTypes ?. filter ( ( type ) => {
144
- return (
145
- type instanceof ReferenceType &&
146
- type . reflection instanceof DeclarationReflection
147
- ) ;
148
- } ) ?? [ ] ) as Array <
149
- ReferenceType & { reflection : DeclarationReflection }
150
- > ;
138
+ const extendedTypes = filterMap (
139
+ reflection . extendedTypes ?? [ ] ,
140
+ ( type ) => {
141
+ return type instanceof ReferenceType &&
142
+ type . reflection instanceof DeclarationReflection
143
+ ? ( type as ReferenceType & {
144
+ reflection : DeclarationReflection ;
145
+ } )
146
+ : void 0 ;
147
+ }
148
+ ) ;
151
149
152
150
for ( const parent of extendedTypes ) {
153
151
for ( const parentMember of parent . reflection . children ?? [ ] ) {
@@ -192,6 +190,38 @@ export class ImplementsPlugin extends ConverterComponent {
192
190
* @param reflection The reflection that is currently resolved.
193
191
*/
194
192
private onResolve ( context : Context , reflection : DeclarationReflection ) {
193
+ this . tryResolve ( context , reflection ) ;
194
+ }
195
+
196
+ private tryResolve ( context : Context , reflection : DeclarationReflection ) {
197
+ const requirements = filterMap (
198
+ [
199
+ ...( reflection . implementedTypes ?? [ ] ) ,
200
+ ...( reflection . extendedTypes ?? [ ] ) ,
201
+ ] ,
202
+ ( type ) => {
203
+ return type instanceof ReferenceType ? type . reflection : void 0 ;
204
+ }
205
+ ) ;
206
+
207
+ if ( requirements . every ( ( req ) => this . resolved . has ( req ) ) ) {
208
+ this . doResolve ( context , reflection ) ;
209
+ this . resolved . add ( reflection ) ;
210
+
211
+ for ( const refl of this . postponed . get ( reflection ) ?? [ ] ) {
212
+ this . tryResolve ( context , refl ) ;
213
+ }
214
+ this . postponed . delete ( reflection ) ;
215
+ } else {
216
+ for ( const req of requirements ) {
217
+ const future = this . postponed . get ( req ) ?? new Set ( ) ;
218
+ future . add ( reflection ) ;
219
+ this . postponed . set ( req , future ) ;
220
+ }
221
+ }
222
+ }
223
+
224
+ private doResolve ( context : Context , reflection : DeclarationReflection ) {
195
225
if (
196
226
reflection . kindOf ( ReflectionKind . Class ) &&
197
227
reflection . implementedTypes
0 commit comments