21
21
use phpDocumentor \Reflection \Types \String_ ;
22
22
use phpDocumentor \Reflection \Types \This ;
23
23
use phpDocumentor \Reflection \Types \Void_ ;
24
+ use SebastianBergmann \ObjectReflector \ObjectReflector ;
24
25
use Spatie \TypeScriptTransformer \Structures \MissingSymbolsCollection ;
26
+ use Spatie \TypeScriptTransformer \Structures \TranspilationResult ;
25
27
use Spatie \TypeScriptTransformer \Types \RecordType ;
26
28
use Spatie \TypeScriptTransformer \Types \StructType ;
27
29
use Spatie \TypeScriptTransformer \Types \TypeScriptType ;
@@ -44,104 +46,152 @@ public function __construct(
44
46
$ this ->currentClass = $ currentClass ;
45
47
}
46
48
47
- public function execute (Type $ type ): string
48
- {
49
- return match (true ) {
49
+ public function execute (Type $ type ): TranspilationResult {
50
+ $ result = match (true ) {
50
51
$ type instanceof Compound => $ this ->resolveCompoundType ($ type ),
51
52
$ type instanceof AbstractList => $ this ->resolveListType ($ type ),
52
53
$ type instanceof Nullable => $ this ->resolveNullableType ($ type ),
53
54
$ type instanceof Object_ => $ this ->resolveObjectType ($ type ),
54
55
$ type instanceof StructType => $ this ->resolveStructType ($ type ),
55
56
$ type instanceof RecordType => $ this ->resolveRecordType ($ type ),
56
- $ type instanceof TypeScriptType => ( string ) $ type ,
57
- $ type instanceof Boolean => 'boolean ' ,
58
- $ type instanceof Float_, $ type instanceof Integer => 'number ' ,
59
- $ type instanceof String_, $ type instanceof ClassString => 'string ' ,
60
- $ type instanceof Null_ => 'null ' ,
57
+ $ type instanceof TypeScriptType => TranspilationResult:: noDeps (( string )$ type) ,
58
+ $ type instanceof Boolean => TranspilationResult:: noDeps ( 'boolean ' ) ,
59
+ $ type instanceof Float_, $ type instanceof Integer => TranspilationResult:: noDeps ( 'number ' ) ,
60
+ $ type instanceof String_, $ type instanceof ClassString => TranspilationResult:: noDeps ( 'string ' ) ,
61
+ $ type instanceof Null_ => TranspilationResult:: noDeps ( 'null ' ) ,
61
62
$ type instanceof Self_, $ type instanceof Static_, $ type instanceof This => $ this ->resolveSelfReferenceType (),
62
- $ type instanceof Scalar => 'string|number|boolean ' ,
63
- $ type instanceof Mixed_ => 'any ' ,
64
- $ type instanceof Void_ => 'void ' ,
63
+ $ type instanceof Scalar => TranspilationResult:: noDeps ( 'string|number|boolean ' ) ,
64
+ $ type instanceof Mixed_ => TranspilationResult:: noDeps ( 'any ' ) ,
65
+ $ type instanceof Void_ => TranspilationResult:: noDeps ( 'void ' ) ,
65
66
$ type instanceof PseudoType => $ this ->execute ($ type ->underlyingType ()),
66
67
default => throw new Exception ("Could not transform type: {$ type }" )
67
68
};
69
+ return new TranspilationResult (
70
+ array_merge (
71
+ (
72
+ $ type instanceof Object_
73
+ && $ type ->__toString () !== 'object '
74
+ )
75
+ ? [$ type ]
76
+ : [],
77
+ $ result ->dependencies
78
+ ),
79
+ $ result ->typescript
80
+ );
68
81
}
69
82
70
- private function resolveCompoundType (Compound $ compound ): string
71
- {
83
+ private function resolveCompoundType (Compound $ compound ): TranspilationResult {
72
84
$ transformed = array_map (
73
- fn (Type $ type ) => $ this ->execute ($ type ),
85
+ fn (Type $ type ) => $ this ->execute ($ type ),
74
86
iterator_to_array ($ compound ->getIterator ())
75
87
);
76
88
77
- return join (' | ' , array_unique ($ transformed ));
89
+ return new TranspilationResult (
90
+ array_reduce (
91
+ $ transformed ,
92
+ fn (array $ carry , TranspilationResult $ item ) => array_merge (
93
+ $ carry ,
94
+ $ item ->dependencies
95
+ ),
96
+ []
97
+ ),
98
+ join (
99
+ ' | ' ,
100
+ array_unique (
101
+ array_map (
102
+ fn (TranspilationResult $ result ) => $ result ->typescript ,
103
+ $ transformed
104
+ )
105
+ )
106
+ )
107
+ );
78
108
}
79
109
80
- private function resolveListType (AbstractList $ list ): string
81
- {
110
+ private function resolveListType (AbstractList $ list ): TranspilationResult {
111
+ $ valueTransResult = $ this -> execute ( $ list -> getValueType ());
82
112
if ($ this ->isTypeScriptArray ($ list ->getKeyType ())) {
83
- return "Array< {$ this ->execute ($ list ->getValueType ())}> " ;
113
+ return new TranspilationResult (
114
+ $ valueTransResult ->dependencies ,
115
+ "Array< $ valueTransResult ->typescript > "
116
+ );
84
117
}
85
118
86
- return "{ [key: {$ this ->execute ($ list ->getKeyType ())}]: {$ this ->execute ($ list ->getValueType ())} } " ;
119
+ $ keyTransResult = $ this ->execute ($ list ->getKeyType ());
120
+ $ typescript = "{ [key: $ keyTransResult ->typescript ]: {$ valueTransResult ->typescript } } " ;
121
+ return new TranspilationResult (
122
+ array_merge ($ valueTransResult ->dependencies , $ keyTransResult ->dependencies ),
123
+ $ typescript
124
+ );
87
125
}
88
126
89
- private function resolveNullableType (Nullable $ nullable ): string
90
- {
127
+ private function resolveNullableType (Nullable $ nullable ): TranspilationResult {
91
128
if ($ this ->nullablesAreOptional ) {
92
129
return $ this ->execute ($ nullable ->getActualType ());
93
130
}
94
131
95
- return "{$ this ->execute ($ nullable ->getActualType ())} | null " ;
132
+ $ transpilationResult = $ this ->execute ($ nullable ->getActualType ());
133
+ return new TranspilationResult (
134
+ $ transpilationResult ->dependencies ,
135
+ "$ transpilationResult ->typescript | null "
136
+ );
96
137
}
97
138
98
- private function resolveObjectType (Object_ $ object ): string
99
- {
139
+ private function resolveObjectType (Object_ $ object ): TranspilationResult {
100
140
if ($ object ->getFqsen () === null ) {
101
- return 'object ' ;
141
+ return TranspilationResult:: noDeps ( 'object ' ) ;
102
142
}
103
143
104
- return $ this ->missingSymbolsCollection ->add (
105
- (string ) $ object ->getFqsen ()
144
+ return TranspilationResult::noDeps (
145
+ $ this ->missingSymbolsCollection ->add (
146
+ (string )$ object ->getFqsen ()
147
+ )
106
148
);
107
149
}
108
150
109
- private function resolveStructType (StructType $ type ): string
110
- {
151
+ private function resolveStructType (StructType $ type ): TranspilationResult {
111
152
$ transformed = "{ " ;
112
153
154
+ $ dependencies = [];
113
155
foreach ($ type ->getTypes () as $ name => $ type ) {
114
- $ transformed .= "{$ name }: {$ this ->execute ($ type )}; " ;
156
+ $ trRes = $ this ->execute ($ type );
157
+ $ transformed .= "{$ name }: {$ trRes ->typescript }; " ;
158
+ foreach ($ trRes ->dependencies as $ dependency ) {
159
+ $ dependencies [] = $ dependency ;
160
+ }
115
161
}
116
162
117
- return "{$ transformed }} " ;
163
+ return new TranspilationResult ( $ dependencies , "{$ transformed }} " ) ;
118
164
}
119
165
120
- private function resolveRecordType (RecordType $ type ): string
121
- {
122
- return "Record< {$ this ->execute ($ type ->getKeyType ())}, {$ this ->execute ($ type ->getValueType ())}> " ;
166
+ private function resolveRecordType (RecordType $ type ): TranspilationResult {
167
+ $ keyTr = $ this ->execute ($ type ->getKeyType ());
168
+ $ valueTr = $ this ->execute ($ type ->getValueType ());
169
+ return new TranspilationResult (
170
+ array_merge ($ keyTr ->dependencies , $ valueTr ->dependencies ),
171
+ "Record< {$ keyTr ->typescript }, {$ valueTr ->typescript }> "
172
+ );
123
173
}
124
174
125
- private function resolveSelfReferenceType (): string
126
- {
175
+ private function resolveSelfReferenceType (): TranspilationResult {
127
176
if ($ this ->currentClass === null ) {
128
- return 'any ' ;
177
+ return TranspilationResult:: noDeps ( 'any ' ) ;
129
178
}
130
179
131
- return $ this ->missingSymbolsCollection ->add ($ this ->currentClass );
180
+ return TranspilationResult::noDeps (
181
+ $ this ->missingSymbolsCollection ->add ($ this ->currentClass )
182
+ );
132
183
}
133
184
134
- private function isTypeScriptArray (Type $ keyType ): bool
135
- {
136
- if (! $ keyType instanceof Compound) {
185
+ private function isTypeScriptArray (Type $ keyType ): bool {
186
+ if (!$ keyType instanceof Compound) {
137
187
return false ;
138
188
}
139
189
140
190
if ($ keyType ->getIterator ()->count () !== 2 ) {
141
191
return false ;
142
192
}
143
193
144
- if (! $ keyType ->contains (new String_ ()) || ! $ keyType ->contains (new Integer ())) {
194
+ if (!$ keyType ->contains (new String_ ()) || !$ keyType ->contains (new Integer ())) {
145
195
return false ;
146
196
}
147
197
0 commit comments