Files
codeql/csharp/ql/lib/semmle/code/dotnet/Generics.qll

73 lines
2.0 KiB
Plaintext

/** Provides classes for generic types and methods. */
import Declaration
/**
* A generic declaration. Either an unbound generic (`UnboundGeneric`) or a
* constructed generic (`ConstructedGeneric`).
*/
abstract class Generic extends Declaration, @dotnet_generic { }
/** An unbound generic. */
abstract class UnboundGeneric extends Generic {
/** Gets the `i`th type parameter, if any. */
abstract TypeParameter getTypeParameter(int i);
/** Gets a type parameter. */
TypeParameter getATypeParameter() { result = getTypeParameter(_) }
/**
* Gets one of the constructed versions of this declaration,
* which has been bound to a specific set of types.
*/
ConstructedGeneric getAConstructedGeneric() { result.getUnboundGeneric() = this }
/** Gets the total number of type parameters. */
int getNumberOfTypeParameters() { result = count(int i | exists(this.getTypeParameter(i))) }
}
/** A constructed generic. */
abstract class ConstructedGeneric extends Generic {
/** Gets the `i`th type argument, if any. */
abstract Type getTypeArgument(int i);
/** Gets a type argument. */
Type getATypeArgument() { result = getTypeArgument(_) }
/**
* Gets the unbound generic declaration from which this declaration was
* constructed.
*/
UnboundGeneric getUnboundGeneric() { none() }
/** Gets the total number of type arguments. */
int getNumberOfTypeArguments() { result = count(int i | exists(this.getTypeArgument(i))) }
}
/**
* INTERNAL: Do not use.
*
* Constructs the label suffix for a generic method or type.
*/
string getGenericsLabel(Generic g) {
result = "`" + g.(UnboundGeneric).getNumberOfTypeParameters()
or
result = "<" + typeArgs(g) + ">"
}
pragma[noinline]
private string getTypeArgumentLabel(ConstructedGeneric generic, int p) {
result = generic.getTypeArgument(p).getLabel()
}
language[monotonicAggregates]
pragma[nomagic]
private string typeArgs(ConstructedGeneric generic) {
result =
concat(int p |
p in [0 .. generic.getNumberOfTypeArguments() - 1]
|
getTypeArgumentLabel(generic, p), ","
)
}