@@ -55,17 +55,50 @@ private predicate isObjectClass(Class c) { c instanceof ObjectType }
55
55
* Either a value type (`ValueType`) or a reference type (`RefType`).
56
56
*/
57
57
class ValueOrRefType extends DotNet:: ValueOrRefType , Type , Attributable , @value_or_ref_type {
58
+ /** Gets the name of this type without `<...>` brackets, in case it is a constructed type. */
59
+ private string getNameWithoutBrackets ( ) {
60
+ exists ( UnboundGenericType unbound , string name |
61
+ unbound = this .( ConstructedType ) .getUnboundDeclaration ( ) and
62
+ name = unbound .getName ( ) and
63
+ result = name .prefix ( name .length ( ) - unbound .getNumberOfTypeParameters ( ) - 1 )
64
+ )
65
+ or
66
+ not this instanceof ConstructedType and
67
+ result = this .getName ( )
68
+ }
69
+
70
+ language [ monotonicAggregates]
71
+ private string getQualifiedTypeArguments ( ) {
72
+ result =
73
+ strictconcat ( Type t , int i |
74
+ t = this .( ConstructedType ) .getTypeArgument ( i )
75
+ |
76
+ t .getQualifiedName ( ) , "," order by i
77
+ )
78
+ }
79
+
58
80
/**
59
81
* Holds if this type has the qualified name `qualifier`.`name`.
60
82
*
61
83
* For example the class `System.IO.IOException` has
62
84
* `qualifier`=`System.IO` and `name`=`IOException`.
63
85
*/
64
86
override predicate hasQualifiedName ( string qualifier , string name ) {
65
- name = this .getName ( ) and
66
- if exists ( this .getDeclaringType ( ) )
67
- then qualifier = this .getDeclaringType ( ) .getQualifiedName ( )
68
- else qualifier = this .getNamespace ( ) .getQualifiedName ( )
87
+ exists ( string name0 |
88
+ not this instanceof ConstructedType and
89
+ name = name0
90
+ or
91
+ name = name0 + "<" + this .getQualifiedTypeArguments ( ) + ">"
92
+ |
93
+ exists ( string enclosing |
94
+ this .getDeclaringType ( ) .hasQualifiedName ( qualifier , enclosing ) and
95
+ name0 = enclosing + "+" + this .getNameWithoutBrackets ( )
96
+ )
97
+ or
98
+ not exists ( this .getDeclaringType ( ) ) and
99
+ qualifier = this .getNamespace ( ) .getQualifiedName ( ) and
100
+ name0 = this .getNameWithoutBrackets ( )
101
+ )
69
102
}
70
103
71
104
/** Gets the namespace containing this type. */
@@ -994,6 +1027,13 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
994
1027
not type_location ( this , _) and
995
1028
result = this .getElementType ( ) .getALocation ( )
996
1029
}
1030
+
1031
+ final override predicate hasQualifiedName ( string qualifier , string name ) {
1032
+ exists ( Type elementType , string name0 |
1033
+ elementType .hasQualifiedName ( qualifier , name0 ) and
1034
+ name = name0 + this .getDimensionString ( elementType )
1035
+ )
1036
+ }
997
1037
}
998
1038
999
1039
/**
@@ -1013,6 +1053,13 @@ class PointerType extends DotNet::PointerType, Type, @pointer_type {
1013
1053
override string toString ( ) { result = DotNet:: PointerType .super .toString ( ) }
1014
1054
1015
1055
override string getAPrimaryQlClass ( ) { result = "PointerType" }
1056
+
1057
+ final override predicate hasQualifiedName ( string qualifier , string name ) {
1058
+ exists ( string name0 |
1059
+ this .getReferentType ( ) .hasQualifiedName ( qualifier , name0 ) and
1060
+ name = name0 + "*"
1061
+ )
1062
+ }
1016
1063
}
1017
1064
1018
1065
/**
@@ -1083,6 +1130,10 @@ class TupleType extends ValueType, @tuple_type {
1083
1130
override string getLabel ( ) { result = getUnderlyingType ( ) .getLabel ( ) }
1084
1131
1085
1132
override Type getChild ( int i ) { result = this .getUnderlyingType ( ) .getChild ( i ) }
1133
+
1134
+ final override predicate hasQualifiedName ( string qualifier , string name ) {
1135
+ this .getUnderlyingType ( ) .hasQualifiedName ( qualifier , name )
1136
+ }
1086
1137
}
1087
1138
1088
1139
/**
0 commit comments