@@ -185,6 +185,31 @@ class ReactMacro
185
185
}
186
186
}
187
187
188
+ static function extractNeededAttrs (type : Expr )
189
+ {
190
+ var neededAttrs = [];
191
+
192
+ try {
193
+ var tprops = Context .storeTypedExpr (Context .typeExpr (macro @:pos (type .pos ) {
194
+ function get <T >(c : Class <T >): T return null ;
195
+ @:privateAccess get ($type ).props ;
196
+ }));
197
+
198
+ switch (Context .typeof (tprops ))
199
+ {
200
+ case TType (_ .get () => _ .type => TAnonymous (_ .get ().fields => fields ), _ ):
201
+ for (f in fields )
202
+ if (! f .meta .has (' :optional' ))
203
+ neededAttrs .push (f .name );
204
+
205
+ default :
206
+ }
207
+
208
+ } catch (e : Dynamic ) {}
209
+
210
+ return neededAttrs ;
211
+ }
212
+
188
213
static function child (c : Child )
189
214
{
190
215
return switch (c .value ) {
@@ -208,6 +233,7 @@ class ReactMacro
208
233
var key = null ;
209
234
var ref = null ;
210
235
var pos = n .name .pos ;
236
+ var neededAttrs = extractNeededAttrs (type );
211
237
212
238
function add (name : StringAt , e : Expr )
213
239
{
@@ -223,14 +249,18 @@ class ReactMacro
223
249
{
224
250
case Splat (e ):
225
251
spread .push (e );
252
+ // Spread is not handled, so we assume every needed prop is passed
253
+ neededAttrs = [];
226
254
227
255
case Empty (invalid = { value : ' key' | ' ref' }):
228
256
invalid .pos .error (' attribute ${invalid .value } must have a value' );
229
257
230
258
case Empty (name ):
259
+ neededAttrs .remove (name .value );
231
260
add (name , macro @:pos (name .pos ) true );
232
261
233
262
case Regular (name , value ):
263
+ neededAttrs .remove (name .value );
234
264
var expr = value .getString ()
235
265
.map (function (s ) return macro $v {replaceEntities (s , value .pos )})
236
266
.orUse (value );
@@ -246,6 +276,13 @@ class ReactMacro
246
276
247
277
// parse children
248
278
var children = children (n .children );
279
+ if (children .compound != null ) neededAttrs .remove (' children' );
280
+
281
+ for (attr in neededAttrs )
282
+ Context .warning (
283
+ ' Missing prop ` $attr ` for component ` ${n .name .value }`' ,
284
+ c .pos
285
+ );
249
286
250
287
// inline declaration or createElement?
251
288
var typeInfo = getComponentInfo (type );
0 commit comments