mirror of
https://github.com/github/codeql.git
synced 2026-04-22 07:15:15 +02:00
Merge pull request #3341 from hvitved/csharp/generics-nested-types
Approved by calumgrant
This commit is contained in:
28
change-notes/1.25/analysis-csharp.md
Normal file
28
change-notes/1.25/analysis-csharp.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Improvements to C# analysis
|
||||
|
||||
The following changes in version 1.25 affect C# analysis in all applications.
|
||||
|
||||
## New queries
|
||||
|
||||
| **Query** | **Tags** | **Purpose** |
|
||||
|-----------------------------|-----------|--------------------------------------------------------------------|
|
||||
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|------------------------------|------------------------|-----------------------------------|
|
||||
|
||||
|
||||
## Removal of old queries
|
||||
|
||||
## Changes to code extraction
|
||||
|
||||
## Changes to libraries
|
||||
|
||||
* The class `UnboundGeneric` has been refined to only be those declarations that actually
|
||||
have type parameters. This means that non-generic nested types inside construced types,
|
||||
such as `A<int>.B`, no longer are considered unbound generics. (Such nested types do,
|
||||
however, still have relevant `.getSourceDeclaration()`s, for example `A<>.B`.)
|
||||
|
||||
## Changes to autobuilder
|
||||
@@ -340,7 +340,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
if (isFullyConstructed)
|
||||
{
|
||||
trapFile.is_constructed(this);
|
||||
trapFile.constructed_generic(this, Method.Create(Context, ConstructedFromSymbol));
|
||||
foreach (var tp in symbol.GetAnnotatedTypeArguments())
|
||||
{
|
||||
@@ -354,7 +353,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
trapFile.is_generic(this);
|
||||
foreach (var typeParam in symbol.TypeParameters.Select(tp => TypeParameter.Create(Context, tp)))
|
||||
{
|
||||
trapFile.type_parameters(typeParam, child, this);
|
||||
|
||||
@@ -40,8 +40,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
else if (symbol.IsReallyUnbound())
|
||||
{
|
||||
trapFile.is_generic(this);
|
||||
|
||||
for (int i = 0; i < symbol.TypeParameters.Length; ++i)
|
||||
{
|
||||
TypeParameter.Create(Context, symbol.TypeParameters[i]);
|
||||
@@ -52,7 +50,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
trapFile.is_constructed(this);
|
||||
trapFile.constructed_generic(this, Type.Create(Context, symbol.ConstructedFrom).TypeRef);
|
||||
|
||||
for (int i = 0; i < symbol.TypeArguments.Length; ++i)
|
||||
|
||||
@@ -306,16 +306,6 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.WriteTuple("indexers", propKey, name, declaringType, memberType, unboundProperty);
|
||||
}
|
||||
|
||||
internal static void is_constructed(this TextWriter trapFile, IEntity typeOrMethod)
|
||||
{
|
||||
trapFile.WriteTuple("is_constructed", typeOrMethod);
|
||||
}
|
||||
|
||||
internal static void is_generic(this TextWriter trapFile, IEntity typeOrMethod)
|
||||
{
|
||||
trapFile.WriteTuple("is_generic", typeOrMethod);
|
||||
}
|
||||
|
||||
internal static void local_function_stmts(this TextWriter trapFile, Entities.Statements.LocalFunction fnStmt, LocalFunction fn)
|
||||
{
|
||||
trapFile.WriteTuple("local_function_stmts", fnStmt, fn);
|
||||
|
||||
@@ -23,19 +23,19 @@ private import dotnet
|
||||
*/
|
||||
class Generic extends DotNet::Generic, Declaration, @generic {
|
||||
Generic() {
|
||||
is_generic(this) or
|
||||
is_constructed(this)
|
||||
type_parameters(_, _, this, _) or
|
||||
type_arguments(_, _, this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic declaration that can have type parameters.
|
||||
* A generic declaration with type parameters.
|
||||
*
|
||||
* Either an unbound generic type (`UnboundGenericType`) or an unbound generic method
|
||||
* (`UnboundGenericMethod`).
|
||||
*/
|
||||
class UnboundGeneric extends DotNet::UnboundGeneric, Generic {
|
||||
UnboundGeneric() { is_generic(this) }
|
||||
UnboundGeneric() { type_parameters(_, _, this, _) }
|
||||
|
||||
override TypeParameter getTypeParameter(int n) { type_parameters(result, n, this, _) }
|
||||
|
||||
@@ -47,13 +47,13 @@ class UnboundGeneric extends DotNet::UnboundGeneric, Generic {
|
||||
}
|
||||
|
||||
/**
|
||||
* A declaration constructed from an `UnboundGeneric` by supplying type arguments.
|
||||
* A constructed generic.
|
||||
*
|
||||
* Either a constructed generic type (`ConstructedType`) or a constructed
|
||||
* generic method (`ConstructedMethod`).
|
||||
*/
|
||||
class ConstructedGeneric extends DotNet::ConstructedGeneric, Generic {
|
||||
ConstructedGeneric() { is_constructed(this) }
|
||||
ConstructedGeneric() { type_arguments(_, _, this) }
|
||||
|
||||
override UnboundGeneric getUnboundGeneric() { constructed_generic(this, result) }
|
||||
|
||||
@@ -61,10 +61,7 @@ class ConstructedGeneric extends DotNet::ConstructedGeneric, Generic {
|
||||
result = getUnboundGeneric().getSourceDeclaration()
|
||||
}
|
||||
|
||||
override int getNumberOfTypeArguments() {
|
||||
// getTypeArgument() could fail if the type does not exist in the database
|
||||
result = count(int i | type_arguments(_, i, this))
|
||||
}
|
||||
override int getNumberOfTypeArguments() { result = count(int i | type_arguments(_, i, this)) }
|
||||
|
||||
override Type getTypeArgument(int i) { none() }
|
||||
|
||||
@@ -84,11 +81,12 @@ class ConstructedGeneric extends DotNet::ConstructedGeneric, Generic {
|
||||
*/
|
||||
class UnboundGenericType extends ValueOrRefType, UnboundGeneric {
|
||||
/**
|
||||
* Gets a bound/constructed version of this unbound generic type. This includes not only closed constructed types such as `G<int>`,
|
||||
* but also open constructed types such as the `G<T>` in `class Other<T> { G<T> g; }`. Note that such a type is distinct from the
|
||||
* `G<T>` used in the class definition, since in `G<T> g;` the `T` will be the actual type parameter used for the `Other` that contains
|
||||
* `g`, whereas in `class G<T> { ... }` the `T` is a formal type parameter of `G`. It is important not to get confused by the superficial
|
||||
* syntactic similarity.
|
||||
* Gets a bound/constructed version of this unbound generic type. This includes
|
||||
* not only closed constructed types such as `G<int>`, but also open constructed
|
||||
* types such as the `G<T>` in `class Other<T> { G<T> g; }`. Note that such a type
|
||||
* is distinct from the `G<T>` used in the class definition, since in `G<T> g;`
|
||||
* the `T` will be the actual type parameter used for the `Other` that contains
|
||||
* `g`, whereas in `class G<T> { ... }` the `T` is a formal type parameter of `G`.
|
||||
*/
|
||||
override ConstructedType getAConstructedGeneric() {
|
||||
result = UnboundGeneric.super.getAConstructedGeneric()
|
||||
@@ -350,15 +348,16 @@ class UnboundGenericDelegateType extends DelegateType, UnboundGenericType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructed (bound) type. This is a generic type for which actual type arguments have been supplied,
|
||||
* for example `G<int>` or the `G<T>` in `class Other<T> { G<T> g; }`. Constructed types can be divided further into
|
||||
* those that are open (for example `G1<T>` or `G2<T,T,U,int>`), in the sense that one or more of their type arguments
|
||||
* is a type parameter, versus those that are closed (for example `G1<int>` or `G2<long,long,float,int>`). We do not
|
||||
* currently distinguish the two in this library.
|
||||
* A constructed (bound) type. This is a generic type for which actual type
|
||||
* arguments have been supplied, for example `G<int>` or the `G<T>` in
|
||||
* `class Other<T> { G<T> g; }`. Constructed types can be divided further into
|
||||
* those that are open (for example `G1<T>` or `G2<T,T,U,int>`), in the sense
|
||||
* that one or more of their type arguments is a type parameter, versus those
|
||||
* that are closed (for example `G1<int>` or `G2<long,long,float,int>`).
|
||||
*
|
||||
* Either a constructed `struct` (`ConstructedStruct`), constructed `class` (`ConstructedClass`),
|
||||
* constructed `interface` (`ConstructedInterface`), or constructed method
|
||||
* (`ConstructedMethod`).
|
||||
* Either a constructed `struct` (`ConstructedStruct`), constructed `class`
|
||||
* (`ConstructedClass`), constructed `interface` (`ConstructedInterface`),
|
||||
* or constructed method (`ConstructedMethod`).
|
||||
*/
|
||||
class ConstructedType extends ValueOrRefType, ConstructedGeneric {
|
||||
override UnboundGenericType getSourceDeclaration() {
|
||||
|
||||
@@ -13,7 +13,7 @@ abstract class UnboundGeneric extends Generic {
|
||||
/** Gets the `i`th type parameter, if any. */
|
||||
abstract TypeParameter getTypeParameter(int i);
|
||||
|
||||
/** Gets a type parameter, if any. */
|
||||
/** Gets a type parameter. */
|
||||
TypeParameter getATypeParameter() { result = getTypeParameter(_) }
|
||||
|
||||
/**
|
||||
@@ -42,10 +42,13 @@ abstract class ConstructedGeneric extends Generic {
|
||||
/** Gets the `i`th type argument, if any. */
|
||||
abstract Type getTypeArgument(int i);
|
||||
|
||||
/** Gets a type argument, if any. */
|
||||
/** Gets a type argument. */
|
||||
Type getATypeArgument() { result = getTypeArgument(_) }
|
||||
|
||||
/** Gets the unbound generic declaration from which this declaration was constructed. */
|
||||
/**
|
||||
* Gets the unbound generic declaration from which this declaration was
|
||||
* constructed.
|
||||
*/
|
||||
UnboundGeneric getUnboundGeneric() { none() }
|
||||
|
||||
/** Gets the total number of type arguments. */
|
||||
|
||||
@@ -497,10 +497,6 @@ expr_flowstate(unique int id: @expr ref, int state: int ref);
|
||||
|
||||
@generic = @type | @method | @local_function;
|
||||
|
||||
is_generic(unique int id: @generic ref);
|
||||
|
||||
is_constructed(unique int id: @generic ref);
|
||||
|
||||
type_parameters(
|
||||
unique int id: @type_parameter ref,
|
||||
int index: int ref,
|
||||
|
||||
@@ -15479,28 +15479,6 @@
|
||||
</dependencies>
|
||||
</relation>
|
||||
<relation>
|
||||
<name>is_generic</name>
|
||||
<cardinality>77320</cardinality>
|
||||
<columnsizes>
|
||||
<e>
|
||||
<k>id</k>
|
||||
<v>77320</v>
|
||||
</e>
|
||||
</columnsizes>
|
||||
<dependencies/>
|
||||
</relation>
|
||||
<relation>
|
||||
<name>is_constructed</name>
|
||||
<cardinality>358124</cardinality>
|
||||
<columnsizes>
|
||||
<e>
|
||||
<k>id</k>
|
||||
<v>358124</v>
|
||||
</e>
|
||||
</columnsizes>
|
||||
<dependencies/>
|
||||
</relation>
|
||||
<relation>
|
||||
<name>type_parameters</name>
|
||||
<cardinality>84292</cardinality>
|
||||
<columnsizes>
|
||||
|
||||
178
csharp/ql/test/library-tests/generics/Generics.expected
Normal file
178
csharp/ql/test/library-tests/generics/Generics.expected
Normal file
@@ -0,0 +1,178 @@
|
||||
test1
|
||||
| generics.cs:7:23:7:40 | GenericDelegate<> |
|
||||
test2
|
||||
| generics.cs:9:18:9:18 | A |
|
||||
test3
|
||||
| generics.cs:13:18:13:21 | A<X> | generics.cs:13:18:13:21 | A<> |
|
||||
test4
|
||||
test5
|
||||
test6
|
||||
| generics.cs:13:18:13:21 | A<T> | generics.cs:22:18:22:21 | B<> | generics.cs:22:18:22:21 | B<X> | generics.cs:25:23:25:24 | at |
|
||||
test7
|
||||
| Nesting.cs:1:14:1:18 | A<String> | Nesting.cs:6:18:6:22 | B<String> |
|
||||
| Nesting.cs:1:14:1:18 | A<String> | generics.cs:22:18:22:21 | B<String> |
|
||||
| generics.cs:13:18:13:21 | A<String> | Nesting.cs:6:18:6:22 | B<String> |
|
||||
| generics.cs:13:18:13:21 | A<String> | generics.cs:22:18:22:21 | B<String> |
|
||||
test8
|
||||
| generics.cs:22:18:22:21 | B<String> | generics.cs:31:21:31:29 | fooParams |
|
||||
test9
|
||||
| generics.cs:22:18:22:21 | B<String> | generics.cs:35:51:35:53 | set_Name | generics.cs:35:51:35:53 | set_Name |
|
||||
test10
|
||||
| generics.cs:22:18:22:21 | B<String> | generics.cs:37:41:37:47 | myEvent |
|
||||
test11
|
||||
| generics.cs:22:18:22:21 | B<String> | generics.cs:39:37:39:38 | ++ |
|
||||
test12
|
||||
| generics.cs:60:18:60:24 | Grid<Int32> | generics.cs:73:18:73:21 | Item |
|
||||
test13
|
||||
| generics.cs:60:18:60:24 | Grid<Int32> | generics.cs:68:20:68:23 | Item |
|
||||
| generics.cs:60:18:60:24 | Grid<Int32> | generics.cs:73:18:73:21 | Item |
|
||||
test14
|
||||
| generics.cs:60:18:60:24 | Grid<> | generics.cs:68:20:68:23 | Item |
|
||||
test15
|
||||
| generics.cs:7:23:7:40 | GenericDelegate<String> |
|
||||
test16
|
||||
| generics.cs:134:11:134:16 | Subtle | generics.cs:137:21:137:25 | fs |
|
||||
| generics.cs:134:11:134:16 | Subtle | generics.cs:139:21:139:25 | fs |
|
||||
| generics.cs:134:11:134:16 | Subtle | generics.cs:141:21:141:22 | fs |
|
||||
test17
|
||||
| generics.cs:134:11:134:16 | Subtle | generics.cs:137:24:137:24 | X | generics.cs:137:21:137:25 | fs | generics.cs:139:24:139:24 | X | generics.cs:139:21:139:25 | fs | 1 |
|
||||
| generics.cs:134:11:134:16 | Subtle | generics.cs:139:24:139:24 | X | generics.cs:139:21:139:25 | fs | generics.cs:137:24:137:24 | X | generics.cs:137:21:137:25 | fs | 2 |
|
||||
test18
|
||||
| Nesting.cs:1:14:1:18 | A<> | Nesting.cs:3:17:3:19 | MA1 | Nesting.cs:3:24:3:24 | x | 0 | T1 | 1 | 1 |
|
||||
| Nesting.cs:1:14:1:18 | A<> | Nesting.cs:4:17:4:23 | MA2 | Nesting.cs:4:28:4:28 | x | 0 | T1 | 2 | 2 |
|
||||
| Nesting.cs:1:14:1:18 | A<> | Nesting.cs:4:17:4:23 | MA2 | Nesting.cs:4:34:4:34 | y | 0 | T2 | 2 | 2 |
|
||||
| Nesting.cs:1:14:1:18 | A<Int32> | Nesting.cs:3:17:3:19 | MA1 | Nesting.cs:3:24:3:24 | x | 0 | Int32 | 1 | 1 |
|
||||
| Nesting.cs:1:14:1:18 | A<Int32> | Nesting.cs:4:17:4:23 | MA2 | Nesting.cs:4:28:4:28 | x | 0 | Int32 | 2 | 2 |
|
||||
| Nesting.cs:1:14:1:18 | A<Int32> | Nesting.cs:4:17:4:23 | MA2 | Nesting.cs:4:28:4:28 | x | 1 | Int32 | 2 | 2 |
|
||||
| Nesting.cs:1:14:1:18 | A<Int32> | Nesting.cs:4:17:4:23 | MA2 | Nesting.cs:4:34:4:34 | y | 0 | T2 | 2 | 2 |
|
||||
| Nesting.cs:1:14:1:18 | A<Int32> | Nesting.cs:4:17:4:23 | MA2 | Nesting.cs:4:34:4:34 | y | 1 | String | 2 | 2 |
|
||||
| Nesting.cs:1:14:1:18 | A<String> | Nesting.cs:3:17:3:19 | MA1 | Nesting.cs:3:24:3:24 | x | 0 | String | 1 | 1 |
|
||||
| Nesting.cs:1:14:1:18 | A<String> | Nesting.cs:4:17:4:23 | MA2 | Nesting.cs:4:28:4:28 | x | 0 | String | 2 | 2 |
|
||||
| Nesting.cs:1:14:1:18 | A<String> | Nesting.cs:4:17:4:23 | MA2 | Nesting.cs:4:28:4:28 | x | 1 | String | 2 | 2 |
|
||||
| Nesting.cs:1:14:1:18 | A<String> | Nesting.cs:4:17:4:23 | MA2 | Nesting.cs:4:34:4:34 | y | 0 | T2 | 2 | 2 |
|
||||
| Nesting.cs:1:14:1:18 | A<String> | Nesting.cs:4:17:4:23 | MA2 | Nesting.cs:4:34:4:34 | y | 1 | Int32 | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<> | generics.cs:18:18:18:23 | bar | generics.cs:18:27:18:27 | x | 0 | X | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<> | generics.cs:18:18:18:23 | bar | generics.cs:18:32:18:32 | t | 0 | T | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<Int32> | generics.cs:18:18:18:23 | bar | generics.cs:18:27:18:27 | x | 0 | X | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<Int32> | generics.cs:18:18:18:23 | bar | generics.cs:18:27:18:27 | x | 1 | Test | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<Int32> | generics.cs:18:18:18:23 | bar | generics.cs:18:32:18:32 | t | 0 | Int32 | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<Int32> | generics.cs:18:18:18:23 | bar | generics.cs:18:32:18:32 | t | 1 | Int32 | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<String> | generics.cs:18:18:18:23 | bar | generics.cs:18:27:18:27 | x | 0 | X | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<String> | generics.cs:18:18:18:23 | bar | generics.cs:18:27:18:27 | x | 1 | Int32 | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<String> | generics.cs:18:18:18:23 | bar | generics.cs:18:32:18:32 | t | 0 | String | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<String> | generics.cs:18:18:18:23 | bar | generics.cs:18:32:18:32 | t | 1 | String | 2 | 2 |
|
||||
test19
|
||||
| generics.cs:137:21:137:25 | fs | generics.cs:137:24:137:24 | X | 1 |
|
||||
| generics.cs:139:21:139:25 | fs | generics.cs:139:24:139:24 | X | 1 |
|
||||
test20
|
||||
test21
|
||||
| generics.cs:147:14:147:14 | E | generics.cs:145:11:145:18 | Param<> |
|
||||
test22
|
||||
| generics.cs:152:14:152:19 | CM1 | Double |
|
||||
| generics.cs:152:14:152:19 | CM1 | Int32 |
|
||||
| generics.cs:153:11:153:16 | CM2 | Double |
|
||||
| generics.cs:153:11:153:16 | CM2 | Int32 |
|
||||
| generics.cs:157:23:157:29 | CM3 | Double |
|
||||
| generics.cs:157:23:157:29 | CM3 | Double |
|
||||
test23
|
||||
| generics.cs:178:11:178:24 | Inheritance<> | generics.cs:173:15:173:26 | Interface<T> |
|
||||
| generics.cs:178:11:178:24 | Inheritance<Int32> | generics.cs:173:15:173:26 | Interface<Int32> |
|
||||
test24
|
||||
| generics.cs:188:15:188:39 | Interface2<,> | generics.cs:188:29:188:30 | T1 | in |
|
||||
| generics.cs:188:15:188:39 | Interface2<,> | generics.cs:188:37:188:38 | T2 | out |
|
||||
test25
|
||||
| generics.cs:157:23:157:29 | CM3 |
|
||||
test26
|
||||
test27
|
||||
| Nesting.cs:6:18:6:22 | B<Int32> | Nesting.cs:6:18:6:22 | B<> | Nesting.cs:6:18:6:22 | B<> |
|
||||
| Nesting.cs:6:18:6:22 | B<String> | Nesting.cs:6:18:6:22 | B<> | Nesting.cs:6:18:6:22 | B<> |
|
||||
| Nesting.cs:17:22:17:26 | D<Boolean> | Nesting.cs:17:22:17:26 | D<> | Nesting.cs:17:22:17:26 | D<> |
|
||||
| Nesting.cs:17:22:17:26 | D<Decimal> | Nesting.cs:17:22:17:26 | D<> | Nesting.cs:17:22:17:26 | D<> |
|
||||
| generics.cs:51:22:51:29 | Inner<String> | generics.cs:51:22:51:29 | Inner<> | generics.cs:51:22:51:29 | Inner<> |
|
||||
test28
|
||||
| Nesting.cs:4:17:4:23 | MA2 | A<>.MA2<T2>(T1, T2) |
|
||||
| Nesting.cs:4:17:4:23 | MA2 | A<Int32>.MA2<T2>(int, T2) |
|
||||
| Nesting.cs:4:17:4:23 | MA2 | A<String>.MA2<T2>(string, T2) |
|
||||
| Nesting.cs:6:18:6:22 | B<> | A<>.B<T3> |
|
||||
| Nesting.cs:6:18:6:22 | B<> | A<Int32>.B<T3> |
|
||||
| Nesting.cs:6:18:6:22 | B<> | A<String>.B<T3> |
|
||||
| Nesting.cs:9:21:9:27 | MB2 | A<>.B<>.MB2<T4>(T1, T3, T4) |
|
||||
| Nesting.cs:9:21:9:27 | MB2 | A<Int32>.B<String>.MB2<T4>(int, string, T4) |
|
||||
| Nesting.cs:9:21:9:27 | MB2 | A<String>.B<Int32>.MB2<T4>(string, int, T4) |
|
||||
| Nesting.cs:15:21:15:27 | MC2 | A<>.C.MC2<T5>(T1, T5) |
|
||||
| Nesting.cs:15:21:15:27 | MC2 | A<Int32>.C.MC2<T5>(int, T5) |
|
||||
| Nesting.cs:15:21:15:27 | MC2 | A<String>.C.MC2<T5>(string, T5) |
|
||||
| Nesting.cs:17:22:17:26 | D<> | A<>.C.D<T6> |
|
||||
| Nesting.cs:17:22:17:26 | D<> | A<Int32>.C.D<T6> |
|
||||
| Nesting.cs:17:22:17:26 | D<> | A<String>.C.D<T6> |
|
||||
| Nesting.cs:20:25:20:31 | MD2 | A<>.C.D<>.MD2<T7>(T1, T6, T7) |
|
||||
| Nesting.cs:20:25:20:31 | MD2 | A<Int32>.C.D<Boolean>.MD2<T7>(int, bool, T7) |
|
||||
| Nesting.cs:20:25:20:31 | MD2 | A<String>.C.D<Decimal>.MD2<T7>(string, decimal, T7) |
|
||||
| generics.cs:16:27:16:58 | GenericDelegateInGenericClass<> | generics.A<>.GenericDelegateInGenericClass<U>(T, U) |
|
||||
| generics.cs:16:27:16:58 | GenericDelegateInGenericClass<> | generics.A<Int32>.GenericDelegateInGenericClass<U>(int, U) |
|
||||
| generics.cs:16:27:16:58 | GenericDelegateInGenericClass<> | generics.A<String>.GenericDelegateInGenericClass<U>(string, U) |
|
||||
| generics.cs:18:18:18:23 | bar | generics.A<>.bar<X>(X, T) |
|
||||
| generics.cs:18:18:18:23 | bar | generics.A<Int32>.bar<X>(X, int) |
|
||||
| generics.cs:18:18:18:23 | bar | generics.A<String>.bar<X>(X, string) |
|
||||
| generics.cs:45:14:45:17 | f | generics.B<>.f<X>() |
|
||||
| generics.cs:45:14:45:17 | f | generics.B<Object>.f<X>() |
|
||||
| generics.cs:45:14:45:17 | f | generics.B<String>.f<X>() |
|
||||
| generics.cs:45:14:45:17 | f | generics.B<X>.f<X>() |
|
||||
| generics.cs:51:22:51:29 | Inner<> | generics.Outer<>.Inner<U> |
|
||||
| generics.cs:51:22:51:29 | Inner<> | generics.Outer<Object>.Inner<U> |
|
||||
| generics.cs:137:21:137:25 | fs | generics.Subtle.fs<X>(int) |
|
||||
| generics.cs:139:21:139:25 | fs | generics.Subtle.fs<X>(int, int) |
|
||||
| generics.cs:152:14:152:19 | CM1 | generics.ConstructedMethods.CM1<T>() |
|
||||
| generics.cs:153:11:153:16 | CM2 | generics.ConstructedMethods.CM2<T>(T) |
|
||||
| generics.cs:155:15:155:23 | Class<> | generics.ConstructedMethods.Class<T1> |
|
||||
| generics.cs:157:23:157:29 | CM3 | generics.ConstructedMethods.Class<>.CM3<T2>(T2, T1) |
|
||||
| generics.cs:157:23:157:29 | CM3 | generics.ConstructedMethods.Class<Double>.CM3<T2>(T2, double) |
|
||||
| generics.cs:157:23:157:29 | CM3 | generics.ConstructedMethods.Class<Int32>.CM3<T2>(T2, int) |
|
||||
test29
|
||||
| Nesting.cs:4:17:4:23 | MA2 | A<Int32>.MA2<string>(int, string) |
|
||||
| Nesting.cs:4:17:4:23 | MA2 | A<String>.MA2<int>(string, int) |
|
||||
| Nesting.cs:6:18:6:22 | B<Int32> | A<String>.B<Int32> |
|
||||
| Nesting.cs:6:18:6:22 | B<String> | A<Int32>.B<String> |
|
||||
| Nesting.cs:9:21:9:27 | MB2 | A<Int32>.B<String>.MB2<bool>(int, string, bool) |
|
||||
| Nesting.cs:9:21:9:27 | MB2 | A<String>.B<Int32>.MB2<bool>(string, int, bool) |
|
||||
| Nesting.cs:15:21:15:27 | MC2 | A<Int32>.C.MC2<bool>(int, bool) |
|
||||
| Nesting.cs:15:21:15:27 | MC2 | A<String>.C.MC2<bool>(string, bool) |
|
||||
| Nesting.cs:17:22:17:26 | D<Boolean> | A<Int32>.C.D<Boolean> |
|
||||
| Nesting.cs:17:22:17:26 | D<Decimal> | A<String>.C.D<Decimal> |
|
||||
| Nesting.cs:20:25:20:31 | MD2 | A<Int32>.C.D<Boolean>.MD2<string>(int, bool, string) |
|
||||
| Nesting.cs:20:25:20:31 | MD2 | A<String>.C.D<Decimal>.MD2<bool>(string, decimal, bool) |
|
||||
| generics.cs:18:18:18:23 | bar | generics.A<Int32>.bar<Test>(Test, int) |
|
||||
| generics.cs:18:18:18:23 | bar | generics.A<String>.bar<int>(int, string) |
|
||||
| generics.cs:51:22:51:29 | Inner<String> | generics.Outer<Object>.Inner<String> |
|
||||
| generics.cs:152:14:152:19 | CM1 | generics.ConstructedMethods.CM1<double>() |
|
||||
| generics.cs:152:14:152:19 | CM1 | generics.ConstructedMethods.CM1<int>() |
|
||||
| generics.cs:153:11:153:16 | CM2 | generics.ConstructedMethods.CM2<double>(double) |
|
||||
| generics.cs:153:11:153:16 | CM2 | generics.ConstructedMethods.CM2<int>(int) |
|
||||
| generics.cs:155:15:155:23 | Class<Double> | generics.ConstructedMethods.Class<Double> |
|
||||
| generics.cs:155:15:155:23 | Class<Int32> | generics.ConstructedMethods.Class<Int32> |
|
||||
| generics.cs:157:23:157:29 | CM3 | generics.ConstructedMethods.Class<Double>.CM3<double>(double, double) |
|
||||
| generics.cs:157:23:157:29 | CM3 | generics.ConstructedMethods.Class<Int32>.CM3<double>(double, int) |
|
||||
test30
|
||||
| Nesting.cs:3:17:3:19 | MA1 | A<Int32>.MA1(int) |
|
||||
| Nesting.cs:3:17:3:19 | MA1 | A<String>.MA1(string) |
|
||||
| Nesting.cs:8:21:8:23 | MB1 | A<Int32>.B<String>.MB1(int, string) |
|
||||
| Nesting.cs:8:21:8:23 | MB1 | A<String>.B<Int32>.MB1(string, int) |
|
||||
| Nesting.cs:12:18:12:18 | C | A<Int32>.C |
|
||||
| Nesting.cs:12:18:12:18 | C | A<String>.C |
|
||||
| Nesting.cs:14:21:14:23 | MC1 | A<Int32>.C.MC1(int) |
|
||||
| Nesting.cs:14:21:14:23 | MC1 | A<String>.C.MC1(string) |
|
||||
| Nesting.cs:19:25:19:27 | MD1 | A<Int32>.C.D<Boolean>.MD1(int, bool) |
|
||||
| Nesting.cs:19:25:19:27 | MD1 | A<String>.C.D<Decimal>.MD1(string, decimal) |
|
||||
| Nesting.cs:24:10:24:18 | Construct | A<Int32>.Construct() |
|
||||
| Nesting.cs:24:10:24:18 | Construct | A<String>.Construct() |
|
||||
| generics.cs:29:21:29:23 | foo | generics.B<Object>.foo() |
|
||||
| generics.cs:29:21:29:23 | foo | generics.B<String>.foo() |
|
||||
| generics.cs:29:21:29:23 | foo | generics.B<X>.foo() |
|
||||
| generics.cs:31:21:31:29 | fooParams | generics.B<Object>.fooParams(params Object[]) |
|
||||
| generics.cs:31:21:31:29 | fooParams | generics.B<String>.fooParams(params String[]) |
|
||||
| generics.cs:31:21:31:29 | fooParams | generics.B<X>.fooParams(params X[]) |
|
||||
| generics.cs:33:28:33:36 | staticFoo | generics.B<Object>.staticFoo() |
|
||||
| generics.cs:33:28:33:36 | staticFoo | generics.B<String>.staticFoo() |
|
||||
| generics.cs:33:28:33:36 | staticFoo | generics.B<X>.staticFoo() |
|
||||
| generics.cs:175:14:175:16 | set | generics.Interface<T>.set(T) |
|
||||
test31
|
||||
252
csharp/ql/test/library-tests/generics/Generics.ql
Normal file
252
csharp/ql/test/library-tests/generics/Generics.ql
Normal file
@@ -0,0 +1,252 @@
|
||||
import csharp
|
||||
|
||||
query predicate test1(UnboundGenericDelegateType d) {
|
||||
d.hasName("GenericDelegate<>") and
|
||||
d.getTypeParameter(0).hasName("T") and
|
||||
d.getParameter(0).getType().hasName("T")
|
||||
}
|
||||
|
||||
query predicate test2(Class c) {
|
||||
c.hasName("A") and
|
||||
not c instanceof UnboundGenericClass
|
||||
}
|
||||
|
||||
query predicate test3(ConstructedClass c, UnboundGenericClass d) {
|
||||
d.hasName("A<>") and
|
||||
c.getTypeArgument(0).hasName("X") and
|
||||
c.getTypeArgument(0) instanceof TypeParameter and
|
||||
c.getUnboundGeneric() = d
|
||||
}
|
||||
|
||||
query predicate test4(UnboundGenericClass c, string s) {
|
||||
c.fromSource() and
|
||||
not c.getName().matches("%<%>") and
|
||||
s = "Unbound generic class with inconsistent name"
|
||||
}
|
||||
|
||||
query predicate test5(ConstructedClass c, string s) {
|
||||
c.fromSource() and
|
||||
not c.getName().matches("%<%>") and
|
||||
s = "Constructed class with inconsistent name"
|
||||
}
|
||||
|
||||
query predicate test6(ConstructedClass at, UnboundGenericClass b, ConstructedClass bt, Field f) {
|
||||
at.hasName("A<T>") and
|
||||
b.hasName("B<>") and
|
||||
bt.hasName("B<X>") and
|
||||
at.getTypeArgument(0).hasName("T") and
|
||||
at.getTypeArgument(0) instanceof TypeParameter and
|
||||
at.getTypeArgument(0) = b.getTypeParameter(0) and
|
||||
bt.getUnboundGeneric() = b and
|
||||
f.getDeclaringType() = b and
|
||||
f.getType() = at
|
||||
}
|
||||
|
||||
query predicate test7(ConstructedClass aString, ConstructedClass bString) {
|
||||
aString.hasName("A<String>") and
|
||||
bString.hasName("B<String>") and
|
||||
aString.getSourceDeclaration().hasName("A<>") and
|
||||
bString.getSourceDeclaration().hasName("B<>")
|
||||
}
|
||||
|
||||
query predicate test8(ConstructedClass bString, Method m) {
|
||||
bString.hasName("B<String>") and
|
||||
m.getDeclaringType() = bString and
|
||||
m.hasName("fooParams") and
|
||||
m.getParameter(0).getType().(ArrayType).getElementType() instanceof StringType and
|
||||
m.getSourceDeclaration().getDeclaringType() = m.getDeclaringType().getSourceDeclaration()
|
||||
}
|
||||
|
||||
query predicate test9(ConstructedClass bString, Setter sourceSetter, Setter setter) {
|
||||
exists(Property p |
|
||||
bString.hasName("B<String>") and
|
||||
p.getDeclaringType() = bString and
|
||||
p.hasName("Name") and
|
||||
p.getSourceDeclaration().getDeclaringType() = p.getDeclaringType().getSourceDeclaration() and
|
||||
p.getSetter().getParameter(0).getType() instanceof StringType and
|
||||
p.getSetter().getSourceDeclaration() = p.getSourceDeclaration().getSetter() and
|
||||
p.getGetter().getSourceDeclaration() = p.getSourceDeclaration().getGetter() and
|
||||
sourceSetter = p.getSourceDeclaration().getSetter() and
|
||||
setter = p.getSetter()
|
||||
)
|
||||
}
|
||||
|
||||
query predicate test10(ConstructedClass bString, Event e) {
|
||||
bString.hasName("B<String>") and
|
||||
e.getDeclaringType() = bString and
|
||||
e.hasName("myEvent") and
|
||||
e.getSourceDeclaration().getDeclaringType() = e.getDeclaringType().getSourceDeclaration() and
|
||||
e.getType().(ConstructedDelegateType).getTypeArgument(0) instanceof StringType and
|
||||
e.getAddEventAccessor().getSourceDeclaration() = e.getSourceDeclaration().getAddEventAccessor() and
|
||||
e.getRemoveEventAccessor().getSourceDeclaration() =
|
||||
e.getSourceDeclaration().getRemoveEventAccessor()
|
||||
}
|
||||
|
||||
query predicate test11(ConstructedClass bString, Operator o) {
|
||||
bString.hasName("B<String>") and
|
||||
o.getDeclaringType() = bString and
|
||||
o instanceof IncrementOperator and
|
||||
o.getSourceDeclaration().getDeclaringType() = o.getDeclaringType().getSourceDeclaration()
|
||||
}
|
||||
|
||||
query predicate test12(ConstructedClass gridInt, Indexer i) {
|
||||
gridInt.hasName("Grid<Int32>") and
|
||||
i.getDeclaringType() = gridInt and
|
||||
i.getSourceDeclaration().getDeclaringType() = i.getDeclaringType().getSourceDeclaration() and
|
||||
i.getGetter().getSourceDeclaration() = i.getSourceDeclaration().getGetter() and
|
||||
i.getSetter().getSourceDeclaration() = i.getSourceDeclaration().getSetter()
|
||||
}
|
||||
|
||||
query predicate test13(ConstructedClass gridInt, Indexer i) {
|
||||
gridInt.hasName("Grid<Int32>") and
|
||||
i.getDeclaringType() = gridInt and
|
||||
i.getType() instanceof IntType
|
||||
}
|
||||
|
||||
query predicate test14(UnboundGenericClass gridInt, Indexer i) {
|
||||
gridInt.hasName("Grid<>") and
|
||||
i.getDeclaringType() = gridInt and
|
||||
i.getType() instanceof IntType
|
||||
}
|
||||
|
||||
query predicate test15(ConstructedDelegateType d) {
|
||||
d.hasName("GenericDelegate<String>") and
|
||||
d.getTypeArgument(0) instanceof StringType and
|
||||
d.getParameter(0).getType() instanceof StringType
|
||||
}
|
||||
|
||||
query predicate test16(Class c, Method m) {
|
||||
c.hasName("Subtle") and
|
||||
count(c.getAMethod()) = 3 and
|
||||
m = c.getAMethod()
|
||||
}
|
||||
|
||||
query predicate test17(
|
||||
Class c, TypeParameter p, UnboundGenericMethod m, TypeParameter q, UnboundGenericMethod n,
|
||||
int numParams
|
||||
) {
|
||||
c.hasName("Subtle") and
|
||||
m = c.getAMethod() and
|
||||
m.getATypeParameter() = p and
|
||||
n = c.getAMethod() and
|
||||
n.getATypeParameter() = q and
|
||||
m != n and
|
||||
p != q and
|
||||
numParams = m.getNumberOfParameters()
|
||||
}
|
||||
|
||||
query predicate test18(
|
||||
Class c, Method m, Parameter p, int numArgs, string typeName, int numParams, int numTypes
|
||||
) {
|
||||
c.getName().matches("A<%") and
|
||||
m = c.getAMethod() and
|
||||
p = m.getAParameter() and
|
||||
numArgs = count(m.(ConstructedMethod).getATypeArgument()) and
|
||||
typeName = p.getType().getName() and
|
||||
numParams = count(m.getAParameter()) and
|
||||
numTypes = count(m.getAParameter().getType())
|
||||
}
|
||||
|
||||
/** Test that locations are populated for the type parameters of generic methods. */
|
||||
query predicate test19(UnboundGenericMethod m, TypeParameter tp, int hasLoc) {
|
||||
m.hasName("fs") and
|
||||
tp = m.getATypeParameter() and
|
||||
if exists(tp.getLocation()) then hasLoc = 1 else hasLoc = 0
|
||||
}
|
||||
|
||||
/** Test that locations are populated for unbound generic types. */
|
||||
query predicate test20(UnboundGenericType t, string s) {
|
||||
not type_location(t, _) and s = "Missing location"
|
||||
}
|
||||
|
||||
/**
|
||||
* This tests a regression in the extractor where the following failed to extract:
|
||||
*
|
||||
* class Foo<T>
|
||||
* {
|
||||
* enum E { a };
|
||||
* }
|
||||
*/
|
||||
query predicate test21(Enum e, Class c) {
|
||||
c.hasName("Param<>") and
|
||||
e.hasName("E") and
|
||||
e.getDeclaringType() = c
|
||||
}
|
||||
|
||||
query predicate test22(ConstructedMethod m, string tpName) {
|
||||
m.getName().matches("CM%") and
|
||||
tpName = m.getATypeArgument().getName()
|
||||
}
|
||||
|
||||
query predicate test23(Class c, Interface i) {
|
||||
c.getName().matches("Inheritance%") and
|
||||
i = c.getABaseInterface()
|
||||
}
|
||||
|
||||
query predicate test24(UnboundGenericInterface ugi, TypeParameter tp, string s) {
|
||||
ugi.fromSource() and
|
||||
ugi.getATypeParameter() = tp and
|
||||
(
|
||||
tp.isOut() and s = "out"
|
||||
or
|
||||
tp.isIn() and s = "in"
|
||||
)
|
||||
}
|
||||
|
||||
query predicate test25(ConstructedMethod cm) {
|
||||
cm.hasName("CM3") and
|
||||
cm.getParameter(0).getType() instanceof DoubleType and
|
||||
cm.getParameter(1).getType() instanceof IntType and
|
||||
cm.getReturnType() instanceof DoubleType and
|
||||
exists(Method sourceDeclaration |
|
||||
sourceDeclaration = cm.getSourceDeclaration() and
|
||||
sourceDeclaration.getParameter(0).getType().(TypeParameter).hasName("T2") and
|
||||
sourceDeclaration.getParameter(1).getType().(TypeParameter).hasName("T1") and
|
||||
sourceDeclaration.getReturnType().(TypeParameter).hasName("T2")
|
||||
) and
|
||||
exists(Method unbound |
|
||||
unbound = cm.getUnboundGeneric() and
|
||||
unbound.getParameter(0).getType().(TypeParameter).hasName("T2") and
|
||||
unbound.getParameter(1).getType() instanceof IntType and
|
||||
unbound.getReturnType().(TypeParameter).hasName("T2")
|
||||
)
|
||||
}
|
||||
|
||||
query predicate test26(ConstructedGeneric cg, string s) {
|
||||
// Source declaration and unbound generic must be unique
|
||||
(
|
||||
strictcount(cg.getSourceDeclaration+()) > 1 or
|
||||
strictcount(cg.getUnboundGeneric()) > 1
|
||||
) and
|
||||
s = "Non-unique source decl or unbound generic"
|
||||
}
|
||||
|
||||
query predicate test27(ConstructedType ct, UnboundGenericType ugt, UnboundGenericType sourceDecl) {
|
||||
ct instanceof NestedType and
|
||||
ugt = ct.getUnboundGeneric() and
|
||||
sourceDecl = ct.getSourceDeclaration() and
|
||||
ugt != sourceDecl
|
||||
}
|
||||
|
||||
query predicate test28(UnboundGeneric ug, string s) {
|
||||
ug.fromSource() and
|
||||
s = ug.getQualifiedNameWithTypes()
|
||||
}
|
||||
|
||||
query predicate test29(ConstructedGeneric cg, string s) {
|
||||
cg.fromSource() and
|
||||
s = cg.getQualifiedNameWithTypes()
|
||||
}
|
||||
|
||||
query predicate test30(Declaration d, string s) {
|
||||
d.fromSource() and
|
||||
d instanceof @generic and
|
||||
s = d.getQualifiedNameWithTypes() and
|
||||
d != d.getSourceDeclaration() and
|
||||
not d instanceof Generic
|
||||
}
|
||||
|
||||
query predicate test31(ConstructedGeneric cg, string s) {
|
||||
not exists(cg.getUnboundGeneric()) and
|
||||
s = "Missing unbound generic"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:7:23:7:40 | GenericDelegate<> |
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from UnboundGenericDelegateType d
|
||||
where
|
||||
d.hasName("GenericDelegate<>") and
|
||||
d.getTypeParameter(0).hasName("T") and
|
||||
d.getParameter(0).getType().hasName("T")
|
||||
select d
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:22:18:22:21 | B<String> | generics.cs:37:41:37:47 | myEvent |
|
||||
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from ConstructedClass bString, Event e
|
||||
where
|
||||
bString.hasName("B<String>") and
|
||||
e.getDeclaringType() = bString and
|
||||
e.hasName("myEvent") and
|
||||
e.getSourceDeclaration().getDeclaringType() = e.getDeclaringType().getSourceDeclaration() and
|
||||
e.getType().(ConstructedDelegateType).getTypeArgument(0) instanceof StringType and
|
||||
e.getAddEventAccessor().getSourceDeclaration() = e.getSourceDeclaration().getAddEventAccessor() and
|
||||
e.getRemoveEventAccessor().getSourceDeclaration() =
|
||||
e.getSourceDeclaration().getRemoveEventAccessor()
|
||||
select bString, e
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:22:18:22:21 | B<String> | generics.cs:39:37:39:38 | ++ |
|
||||
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from ConstructedClass bString, Operator o
|
||||
where
|
||||
bString.hasName("B<String>") and
|
||||
o.getDeclaringType() = bString and
|
||||
o instanceof IncrementOperator and
|
||||
o.getSourceDeclaration().getDeclaringType() = o.getDeclaringType().getSourceDeclaration()
|
||||
select bString, o
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:60:18:60:24 | Grid<Int32> | generics.cs:73:18:73:21 | Item |
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from ConstructedClass gridInt, Indexer i
|
||||
where
|
||||
gridInt.hasName("Grid<Int32>") and
|
||||
i.getDeclaringType() = gridInt and
|
||||
i.getSourceDeclaration().getDeclaringType() = i.getDeclaringType().getSourceDeclaration() and
|
||||
i.getGetter().getSourceDeclaration() = i.getSourceDeclaration().getGetter() and
|
||||
i.getSetter().getSourceDeclaration() = i.getSourceDeclaration().getSetter()
|
||||
select gridInt, i
|
||||
@@ -1,2 +0,0 @@
|
||||
| generics.cs:60:18:60:24 | Grid<Int32> | generics.cs:68:20:68:23 | Item |
|
||||
| generics.cs:60:18:60:24 | Grid<Int32> | generics.cs:73:18:73:21 | Item |
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from ConstructedClass gridInt, Indexer i
|
||||
where
|
||||
gridInt.hasName("Grid<Int32>") and
|
||||
i.getDeclaringType() = gridInt and
|
||||
i.getType() instanceof IntType
|
||||
select gridInt, i
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:60:18:60:24 | Grid<> | generics.cs:68:20:68:23 | Item |
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from UnboundGenericClass gridInt, Indexer i
|
||||
where
|
||||
gridInt.hasName("Grid<>") and
|
||||
i.getDeclaringType() = gridInt and
|
||||
i.getType() instanceof IntType
|
||||
select gridInt, i
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:7:23:7:40 | GenericDelegate<String> |
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from ConstructedDelegateType d
|
||||
where
|
||||
d.hasName("GenericDelegate<String>") and
|
||||
d.getTypeArgument(0) instanceof StringType and
|
||||
d.getParameter(0).getType() instanceof StringType
|
||||
select d
|
||||
@@ -1,3 +0,0 @@
|
||||
| generics.cs:134:11:134:16 | Subtle | generics.cs:137:21:137:25 | fs |
|
||||
| generics.cs:134:11:134:16 | Subtle | generics.cs:139:21:139:25 | fs |
|
||||
| generics.cs:134:11:134:16 | Subtle | generics.cs:141:21:141:22 | fs |
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from Class c
|
||||
where
|
||||
c.hasName("Subtle") and
|
||||
count(c.getAMethod()) = 3
|
||||
select c, c.getAMethod()
|
||||
@@ -1,2 +0,0 @@
|
||||
| generics.cs:134:11:134:16 | Subtle | generics.cs:137:21:137:25 | fs | 1 | generics.cs:137:24:137:24 | X | generics.cs:139:21:139:25 | fs | generics.cs:139:24:139:24 | X |
|
||||
| generics.cs:134:11:134:16 | Subtle | generics.cs:139:21:139:25 | fs | 2 | generics.cs:139:24:139:24 | X | generics.cs:137:21:137:25 | fs | generics.cs:137:24:137:24 | X |
|
||||
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from Class c, TypeParameter p, UnboundGenericMethod m, TypeParameter q, UnboundGenericMethod n
|
||||
where
|
||||
c.hasName("Subtle") and
|
||||
m = c.getAMethod() and
|
||||
m.getATypeParameter() = p and
|
||||
n = c.getAMethod() and
|
||||
n.getATypeParameter() = q and
|
||||
m != n and
|
||||
p != q
|
||||
select c, m, m.getNumberOfParameters(), p, n, q
|
||||
@@ -1,10 +0,0 @@
|
||||
| generics.cs:13:18:13:21 | A<> | generics.cs:18:18:18:23 | bar | generics.cs:18:27:18:27 | x | 0 | X | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<> | generics.cs:18:18:18:23 | bar | generics.cs:18:32:18:32 | t | 0 | T | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<Int32> | generics.cs:18:18:18:23 | bar | generics.cs:18:27:18:27 | x | 0 | X | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<Int32> | generics.cs:18:18:18:23 | bar | generics.cs:18:27:18:27 | x | 1 | Test | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<Int32> | generics.cs:18:18:18:23 | bar | generics.cs:18:32:18:32 | t | 0 | Int32 | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<Int32> | generics.cs:18:18:18:23 | bar | generics.cs:18:32:18:32 | t | 1 | Int32 | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<String> | generics.cs:18:18:18:23 | bar | generics.cs:18:27:18:27 | x | 0 | X | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<String> | generics.cs:18:18:18:23 | bar | generics.cs:18:27:18:27 | x | 1 | Int32 | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<String> | generics.cs:18:18:18:23 | bar | generics.cs:18:32:18:32 | t | 0 | String | 2 | 2 |
|
||||
| generics.cs:13:18:13:21 | A<String> | generics.cs:18:18:18:23 | bar | generics.cs:18:32:18:32 | t | 1 | String | 2 | 2 |
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* @name Test for generic parameter types
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from Class c, Method m
|
||||
where
|
||||
c.getName().matches("A<%") and
|
||||
m = c.getAMethod()
|
||||
select c, m, m.getAParameter() as p, count(m.(ConstructedMethod).getATypeArgument()),
|
||||
p.getType().getName(), count(m.getAParameter()), count(m.getAParameter().getType())
|
||||
@@ -1,2 +0,0 @@
|
||||
| generics.cs:137:21:137:25 | fs | generics.cs:137:24:137:24 | X | 1 |
|
||||
| generics.cs:139:21:139:25 | fs | generics.cs:139:24:139:24 | X | 1 |
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* @name Test that locations are populated for the type parameters of generic methods
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from UnboundGenericMethod m, TypeParameter tp, int hasLoc
|
||||
where
|
||||
m.hasName("fs") and
|
||||
tp = m.getATypeParameter() and
|
||||
if exists(tp.getLocation()) then hasLoc = 1 else hasLoc = 0
|
||||
select m, tp, hasLoc
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:9:18:9:18 | A |
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from Class c
|
||||
where
|
||||
c.hasName("A") and
|
||||
not c instanceof UnboundGenericClass
|
||||
select c
|
||||
@@ -1 +0,0 @@
|
||||
| 1 |
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* @name Test that locations are populated for unbound generic types
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from UnboundGenericType t
|
||||
where type_location(t, _)
|
||||
select 1
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:145:11:145:18 | Param<> | generics.cs:147:14:147:14 | E |
|
||||
@@ -1,17 +0,0 @@
|
||||
import csharp
|
||||
|
||||
/*
|
||||
* This tests a regression in the extractor where the following failed to extract:
|
||||
*
|
||||
* class Foo<T>
|
||||
* {
|
||||
* enum E { a };
|
||||
* }
|
||||
*/
|
||||
|
||||
from Enum e, Class c
|
||||
where
|
||||
c.hasName("Param<>") and
|
||||
e.hasName("E") and
|
||||
e.getDeclaringType() = c
|
||||
select c, e
|
||||
@@ -1,6 +0,0 @@
|
||||
| generics.cs:152:14:152:19 | CM1 | Double |
|
||||
| generics.cs:152:14:152:19 | CM1 | Int32 |
|
||||
| generics.cs:153:11:153:16 | CM2 | Double |
|
||||
| generics.cs:153:11:153:16 | CM2 | Int32 |
|
||||
| generics.cs:157:23:157:29 | CM3 | Double |
|
||||
| generics.cs:157:23:157:29 | CM3 | Double |
|
||||
@@ -1,7 +0,0 @@
|
||||
import csharp
|
||||
|
||||
from ConstructedMethod m, ValueOrRefType tp
|
||||
where
|
||||
m.getName().matches("CM%") and
|
||||
tp = m.getATypeArgument()
|
||||
select m, tp.getName()
|
||||
@@ -1,2 +0,0 @@
|
||||
| generics.cs:178:11:178:24 | Inheritance<> | generics.cs:173:15:173:26 | Interface<T> |
|
||||
| generics.cs:178:11:178:24 | Inheritance<Int32> | generics.cs:173:15:173:26 | Interface<Int32> |
|
||||
@@ -1,7 +0,0 @@
|
||||
import csharp
|
||||
|
||||
from Class c, Interface i
|
||||
where
|
||||
c.getName().matches("Inheritance%") and
|
||||
i = c.getABaseInterface()
|
||||
select c, i
|
||||
@@ -1,2 +0,0 @@
|
||||
| generics.cs:188:15:188:39 | Interface2<,> | generics.cs:188:29:188:30 | T1 | in |
|
||||
| generics.cs:188:15:188:39 | Interface2<,> | generics.cs:188:37:188:38 | T2 | out |
|
||||
@@ -1,12 +0,0 @@
|
||||
import csharp
|
||||
|
||||
from UnboundGenericInterface ugi, TypeParameter tp, string s
|
||||
where
|
||||
ugi.fromSource() and
|
||||
ugi.getATypeParameter() = tp and
|
||||
(
|
||||
tp.isOut() and s = "out"
|
||||
or
|
||||
tp.isIn() and s = "in"
|
||||
)
|
||||
select ugi, tp, s
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:157:23:157:29 | CM3 |
|
||||
@@ -1,21 +0,0 @@
|
||||
import csharp
|
||||
|
||||
from ConstructedMethod cm
|
||||
where
|
||||
cm.hasName("CM3") and
|
||||
cm.getParameter(0).getType() instanceof DoubleType and
|
||||
cm.getParameter(1).getType() instanceof IntType and
|
||||
cm.getReturnType() instanceof DoubleType and
|
||||
exists(Method sourceDeclaration |
|
||||
sourceDeclaration = cm.getSourceDeclaration() and
|
||||
sourceDeclaration.getParameter(0).getType().(TypeParameter).hasName("T2") and
|
||||
sourceDeclaration.getParameter(1).getType().(TypeParameter).hasName("T1") and
|
||||
sourceDeclaration.getReturnType().(TypeParameter).hasName("T2")
|
||||
) and
|
||||
exists(Method unbound |
|
||||
unbound = cm.getUnboundGeneric() and
|
||||
unbound.getParameter(0).getType().(TypeParameter).hasName("T2") and
|
||||
unbound.getParameter(1).getType() instanceof IntType and
|
||||
unbound.getReturnType().(TypeParameter).hasName("T2")
|
||||
)
|
||||
select cm
|
||||
@@ -1 +0,0 @@
|
||||
| Test passed |
|
||||
@@ -1,9 +0,0 @@
|
||||
import csharp
|
||||
|
||||
// Source declaration and unbound generic must be unique
|
||||
where
|
||||
not exists(ConstructedGeneric cg |
|
||||
strictcount(cg.getSourceDeclaration+()) > 1 or
|
||||
strictcount(cg.getUnboundGeneric()) > 1
|
||||
)
|
||||
select "Test passed"
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:51:22:51:29 | Inner<String> | generics.cs:51:22:51:29 | Inner<> | generics.cs:51:22:51:29 | Inner<> |
|
||||
@@ -1,9 +0,0 @@
|
||||
import csharp
|
||||
|
||||
from ConstructedType ct, UnboundGenericType ugt, UnboundGenericType sourceDecl
|
||||
where
|
||||
ct instanceof NestedType and
|
||||
ugt = ct.getUnboundGeneric() and
|
||||
sourceDecl = ct.getSourceDeclaration() and
|
||||
ugt != sourceDecl
|
||||
select ct, ugt, sourceDecl
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:13:18:13:21 | A<X> | generics.cs:13:18:13:21 | A<> |
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from ConstructedClass c, UnboundGenericClass d
|
||||
where
|
||||
c.hasName("A<X>") and
|
||||
d.hasName("A<>") and
|
||||
c.getTypeArgument(0).hasName("X") and
|
||||
c.getTypeArgument(0) instanceof TypeParameter and
|
||||
c.getUnboundGeneric() = d
|
||||
select c, d
|
||||
@@ -1 +0,0 @@
|
||||
| 1 |
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
where forex(UnboundGenericClass c | c.fromSource() | c.getName().matches("%<%>"))
|
||||
select 1
|
||||
@@ -1 +0,0 @@
|
||||
| 1 |
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
where forex(ConstructedClass c | c.getName().matches("%<%>"))
|
||||
select 1
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:22:18:22:21 | B<> | generics.cs:22:18:22:21 | B<X> | generics.cs:25:23:25:24 | at | generics.cs:13:18:13:21 | A<T> |
|
||||
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from ConstructedClass at, UnboundGenericClass b, ConstructedClass bt, Field f
|
||||
where
|
||||
at.hasName("A<T>") and
|
||||
b.hasName("B<>") and
|
||||
bt.hasName("B<X>") and
|
||||
at.getTypeArgument(0).hasName("T") and
|
||||
at.getTypeArgument(0) instanceof TypeParameter and
|
||||
at.getTypeArgument(0) = b.getTypeParameter(0) and
|
||||
bt.getUnboundGeneric() = b and
|
||||
f.getDeclaringType() = b and
|
||||
f.getType() = at
|
||||
select b, bt, f, at
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:13:18:13:21 | A<String> | generics.cs:22:18:22:21 | B<String> |
|
||||
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from ConstructedClass aString, ConstructedClass bString
|
||||
where
|
||||
aString.hasName("A<String>") and
|
||||
bString.hasName("B<String>") and
|
||||
aString.getSourceDeclaration().hasName("A<>") and
|
||||
bString.getSourceDeclaration().hasName("B<>")
|
||||
select aString, bString
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:22:18:22:21 | B<String> | generics.cs:31:21:31:29 | fooParams |
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from ConstructedClass bString, Method m
|
||||
where
|
||||
bString.hasName("B<String>") and
|
||||
m.getDeclaringType() = bString and
|
||||
m.hasName("fooParams") and
|
||||
m.getParameter(0).getType().(ArrayType).getElementType() instanceof StringType and
|
||||
m.getSourceDeclaration().getDeclaringType() = m.getDeclaringType().getSourceDeclaration()
|
||||
select bString, m
|
||||
@@ -1 +0,0 @@
|
||||
| generics.cs:22:18:22:21 | B<String> | generics.cs:35:51:35:53 | set_Name | generics.cs:35:51:35:53 | set_Name |
|
||||
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* @name Test for generics
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from ConstructedClass bString, Property p
|
||||
where
|
||||
bString.hasName("B<String>") and
|
||||
p.getDeclaringType() = bString and
|
||||
p.hasName("Name") and
|
||||
p.getSourceDeclaration().getDeclaringType() = p.getDeclaringType().getSourceDeclaration() and
|
||||
p.getSetter().getParameter(0).getType() instanceof StringType and
|
||||
p.getSetter().getSourceDeclaration() = p.getSourceDeclaration().getSetter() and
|
||||
p.getGetter().getSourceDeclaration() = p.getSourceDeclaration().getGetter()
|
||||
select bString, p.getSourceDeclaration().getSetter(), p.getSetter()
|
||||
58
csharp/ql/test/library-tests/generics/Nesting.cs
Normal file
58
csharp/ql/test/library-tests/generics/Nesting.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
public class A<T1>
|
||||
{
|
||||
public void MA1(T1 x) { }
|
||||
public void MA2<T2>(T1 x, T2 y) { }
|
||||
|
||||
public class B<T3>
|
||||
{
|
||||
public void MB1(T1 x, T3 y) { }
|
||||
public void MB2<T4>(T1 x, T3 y, T4 z) { }
|
||||
}
|
||||
|
||||
public class C
|
||||
{
|
||||
public void MC1(T1 x) { }
|
||||
public void MC2<T5>(T1 x, T5 y) { }
|
||||
|
||||
public class D<T6>
|
||||
{
|
||||
public void MD1(T1 x, T6 y) { }
|
||||
public void MD2<T7>(T1 x, T6 y, T7 z) { }
|
||||
}
|
||||
}
|
||||
|
||||
void Construct()
|
||||
{
|
||||
var a1 = new A<int>();
|
||||
a1.MA1(0);
|
||||
a1.MA2(0, "");
|
||||
|
||||
var a2 = new A<string>();
|
||||
a2.MA1("");
|
||||
a2.MA2("", 0);
|
||||
|
||||
var b1 = new A<int>.B<string>();
|
||||
b1.MB1(0, "");
|
||||
b1.MB2(0, "", false);
|
||||
|
||||
var b2 = new A<string>.B<int>();
|
||||
b2.MB1("", 0);
|
||||
b2.MB2("", 0, false);
|
||||
|
||||
var c1 = new A<int>.C();
|
||||
c1.MC1(0);
|
||||
c1.MC2(0, false);
|
||||
|
||||
var c2 = new A<string>.C();
|
||||
c2.MC1("");
|
||||
c2.MC2("", false);
|
||||
|
||||
var d1 = new A<int>.C.D<bool>();
|
||||
d1.MD1(0, false);
|
||||
d1.MD2(0, false, "");
|
||||
|
||||
var d2 = new A<string>.C.D<decimal>();
|
||||
d2.MD1("", 0m);
|
||||
d2.MD2("", 0m, false);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: Removed relations `is_constructed` and `is_generic`
|
||||
compatibility: full
|
||||
is_generic.rel: delete
|
||||
is_constructed.rel: delete
|
||||
Reference in New Issue
Block a user