@@ -13,11 +13,14 @@ export interface ComponentInfoProvider {
13
13
export class JsOrTsComponentInfoProvider implements ComponentInfoProvider {
14
14
private constructor (
15
15
private readonly typeChecker : ts . TypeChecker ,
16
- private readonly classType : ts . Type
16
+ private readonly classType : ts . Type ,
17
+ private readonly useSvelte5PlusPropsParameter : boolean = false
17
18
) { }
18
19
19
20
getEvents ( ) : ComponentPartInfo {
20
- const eventType = this . getType ( '$$events_def' ) ;
21
+ const eventType = this . getType (
22
+ this . useSvelte5PlusPropsParameter ? '$$events' : '$$events_def'
23
+ ) ;
21
24
if ( ! eventType ) {
22
25
return [ ] ;
23
26
}
@@ -26,7 +29,7 @@ export class JsOrTsComponentInfoProvider implements ComponentInfoProvider {
26
29
}
27
30
28
31
getSlotLets ( slot = 'default' ) : ComponentPartInfo {
29
- const slotType = this . getType ( '$$slot_def' ) ;
32
+ const slotType = this . getType ( this . useSvelte5PlusPropsParameter ? '$$slots' : '$$slot_def' ) ;
30
33
if ( ! slotType ) {
31
34
return [ ] ;
32
35
}
@@ -45,12 +48,18 @@ export class JsOrTsComponentInfoProvider implements ComponentInfoProvider {
45
48
}
46
49
47
50
getProps ( ) {
48
- const props = this . getType ( '$$prop_def' ) ;
49
- if ( ! props ) {
50
- return [ ] ;
51
+ if ( ! this . useSvelte5PlusPropsParameter ) {
52
+ const props = this . getType ( '$$prop_def' ) ;
53
+ if ( ! props ) {
54
+ return [ ] ;
55
+ }
56
+
57
+ return this . mapPropertiesOfType ( props ) ;
51
58
}
52
59
53
- return this . mapPropertiesOfType ( props ) ;
60
+ return this . mapPropertiesOfType ( this . classType ) . filter (
61
+ ( prop ) => ! prop . name . startsWith ( '$$' )
62
+ ) ;
54
63
}
55
64
56
65
private getType ( classProperty : string ) {
@@ -87,32 +96,65 @@ export class JsOrTsComponentInfoProvider implements ComponentInfoProvider {
87
96
* The result of this shouldn't be cached as it could lead to memory leaks. The type checker
88
97
* could become old and then multiple versions of it could exist.
89
98
*/
90
- static create ( lang : ts . LanguageService , def : ts . DefinitionInfo ) : ComponentInfoProvider | null {
99
+ static create (
100
+ lang : ts . LanguageService ,
101
+ def : ts . DefinitionInfo ,
102
+ isSvelte5Plus : boolean
103
+ ) : ComponentInfoProvider | null {
91
104
const program = lang . getProgram ( ) ;
92
105
const sourceFile = program ?. getSourceFile ( def . fileName ) ;
93
106
94
107
if ( ! program || ! sourceFile ) {
95
108
return null ;
96
109
}
97
110
98
- const defClass = findContainingNode (
99
- sourceFile ,
100
- def . textSpan ,
101
- ( node ) : node is ts . ClassDeclaration | ts . VariableDeclaration =>
102
- ts . isClassDeclaration ( node ) || ts . isTypeAliasDeclaration ( node )
103
- ) ;
111
+ const defIdentifier = findContainingNode ( sourceFile , def . textSpan , ts . isIdentifier ) ;
104
112
105
- if ( ! defClass ) {
113
+ if ( ! defIdentifier ) {
106
114
return null ;
107
115
}
108
116
109
117
const typeChecker = program . getTypeChecker ( ) ;
110
- const classType = typeChecker . getTypeAtLocation ( defClass ) ;
111
118
112
- if ( ! classType ) {
119
+ const componentSymbol = typeChecker . getSymbolAtLocation ( defIdentifier ) ;
120
+
121
+ if ( ! componentSymbol ) {
113
122
return null ;
114
123
}
115
124
116
- return new JsOrTsComponentInfoProvider ( typeChecker , classType ) ;
125
+ const type = typeChecker . getTypeOfSymbolAtLocation ( componentSymbol , defIdentifier ) ;
126
+
127
+ if ( type . isClass ( ) ) {
128
+ return new JsOrTsComponentInfoProvider ( typeChecker , type ) ;
129
+ }
130
+
131
+ const constructorSignatures = type . getConstructSignatures ( ) ;
132
+ if ( constructorSignatures . length === 1 ) {
133
+ return new JsOrTsComponentInfoProvider (
134
+ typeChecker ,
135
+ constructorSignatures [ 0 ] . getReturnType ( )
136
+ ) ;
137
+ }
138
+
139
+ if ( ! isSvelte5Plus ) {
140
+ return null ;
141
+ }
142
+
143
+ const signatures = type . getCallSignatures ( ) ;
144
+ if ( signatures . length !== 1 ) {
145
+ return null ;
146
+ }
147
+
148
+ const propsParameter = signatures [ 0 ] . parameters [ 1 ] ;
149
+ if ( ! propsParameter ) {
150
+ return null ;
151
+ }
152
+ const propsParameterType = typeChecker . getTypeOfSymbol ( propsParameter ) ;
153
+
154
+ return new JsOrTsComponentInfoProvider (
155
+ typeChecker ,
156
+ propsParameterType ,
157
+ /** useSvelte5PlusPropsParameter */ true
158
+ ) ;
117
159
}
118
160
}
0 commit comments