Skip to content

Commit 7ba25b2

Browse files
committed
C#: Copy dotnet.Generics implementation.
1 parent eb5cb2a commit 7ba25b2

File tree

1 file changed

+54
-11
lines changed

1 file changed

+54
-11
lines changed

csharp/ql/lib/semmle/code/csharp/Generics.qll

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ private import TypeRef
2323
* A generic declaration. Either an unbound generic (`UnboundGeneric`) or a
2424
* constructed generic (`ConstructedGeneric`).
2525
*/
26-
class Generic extends DotNet::Generic, Declaration, @generic {
26+
class Generic extends Declaration, @generic {
2727
Generic() {
2828
type_parameters(_, _, this, _) or
2929
type_arguments(_, _, this) or
@@ -37,16 +37,23 @@ class Generic extends DotNet::Generic, Declaration, @generic {
3737
* Either an unbound generic type (`UnboundGenericType`) or an unbound generic method
3838
* (`UnboundGenericMethod`).
3939
*/
40-
class UnboundGeneric extends DotNet::UnboundGeneric, Generic {
40+
class UnboundGeneric extends Generic {
4141
UnboundGeneric() { type_parameters(_, _, this, _) }
4242

43-
final override TypeParameter getTypeParameter(int n) { type_parameters(result, n, this, _) }
43+
/** Gets the `i`th type parameter, if any. */
44+
final TypeParameter getTypeParameter(int n) { type_parameters(result, n, this, _) }
4445

45-
override ConstructedGeneric getAConstructedGeneric() { result.getUnboundGeneric() = this }
46+
/** Gets a type parameter. */
47+
TypeParameter getATypeParameter() { result = this.getTypeParameter(_) }
4648

47-
override TypeParameter getATypeParameter() {
48-
result = DotNet::UnboundGeneric.super.getATypeParameter()
49-
}
49+
/**
50+
* Gets one of the constructed versions of this declaration,
51+
* which has been bound to a specific set of types.
52+
*/
53+
ConstructedGeneric getAConstructedGeneric() { result.getUnboundGeneric() = this }
54+
55+
/** Gets the total number of type parameters. */
56+
int getNumberOfTypeParameters() { result = count(int i | exists(this.getTypeParameter(i))) }
5057
}
5158

5259
/** Gets the type parameters as a comma-separated string. */
@@ -67,25 +74,61 @@ private string getTypeParameterBacktick(UnboundGeneric ug) {
6774
* Either a constructed generic type (`ConstructedType`) or a constructed
6875
* generic method (`ConstructedMethod`).
6976
*/
70-
class ConstructedGeneric extends DotNet::ConstructedGeneric, Generic {
77+
class ConstructedGeneric extends Generic {
7178
ConstructedGeneric() {
7279
type_arguments(_, _, this)
7380
or
7481
nullable_underlying_type(this, _)
7582
}
7683

77-
override UnboundGeneric getUnboundGeneric() { constructed_generic(this, result) }
84+
/**
85+
* Gets the unbound generic declaration from which this declaration was
86+
* constructed.
87+
*/
88+
UnboundGeneric getUnboundGeneric() { constructed_generic(this, result) }
7889

7990
override UnboundGeneric getUnboundDeclaration() {
8091
result = this.getUnboundGeneric().getUnboundDeclaration()
8192
}
8293

83-
override Type getTypeArgument(int i) { none() }
94+
/** Gets the `i`th type argument, if any. */
95+
Type getTypeArgument(int i) { none() }
8496

85-
override Type getATypeArgument() { result = this.getTypeArgument(_) }
97+
/** Gets a type argument. */
98+
Type getATypeArgument() { result = this.getTypeArgument(_) }
8699

87100
/** Gets the annotated type of type argument `i`. */
88101
final AnnotatedType getAnnotatedTypeArgument(int i) { result.appliesToTypeArgument(this, i) }
102+
103+
/** Gets the total number of type arguments. */
104+
final int getNumberOfTypeArguments() { result = count(int i | exists(this.getTypeArgument(i))) }
105+
}
106+
107+
/**
108+
* INTERNAL: Do not use.
109+
*
110+
* Constructs the label suffix for a generic method or type.
111+
*/
112+
string getGenericsLabel(Generic g) {
113+
result = "`" + g.(UnboundGeneric).getNumberOfTypeParameters()
114+
or
115+
result = "<" + typeArgs(g) + ">"
116+
}
117+
118+
pragma[noinline]
119+
private string getTypeArgumentLabel(ConstructedGeneric generic, int p) {
120+
result = generic.getTypeArgument(p).getLabel()
121+
}
122+
123+
language[monotonicAggregates]
124+
pragma[nomagic]
125+
private string typeArgs(ConstructedGeneric generic) {
126+
result =
127+
concat(int p |
128+
p in [0 .. generic.getNumberOfTypeArguments() - 1]
129+
|
130+
getTypeArgumentLabel(generic, p), ","
131+
)
89132
}
90133

91134
/** Gets the type arguments as a comma-separated string. */

0 commit comments

Comments
 (0)