Skip to content

Commit 6178acc

Browse files
committed
C#: Copy dotnet.Type implementation.
1 parent 81ce8dc commit 6178acc

File tree

2 files changed

+55
-14
lines changed

2 files changed

+55
-14
lines changed

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,10 @@ class UnboundGenericType extends ValueOrRefType, UnboundGeneric {
202202
/**
203203
* A type parameter, for example `T` in `List<T>`.
204204
*/
205-
class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
205+
class TypeParameter extends Type, @type_parameter {
206+
/** Gets the generic type or method declaring this type parameter. */
207+
UnboundGeneric getDeclaringGeneric() { this = result.getATypeParameter() }
208+
206209
/** Gets the constraints on this type parameter, if any. */
207210
TypeParameterConstraints getConstraints() { result.getTypeParameter() = this }
208211

@@ -258,8 +261,13 @@ class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
258261
result = this.getASuppliedType().(TypeParameter).getAnUltimatelySuppliedType()
259262
}
260263

264+
/** Gets the index of this type parameter. For example the index of `U` in `Func<T,U>` is 1. */
261265
override int getIndex() { type_parameters(this, result, _, _) }
262266

267+
final override string getLabel() { result = "!" + this.getIndex() }
268+
269+
override string getUndecoratedName() { result = "!" + this.getIndex() }
270+
263271
/** Gets the generic that defines this type parameter. */
264272
UnboundGeneric getGeneric() { type_parameters(this, _, result, _) }
265273

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

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import Location
77
import Namespace
88
import Property
99
private import Conversion
10-
private import dotnet
1110
private import semmle.code.csharp.metrics.Coupling
1211
private import TypeRef
1312
private import semmle.code.csharp.frameworks.System
@@ -20,7 +19,10 @@ private import semmle.code.csharp.frameworks.system.runtime.CompilerServices
2019
* a pointer type (`PointerType`), the arglist type (`ArglistType`), an unknown
2120
* type (`UnknownType`), or a type parameter (`TypeParameter`).
2221
*/
23-
class Type extends DotNet::Type, Member, TypeContainer, @type {
22+
class Type extends Member, TypeContainer, @type {
23+
/** Gets the name of this type without additional syntax such as `[]` or `*`. */
24+
override string getUndecoratedName() { none() }
25+
2426
override string getName() { types(this, _, result) }
2527

2628
override Type getUnboundDeclaration() { result = this }
@@ -56,15 +58,16 @@ private predicate isObjectClass(Class c) { c instanceof ObjectType }
5658
*
5759
* Either a value type (`ValueType`) or a reference type (`RefType`).
5860
*/
59-
class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_or_ref_type {
61+
class ValueOrRefType extends Type, Attributable, @value_or_ref_type {
6062
/** Gets the namespace containing this type. */
6163
Namespace getNamespace() {
6264
if exists(this.getDeclaringType())
6365
then result = this.getDeclaringType().getNamespace()
6466
else result.getATypeDeclaration() = this
6567
}
6668

67-
override Namespace getDeclaringNamespace() { this = result.getATypeDeclaration() }
69+
/** Gets the namespace declaring this type, if any. */
70+
Namespace getDeclaringNamespace() { this = result.getATypeDeclaration() }
6871

6972
override ValueOrRefType getDeclaringType() { none() }
7073

@@ -73,6 +76,30 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
7376
/** Gets a nested child type, if any. */
7477
NestedType getAChildType() { nested_types(result, this, _) }
7578

79+
private string getPrefixWithTypes() {
80+
result = this.getDeclaringType().getLabel() + "."
81+
or
82+
if this.getDeclaringNamespace().isGlobalNamespace()
83+
then result = ""
84+
else result = this.getDeclaringNamespace().getFullName() + "."
85+
}
86+
87+
pragma[noinline]
88+
private string getLabelNonGeneric() {
89+
not this instanceof Generic and
90+
result = this.getPrefixWithTypes() + this.getUndecoratedName()
91+
}
92+
93+
pragma[noinline]
94+
private string getLabelGeneric() {
95+
result = this.getPrefixWithTypes() + this.getUndecoratedName() + getGenericsLabel(this)
96+
}
97+
98+
override string getLabel() {
99+
result = this.getLabelNonGeneric() or
100+
result = this.getLabelGeneric()
101+
}
102+
76103
/**
77104
* Gets the source namespace declaration in which this type is declared, if any.
78105
* This only holds for non-nested types.
@@ -120,7 +147,7 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
120147
}
121148

122149
/** Gets an immediate base type of this type, if any. */
123-
override ValueOrRefType getABaseType() {
150+
ValueOrRefType getABaseType() {
124151
result = this.getBaseClass() or
125152
result = this.getABaseInterface()
126153
}
@@ -360,7 +387,8 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
360387
nested_types(this, _, result)
361388
}
362389

363-
override predicate isRecord() { this.hasModifier("record") }
390+
/** Holds if this type is a `record`. */
391+
predicate isRecord() { this.hasModifier("record") }
364392

365393
override string toString() { result = Type.super.toString() }
366394
}
@@ -1064,7 +1092,7 @@ class InlineArrayType extends ValueType, @inline_array_type {
10641092
/**
10651093
* An array type, for example `int[]`.
10661094
*/
1067-
class ArrayType extends DotNet::ArrayType, RefType, @array_type {
1095+
class ArrayType extends RefType, @array_type {
10681096
/**
10691097
* Gets the dimension of this array type. For example `int[][]` is of
10701098
* dimension 2, while `int[]` is of dimension 1.
@@ -1081,13 +1109,15 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
10811109
predicate isMultiDimensional() { this.getRank() > 1 }
10821110

10831111
/** Gets the element type of this array, for example `int` in `int[]`. */
1084-
override Type getElementType() {
1112+
Type getElementType() {
10851113
array_element_type(this, _, _, result)
10861114
or
10871115
not array_element_type(this, _, _, any(Type t)) and
10881116
array_element_type(this, _, _, getTypeRef(result))
10891117
}
10901118

1119+
final override string getLabel() { result = this.getElementType().getLabel() + "[]" }
1120+
10911121
/** Holds if this array type has the same shape (dimension and rank) as `that` array type. */
10921122
predicate hasSameShapeAs(ArrayType that) {
10931123
this.getDimension() = that.getDimension() and
@@ -1128,33 +1158,36 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
11281158
not type_location(this, _) and
11291159
result = this.getElementType().getALocation()
11301160
}
1161+
1162+
override string getAPrimaryQlClass() { result = "ArrayType" }
11311163
}
11321164

11331165
/**
11341166
* A pointer type, for example `char*`.
11351167
*/
1136-
class PointerType extends DotNet::PointerType, Type, @pointer_type {
1137-
override Type getReferentType() {
1168+
class PointerType extends Type, @pointer_type {
1169+
/** Gets the type referred by this pointer type, for example `char` in `char*`. */
1170+
Type getReferentType() {
11381171
pointer_referent_type(this, result)
11391172
or
11401173
not pointer_referent_type(this, any(Type t)) and
11411174
pointer_referent_type(this, getTypeRef(result))
11421175
}
11431176

1144-
override string toStringWithTypes() { result = DotNet::PointerType.super.toStringWithTypes() }
1177+
override string toStringWithTypes() { result = this.getReferentType().toStringWithTypes() + "*" }
11451178

11461179
override Type getChild(int n) { result = this.getReferentType() and n = 0 }
11471180

11481181
final override string getName() { types(this, _, result) }
11491182

1183+
final override string getLabel() { result = this.getReferentType().getLabel() + "*" }
1184+
11501185
final override string getUndecoratedName() {
11511186
result = this.getReferentType().getUndecoratedName()
11521187
}
11531188

11541189
override Location getALocation() { result = this.getReferentType().getALocation() }
11551190

1156-
override string toString() { result = DotNet::PointerType.super.toString() }
1157-
11581191
override string getAPrimaryQlClass() { result = "PointerType" }
11591192
}
11601193

0 commit comments

Comments
 (0)