@@ -95,6 +95,7 @@ private import DataFlowPublic
9595private import FlowSummaryImpl:: Public
9696private import FlowSummaryImpl:: Private:: External
9797private import FlowSummaryImplSpecific
98+ private import semmle.code.csharp.commons.QualifiedName
9899private import codeql.mad.ModelValidation as SharedModelVal
99100
100101private predicate relevantNamespace ( string namespace ) {
@@ -449,3 +450,76 @@ private module Cached {
449450}
450451
451452import Cached
453+
454+ /** Holds if the summary should apply for all overrides of `c`. */
455+ predicate isBaseCallableOrPrototype ( UnboundCallable c ) {
456+ c .getDeclaringType ( ) instanceof Interface
457+ or
458+ exists ( Modifiable m | m = [ c .( Modifiable ) , c .( Accessor ) .getDeclaration ( ) ] |
459+ m .isAbstract ( )
460+ or
461+ c .getDeclaringType ( ) .( Modifiable ) .isAbstract ( ) and m .( Virtualizable ) .isVirtual ( )
462+ )
463+ }
464+
465+ /** Gets a string representing whether the summary should apply for all overrides of `c`. */
466+ private string getCallableOverride ( UnboundCallable c ) {
467+ if isBaseCallableOrPrototype ( c ) then result = "true" else result = "false"
468+ }
469+
470+ private module QualifiedNameInput implements QualifiedNameInputSig {
471+ string getUnboundGenericSuffix ( UnboundGeneric ug ) {
472+ result =
473+ "<" + strictconcat ( int i , string s | s = ug .getTypeParameter ( i ) .getName ( ) | s , "," order by i )
474+ + ">"
475+ }
476+ }
477+
478+ private module QN = QualifiedName< QualifiedNameInput > ;
479+
480+ pragma [ nomagic]
481+ private string parameterQualifiedType ( Parameter p ) {
482+ exists ( string qualifier , string name |
483+ QN:: hasQualifiedName ( p .getType ( ) , qualifier , name ) and
484+ result = getQualifiedName ( qualifier , name )
485+ )
486+ }
487+
488+ /** Gets the string representation of the parameters of `c`. */
489+ string parameterQualifiedTypeNamesToString ( Callable c ) {
490+ result =
491+ concat ( int i , string s | s = parameterQualifiedType ( c .getParameter ( i ) ) | s , "," order by i )
492+ }
493+
494+ private predicate partialModel (
495+ UnboundCallable c , string namespace , string type , string name , string parameters
496+ ) {
497+ QN:: hasQualifiedName ( c , namespace , type , name ) and
498+ parameters = "(" + parameterQualifiedTypeNamesToString ( c ) + ")"
499+ }
500+
501+ /** Computes the first 6 columns for positive CSV rows of `c`. */
502+ string asPartialModel ( UnboundCallable c ) {
503+ exists ( string namespace , string type , string name , string parameters |
504+ partialModel ( c , namespace , type , name , parameters ) and
505+ result =
506+ namespace + ";" //
507+ + type + ";" //
508+ + getCallableOverride ( c ) + ";" //
509+ + name + ";" //
510+ + parameters + ";" //
511+ + /* ext + */ ";" //
512+ )
513+ }
514+
515+ /** Computes the first 4 columns for neutral CSV rows of `c`. */
516+ string asPartialNeutralModel ( UnboundCallable c ) {
517+ exists ( string namespace , string type , string name , string parameters |
518+ partialModel ( c , namespace , type , name , parameters ) and
519+ result =
520+ namespace + ";" //
521+ + type + ";" //
522+ + name + ";" //
523+ + parameters + ";" //
524+ )
525+ }
0 commit comments