@@ -72,6 +72,8 @@ private class Unit = Specific::Unit;
72
72
73
73
private module API = Specific:: API;
74
74
75
+ private module DataFlow = Specific:: DF;
76
+
75
77
private import Specific:: AccessPathSyntax
76
78
77
79
/** Module containing hooks for providing input data to be interpreted as a model. */
@@ -156,6 +158,22 @@ module ModelInput {
156
158
abstract predicate row ( string row ) ;
157
159
}
158
160
161
+ /**
162
+ * A unit class for adding additional type model rows from CodeQL models.
163
+ */
164
+ class TypeModel extends Unit {
165
+ /**
166
+ * Gets a data-flow node that is a source of the type `package;type`.
167
+ */
168
+ DataFlow:: Node getASource ( string package , string type ) { none ( ) }
169
+
170
+ /**
171
+ * Gets a data flow node that is a sink of the type `package;type`,
172
+ * usually because it is an argument passed to a parameter of that type.
173
+ */
174
+ DataFlow:: Node getASink ( string package , string type ) { none ( ) }
175
+ }
176
+
159
177
/**
160
178
* A unit class for adding additional type variable model rows.
161
179
*/
@@ -368,6 +386,58 @@ private predicate invocationMatchesCallSiteFilter(Specific::InvokeNode invoke, A
368
386
Specific:: invocationMatchesExtraCallSiteFilter ( invoke , token )
369
387
}
370
388
389
+ private class TypeModelUseEntry extends API:: EntryPoint {
390
+ private string package ;
391
+ private string type ;
392
+
393
+ TypeModelUseEntry ( ) {
394
+ exists ( any ( TypeModel tm ) .getASource ( package , type ) ) and
395
+ this = "TypeModelUseEntry;" + package + ";" + type
396
+ }
397
+
398
+ override DataFlow:: LocalSourceNode getASource ( ) {
399
+ result = any ( TypeModel tm ) .getASource ( package , type )
400
+ }
401
+
402
+ API:: Node getNodeForType ( string package_ , string type_ ) {
403
+ package = package_ and type = type_ and result = this .getANode ( )
404
+ }
405
+ }
406
+
407
+ private class TypeModelDefEntry extends API:: EntryPoint {
408
+ private string package ;
409
+ private string type ;
410
+
411
+ TypeModelDefEntry ( ) {
412
+ exists ( any ( TypeModel tm ) .getASink ( package , type ) ) and
413
+ this = "TypeModelDefEntry;" + package + ";" + type
414
+ }
415
+
416
+ override DataFlow:: Node getASink ( ) { result = any ( TypeModel tm ) .getASink ( package , type ) }
417
+
418
+ API:: Node getNodeForType ( string package_ , string type_ ) {
419
+ package = package_ and type = type_ and result = this .getANode ( )
420
+ }
421
+ }
422
+
423
+ /**
424
+ * Gets an API node identified by the given `(package,type)` pair.
425
+ */
426
+ pragma [ nomagic]
427
+ private API:: Node getNodeFromType ( string package , string type ) {
428
+ exists ( string package2 , string type2 , AccessPath path2 |
429
+ typeModel ( package , type , package2 , type2 , path2 ) and
430
+ result = getNodeFromPath ( package2 , type2 , path2 , path2 .getNumToken ( ) )
431
+ )
432
+ or
433
+ result = any ( TypeModelUseEntry e ) .getNodeForType ( package , type )
434
+ or
435
+ result = any ( TypeModelDefEntry e ) .getNodeForType ( package , type )
436
+ or
437
+ isRelevantFullPath ( package , type , _) and
438
+ result = Specific:: getExtraNodeFromPath ( package , type , _, 0 )
439
+ }
440
+
371
441
/**
372
442
* Gets the API node identified by the first `n` tokens of `path` in the given `(package, type, path)` tuple.
373
443
*/
@@ -376,12 +446,8 @@ private API::Node getNodeFromPath(string package, string type, AccessPath path,
376
446
isRelevantFullPath ( package , type , path ) and
377
447
(
378
448
n = 0 and
379
- exists ( string package2 , string type2 , AccessPath path2 |
380
- typeModel ( package , type , package2 , type2 , path2 ) and
381
- result = getNodeFromPath ( package2 , type2 , path2 , path2 .getNumToken ( ) )
382
- )
449
+ result = getNodeFromType ( package , type )
383
450
or
384
- // Language-specific cases, such as handling of global variables
385
451
result = Specific:: getExtraNodeFromPath ( package , type , path , n )
386
452
)
387
453
or
@@ -581,12 +647,7 @@ module ModelOutput {
581
647
* Holds if `node` is seen as an instance of `(package,type)` due to a type definition
582
648
* contributed by a CSV model.
583
649
*/
584
- API:: Node getATypeNode ( string package , string type ) {
585
- exists ( string package2 , string type2 , AccessPath path |
586
- typeModel ( package , type , package2 , type2 , path ) and
587
- result = getNodeFromPath ( package2 , type2 , path )
588
- )
589
- }
650
+ API:: Node getATypeNode ( string package , string type ) { result = getNodeFromType ( package , type ) }
590
651
591
652
/**
592
653
* Gets an error message relating to an invalid CSV row in a model.
0 commit comments