Skip to content

Commit 86c5b38

Browse files
authored
Merge pull request github#3341 from hvitved/csharp/generics-nested-types
Approved by calumgrant
2 parents 78d2ac1 + e8e27e0 commit 86c5b38

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+4331
-452
lines changed

change-notes/1.25/analysis-csharp.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Improvements to C# analysis
2+
3+
The following changes in version 1.25 affect C# analysis in all applications.
4+
5+
## New queries
6+
7+
| **Query** | **Tags** | **Purpose** |
8+
|-----------------------------|-----------|--------------------------------------------------------------------|
9+
10+
11+
## Changes to existing queries
12+
13+
| **Query** | **Expected impact** | **Change** |
14+
|------------------------------|------------------------|-----------------------------------|
15+
16+
17+
## Removal of old queries
18+
19+
## Changes to code extraction
20+
21+
## Changes to libraries
22+
23+
* The class `UnboundGeneric` has been refined to only be those declarations that actually
24+
have type parameters. This means that non-generic nested types inside construced types,
25+
such as `A<int>.B`, no longer are considered unbound generics. (Such nested types do,
26+
however, still have relevant `.getSourceDeclaration()`s, for example `A<>.B`.)
27+
28+
## Changes to autobuilder

csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,6 @@ protected void PopulateGenerics(TextWriter trapFile)
340340

341341
if (isFullyConstructed)
342342
{
343-
trapFile.is_constructed(this);
344343
trapFile.constructed_generic(this, Method.Create(Context, ConstructedFromSymbol));
345344
foreach (var tp in symbol.GetAnnotatedTypeArguments())
346345
{
@@ -354,7 +353,6 @@ protected void PopulateGenerics(TextWriter trapFile)
354353
}
355354
else
356355
{
357-
trapFile.is_generic(this);
358356
foreach (var typeParam in symbol.TypeParameters.Select(tp => TypeParameter.Create(Context, tp)))
359357
{
360358
trapFile.type_parameters(typeParam, child, this);

csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NamedType.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ public override void Populate(TextWriter trapFile)
4040
}
4141
else if (symbol.IsReallyUnbound())
4242
{
43-
trapFile.is_generic(this);
44-
4543
for (int i = 0; i < symbol.TypeParameters.Length; ++i)
4644
{
4745
TypeParameter.Create(Context, symbol.TypeParameters[i]);
@@ -52,7 +50,6 @@ public override void Populate(TextWriter trapFile)
5250
}
5351
else
5452
{
55-
trapFile.is_constructed(this);
5653
trapFile.constructed_generic(this, Type.Create(Context, symbol.ConstructedFrom).TypeRef);
5754

5855
for (int i = 0; i < symbol.TypeArguments.Length; ++i)

csharp/extractor/Semmle.Extraction.CSharp/Tuples.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,16 +306,6 @@ internal static void indexers(this TextWriter trapFile, Indexer propKey, string
306306
trapFile.WriteTuple("indexers", propKey, name, declaringType, memberType, unboundProperty);
307307
}
308308

309-
internal static void is_constructed(this TextWriter trapFile, IEntity typeOrMethod)
310-
{
311-
trapFile.WriteTuple("is_constructed", typeOrMethod);
312-
}
313-
314-
internal static void is_generic(this TextWriter trapFile, IEntity typeOrMethod)
315-
{
316-
trapFile.WriteTuple("is_generic", typeOrMethod);
317-
}
318-
319309
internal static void local_function_stmts(this TextWriter trapFile, Entities.Statements.LocalFunction fnStmt, LocalFunction fn)
320310
{
321311
trapFile.WriteTuple("local_function_stmts", fnStmt, fn);

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

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,19 @@ private import dotnet
2323
*/
2424
class Generic extends DotNet::Generic, Declaration, @generic {
2525
Generic() {
26-
is_generic(this) or
27-
is_constructed(this)
26+
type_parameters(_, _, this, _) or
27+
type_arguments(_, _, this)
2828
}
2929
}
3030

3131
/**
32-
* A generic declaration that can have type parameters.
32+
* A generic declaration with type parameters.
3333
*
3434
* Either an unbound generic type (`UnboundGenericType`) or an unbound generic method
3535
* (`UnboundGenericMethod`).
3636
*/
3737
class UnboundGeneric extends DotNet::UnboundGeneric, Generic {
38-
UnboundGeneric() { is_generic(this) }
38+
UnboundGeneric() { type_parameters(_, _, this, _) }
3939

4040
override TypeParameter getTypeParameter(int n) { type_parameters(result, n, this, _) }
4141

@@ -47,24 +47,21 @@ class UnboundGeneric extends DotNet::UnboundGeneric, Generic {
4747
}
4848

4949
/**
50-
* A declaration constructed from an `UnboundGeneric` by supplying type arguments.
50+
* A constructed generic.
5151
*
5252
* Either a constructed generic type (`ConstructedType`) or a constructed
5353
* generic method (`ConstructedMethod`).
5454
*/
5555
class ConstructedGeneric extends DotNet::ConstructedGeneric, Generic {
56-
ConstructedGeneric() { is_constructed(this) }
56+
ConstructedGeneric() { type_arguments(_, _, this) }
5757

5858
override UnboundGeneric getUnboundGeneric() { constructed_generic(this, result) }
5959

6060
override UnboundGeneric getSourceDeclaration() {
6161
result = getUnboundGeneric().getSourceDeclaration()
6262
}
6363

64-
override int getNumberOfTypeArguments() {
65-
// getTypeArgument() could fail if the type does not exist in the database
66-
result = count(int i | type_arguments(_, i, this))
67-
}
64+
override int getNumberOfTypeArguments() { result = count(int i | type_arguments(_, i, this)) }
6865

6966
override Type getTypeArgument(int i) { none() }
7067

@@ -84,11 +81,12 @@ class ConstructedGeneric extends DotNet::ConstructedGeneric, Generic {
8481
*/
8582
class UnboundGenericType extends ValueOrRefType, UnboundGeneric {
8683
/**
87-
* Gets a bound/constructed version of this unbound generic type. This includes not only closed constructed types such as `G<int>`,
88-
* 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
89-
* `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
90-
* `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
91-
* syntactic similarity.
84+
* Gets a bound/constructed version of this unbound generic type. This includes
85+
* not only closed constructed types such as `G<int>`, but also open constructed
86+
* types such as the `G<T>` in `class Other<T> { G<T> g; }`. Note that such a type
87+
* is distinct from the `G<T>` used in the class definition, since in `G<T> g;`
88+
* the `T` will be the actual type parameter used for the `Other` that contains
89+
* `g`, whereas in `class G<T> { ... }` the `T` is a formal type parameter of `G`.
9290
*/
9391
override ConstructedType getAConstructedGeneric() {
9492
result = UnboundGeneric.super.getAConstructedGeneric()
@@ -350,15 +348,16 @@ class UnboundGenericDelegateType extends DelegateType, UnboundGenericType {
350348
}
351349

352350
/**
353-
* A constructed (bound) type. This is a generic type for which actual type arguments have been supplied,
354-
* for example `G<int>` or the `G<T>` in `class Other<T> { G<T> g; }`. Constructed types can be divided further into
355-
* 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
356-
* is a type parameter, versus those that are closed (for example `G1<int>` or `G2<long,long,float,int>`). We do not
357-
* currently distinguish the two in this library.
358-
*
359-
* Either a constructed `struct` (`ConstructedStruct`), constructed `class` (`ConstructedClass`),
360-
* constructed `interface` (`ConstructedInterface`), or constructed method
361-
* (`ConstructedMethod`).
351+
* A constructed (bound) type. This is a generic type for which actual type
352+
* arguments have been supplied, for example `G<int>` or the `G<T>` in
353+
* `class Other<T> { G<T> g; }`. Constructed types can be divided further into
354+
* those that are open (for example `G1<T>` or `G2<T,T,U,int>`), in the sense
355+
* that one or more of their type arguments is a type parameter, versus those
356+
* that are closed (for example `G1<int>` or `G2<long,long,float,int>`).
357+
*
358+
* Either a constructed `struct` (`ConstructedStruct`), constructed `class`
359+
* (`ConstructedClass`), constructed `interface` (`ConstructedInterface`),
360+
* or constructed method (`ConstructedMethod`).
362361
*/
363362
class ConstructedType extends ValueOrRefType, ConstructedGeneric {
364363
override UnboundGenericType getSourceDeclaration() {

csharp/ql/src/semmle/code/dotnet/Generics.qll

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ abstract class UnboundGeneric extends Generic {
1313
/** Gets the `i`th type parameter, if any. */
1414
abstract TypeParameter getTypeParameter(int i);
1515

16-
/** Gets a type parameter, if any. */
16+
/** Gets a type parameter. */
1717
TypeParameter getATypeParameter() { result = getTypeParameter(_) }
1818

1919
/**
@@ -42,10 +42,13 @@ abstract class ConstructedGeneric extends Generic {
4242
/** Gets the `i`th type argument, if any. */
4343
abstract Type getTypeArgument(int i);
4444

45-
/** Gets a type argument, if any. */
45+
/** Gets a type argument. */
4646
Type getATypeArgument() { result = getTypeArgument(_) }
4747

48-
/** Gets the unbound generic declaration from which this declaration was constructed. */
48+
/**
49+
* Gets the unbound generic declaration from which this declaration was
50+
* constructed.
51+
*/
4952
UnboundGeneric getUnboundGeneric() { none() }
5053

5154
/** Gets the total number of type arguments. */

csharp/ql/src/semmlecode.csharp.dbscheme

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -497,10 +497,6 @@ expr_flowstate(unique int id: @expr ref, int state: int ref);
497497

498498
@generic = @type | @method | @local_function;
499499

500-
is_generic(unique int id: @generic ref);
501-
502-
is_constructed(unique int id: @generic ref);
503-
504500
type_parameters(
505501
unique int id: @type_parameter ref,
506502
int index: int ref,

csharp/ql/src/semmlecode.csharp.dbscheme.stats

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15479,28 +15479,6 @@
1547915479
</dependencies>
1548015480
</relation>
1548115481
<relation>
15482-
<name>is_generic</name>
15483-
<cardinality>77320</cardinality>
15484-
<columnsizes>
15485-
<e>
15486-
<k>id</k>
15487-
<v>77320</v>
15488-
</e>
15489-
</columnsizes>
15490-
<dependencies/>
15491-
</relation>
15492-
<relation>
15493-
<name>is_constructed</name>
15494-
<cardinality>358124</cardinality>
15495-
<columnsizes>
15496-
<e>
15497-
<k>id</k>
15498-
<v>358124</v>
15499-
</e>
15500-
</columnsizes>
15501-
<dependencies/>
15502-
</relation>
15503-
<relation>
1550415482
<name>type_parameters</name>
1550515483
<cardinality>84292</cardinality>
1550615484
<columnsizes>

0 commit comments

Comments
 (0)