@@ -267,6 +267,29 @@ class GraphqlFieldDefinitionMethodCall extends GraphqlSchemaObjectClassMethodCal
267
267
}
268
268
}
269
269
270
+ /**
271
+ * A call to `argument` in a GraphQL InputObject class.
272
+ */
273
+ class GraphqlInputObjectArgumentDefinitionCall extends DataFlow:: CallNode {
274
+ GraphqlInputObjectArgumentDefinitionCall ( ) {
275
+ this =
276
+ graphQlSchema ( )
277
+ .getMember ( "InputObject" )
278
+ .getADescendentModule ( )
279
+ .getAnOwnModuleSelf ( )
280
+ .getAMethodCall ( )
281
+ }
282
+
283
+ /** Gets the name of the argument (i.e. the first argument to this `argument` method call) */
284
+ string getArgumentName ( ) { result = this .getArgument ( 0 ) .getConstantValue ( ) .getStringlikeValue ( ) }
285
+
286
+ /** Gets the type of this argument */
287
+ GraphqlType getArgumentType ( ) { result = this .getArgument ( 1 ) .asExpr ( ) .getExpr ( ) }
288
+
289
+ /** Gets the class representing the receiver of this method. */
290
+ ClassDeclaration getReceiverClass ( ) { result = this .asExpr ( ) .getExpr ( ) .getEnclosingModule ( ) }
291
+ }
292
+
270
293
/**
271
294
* A `MethodCall` that represents calling the class method `argument` inside the
272
295
* block for a `field` definition on a GraphQL object.
@@ -313,19 +336,23 @@ private class GraphqlType extends ConstantAccess {
313
336
Module getModule ( ) { result .getAnImmediateReference ( ) = this }
314
337
315
338
/**
316
- * Gets a field of this type, if it is an object type.
339
+ * Gets the type of a field/argument of this type, if it is an object type.
317
340
*/
318
- GraphqlType getAField ( ) { result = this .getField ( _) }
341
+ GraphqlType getAFieldOrArgument ( ) { result = this .getFieldOrArgument ( _) }
319
342
320
343
/**
321
- * Gets the field of this type named `name`, if it exists.
344
+ * Gets the type of the `name` field/argument of this type , if it exists.
322
345
*/
323
- GraphqlType getField ( string name ) {
346
+ GraphqlType getFieldOrArgument ( string name ) {
324
347
result =
325
348
any ( GraphqlFieldDefinitionMethodCall field |
326
349
field .getFieldName ( ) = name and
327
350
this .getModule ( ) .getADeclaration ( ) = field .getReceiverClass ( )
328
- ) .getFieldType ( )
351
+ ) .getFieldType ( ) or
352
+ result =
353
+ any ( GraphqlInputObjectArgumentDefinitionCall arg |
354
+ arg .getArgumentName ( ) = name and this .getModule ( ) .getADeclaration ( ) = arg .getReceiverClass ( )
355
+ ) .getArgumentType ( )
329
356
}
330
357
331
358
/**
@@ -344,7 +371,7 @@ private class GraphqlType extends ConstantAccess {
344
371
/**
345
372
* Holds if this type is scalar - i.e. it is neither an object or an enum.
346
373
*/
347
- predicate isScalar ( ) { not exists ( this .getAField ( ) ) and not this .isEnum ( ) }
374
+ predicate isScalar ( ) { not exists ( this .getAFieldOrArgument ( ) ) and not this .isEnum ( ) }
348
375
}
349
376
350
377
/**
@@ -440,34 +467,35 @@ private DataFlow::CallNode hashAccess(DataFlow::Node recv, string key) {
440
467
}
441
468
442
469
private DataFlow:: CallNode parameterAccess (
443
- GraphqlFieldResolutionMethod method , GraphqlFieldArgumentDefinitionMethodCall def ,
444
- HashSplatParameter param , string key , GraphqlType type
470
+ GraphqlFieldResolutionMethod method , HashSplatParameter param , GraphqlType type
445
471
) {
446
- param = method .getAParameter ( ) and
447
- def = method .getDefinition ( ) .getAnArgumentCall ( ) and
448
- (
449
- // Direct access to the params hash
450
- def .getArgumentType ( ) = type and
451
- def .getArgumentName ( ) = key and
452
- exists ( DataFlow:: Node paramRead |
453
- paramRead .asExpr ( ) .getExpr ( ) = param .getVariable ( ) .getAnAccess ( ) .( VariableReadAccess ) and
454
- result = hashAccess ( paramRead , key )
455
- )
456
- or
457
- // Nested access
458
- exists ( GraphqlType type2 |
459
- parameterAccess ( method , _, param , _, type2 )
460
- .( DataFlow:: LocalSourceNode )
461
- .flowsTo ( result .getReceiver ( ) ) and
462
- result = hashAccess ( _, key ) and
463
- type2 .getField ( key ) = type
472
+ exists ( GraphqlFieldArgumentDefinitionMethodCall def , string key |
473
+ param = method .getAParameter ( ) and
474
+ def = method .getDefinition ( ) .getAnArgumentCall ( ) and
475
+ (
476
+ // Direct access to the params hash
477
+ def .getArgumentType ( ) = type and
478
+ def .getArgumentName ( ) = key and
479
+ exists ( DataFlow:: Node paramRead |
480
+ paramRead .asExpr ( ) .getExpr ( ) = param .getVariable ( ) .getAnAccess ( ) .( VariableReadAccess ) and
481
+ result = hashAccess ( paramRead , key )
482
+ )
483
+ or
484
+ // Nested access
485
+ exists ( GraphqlType type2 |
486
+ parameterAccess ( method , param , type2 )
487
+ .( DataFlow:: LocalSourceNode )
488
+ .flowsTo ( result .getReceiver ( ) ) and
489
+ result = hashAccess ( _, key ) and
490
+ type2 .getFieldOrArgument ( key ) = type
491
+ )
464
492
)
465
493
)
466
494
}
467
495
468
496
private class GraphqlParameterAccess extends RemoteFlowSource:: Range {
469
497
GraphqlParameterAccess ( ) {
470
- exists ( GraphqlType type | this = parameterAccess ( _, _, _ , _ , type ) and type .isScalar ( ) )
498
+ exists ( GraphqlType type | this = parameterAccess ( _, _, type ) and type .isScalar ( ) )
471
499
}
472
500
473
501
override string getSourceType ( ) { result = "GraphQL" }
0 commit comments