@@ -72,6 +72,8 @@ private class Unit = Specific::Unit;
7272
7373private module API = Specific:: API;
7474
75+ private module DataFlow = Specific:: DataFlow;
76+
7577private import Specific:: AccessPathSyntax
7678
7779/** Module containing hooks for providing input data to be interpreted as a model. */
@@ -156,6 +158,22 @@ module ModelInput {
156158 abstract predicate row ( string row ) ;
157159 }
158160
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+
159177 /**
160178 * A unit class for adding additional type variable model rows.
161179 */
@@ -368,6 +386,57 @@ private predicate invocationMatchesCallSiteFilter(Specific::InvokeNode invoke, A
368386 Specific:: invocationMatchesExtraCallSiteFilter ( invoke , token )
369387}
370388
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 )
431+ )
432+ or
433+ result = any ( TypeModelUseEntry e ) .getNodeForType ( package , type )
434+ or
435+ result = any ( TypeModelDefEntry e ) .getNodeForType ( package , type )
436+ or
437+ result = Specific:: getExtraNodeFromType ( package , type )
438+ }
439+
371440/**
372441 * Gets the API node identified by the first `n` tokens of `path` in the given `(package, type, path)` tuple.
373442 */
@@ -376,12 +445,8 @@ private API::Node getNodeFromPath(string package, string type, AccessPath path,
376445 isRelevantFullPath ( package , type , path ) and
377446 (
378447 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- )
448+ result = getNodeFromType ( package , type )
383449 or
384- // Language-specific cases, such as handling of global variables
385450 result = Specific:: getExtraNodeFromPath ( package , type , path , n )
386451 )
387452 or
@@ -581,12 +646,7 @@ module ModelOutput {
581646 * Holds if `node` is seen as an instance of `(package,type)` due to a type definition
582647 * contributed by a CSV model.
583648 */
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- }
649+ API:: Node getATypeNode ( string package , string type ) { result = getNodeFromType ( package , type ) }
590650
591651 /**
592652 * Gets an error message relating to an invalid CSV row in a model.
0 commit comments