Skip to content

Commit 647ed03

Browse files
authored
Merge pull request #4136 from tamasvajk/feature/qldocs
C#: Add missing QlDocs
2 parents 8caaf8f + 29eaacd commit 647ed03

File tree

21 files changed

+124
-26
lines changed

21 files changed

+124
-26
lines changed

csharp/ql/src/Linq/Helpers.qll

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,32 @@
66
import csharp
77

88
//#################### PREDICATES ####################
9-
Stmt firstStmt(ForeachStmt fes) {
9+
private Stmt firstStmt(ForeachStmt fes) {
1010
if fes.getBody() instanceof BlockStmt
1111
then result = fes.getBody().(BlockStmt).getStmt(0)
1212
else result = fes.getBody()
1313
}
1414

15+
private int numStmts(ForeachStmt fes) {
16+
if fes.getBody() instanceof BlockStmt
17+
then result = count(fes.getBody().(BlockStmt).getAStmt())
18+
else result = 1
19+
}
20+
21+
/** Holds if the type's qualified name is "System.Linq.Enumerable" */
1522
predicate isEnumerableType(ValueOrRefType t) { t.hasQualifiedName("System.Linq.Enumerable") }
1623

24+
/** Holds if the type's qualified name starts with "System.Collections.Generic.IEnumerable" */
1725
predicate isIEnumerableType(ValueOrRefType t) {
1826
t.getQualifiedName().matches("System.Collections.Generic.IEnumerable%")
1927
}
2028

29+
/**
30+
* Holds if `foreach` statement `fes` could be converted to a `.All()` call.
31+
* That is, the `ForeachStmt` contains a single `if` with a condition that
32+
* accesses the loop variable and with a body that assigns `false` to a variable
33+
* and `break`s out of the `foreach`.
34+
*/
2135
predicate missedAllOpportunity(ForeachStmt fes) {
2236
exists(IfStmt is |
2337
// The loop contains an if statement with no else case, and nothing else.
@@ -36,6 +50,12 @@ predicate missedAllOpportunity(ForeachStmt fes) {
3650
)
3751
}
3852

53+
/**
54+
* Holds if `foreach` statement `fes` could be converted to a `.Cast()` call.
55+
* That is, the loop variable is accessed only in the first statement of the
56+
* block, and the access is a cast. The first statement needs to be a
57+
* `LocalVariableDeclStmt`.
58+
*/
3959
predicate missedCastOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
4060
s = firstStmt(fes) and
4161
forex(VariableAccess va | va = fes.getVariable().getAnAccess() |
@@ -47,6 +67,12 @@ predicate missedCastOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
4767
)
4868
}
4969

70+
/**
71+
* Holds if `foreach` statement `fes` could be converted to an `.OfType()` call.
72+
* That is, the loop variable is accessed only in the first statement of the
73+
* block, and the access is a cast with the `as` operator. The first statement
74+
* needs to be a `LocalVariableDeclStmt`.
75+
*/
5076
predicate missedOfTypeOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
5177
s = firstStmt(fes) and
5278
forex(VariableAccess va | va = fes.getVariable().getAnAccess() |
@@ -58,6 +84,12 @@ predicate missedOfTypeOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
5884
)
5985
}
6086

87+
/**
88+
* Holds if `foreach` statement `fes` could be converted to a `.Select()` call.
89+
* That is, the loop variable is accessed only in the first statement of the
90+
* block, and the access is not a cast. The first statement needs to be a
91+
* `LocalVariableDeclStmt`.
92+
*/
6193
predicate missedSelectOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
6294
s = firstStmt(fes) and
6395
forex(VariableAccess va | va = fes.getVariable().getAnAccess() |
@@ -66,6 +98,12 @@ predicate missedSelectOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
6698
not s.getAVariableDeclExpr().getInitializer() instanceof Cast
6799
}
68100

101+
/**
102+
* Holds if `foreach` statement `fes` could be converted to a `.Where()` call.
103+
* That is, first statement of the loop is an `if`, which accesses the loop
104+
* variable, and the body of the `if` is either a `continue` or there's nothing
105+
* else in the loop than the `if`.
106+
*/
69107
predicate missedWhereOpportunity(ForeachStmt fes, IfStmt is) {
70108
// The very first thing the foreach loop does is test its iteration variable.
71109
is = firstStmt(fes) and
@@ -82,12 +120,6 @@ predicate missedWhereOpportunity(ForeachStmt fes, IfStmt is) {
82120
)
83121
}
84122

85-
int numStmts(ForeachStmt fes) {
86-
if fes.getBody() instanceof BlockStmt
87-
then result = count(fes.getBody().(BlockStmt).getAStmt())
88-
else result = 1
89-
}
90-
91123
//#################### CLASSES ####################
92124
/** A LINQ Any(...) call. */
93125
class AnyCall extends MethodCall {

csharp/ql/src/external/CodeDuplication.qll

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ class SimilarBlock extends Copy, @similarity {
6666
}
6767
}
6868

69-
Method sourceMethod() { method_location(result, _) and numlines(result, _, _, _) }
69+
private Method sourceMethod() { method_location(result, _) and numlines(result, _, _, _) }
7070

71-
int numberOfSourceMethods(Class c) {
71+
private int numberOfSourceMethods(Class c) {
7272
result = count(Method m | m = sourceMethod() and m.getDeclaringType() = c)
7373
}
7474

@@ -97,6 +97,7 @@ private predicate duplicateStatement(Method m1, Method m2, Stmt s1, Stmt s2) {
9797
)
9898
}
9999

100+
/** Holds if `duplicate` number of statements are duplicated in the methods. */
100101
predicate duplicateStatements(Method m1, Method m2, int duplicate, int total) {
101102
duplicate = strictcount(Stmt s | duplicateStatement(m1, m2, s, _)) and
102103
total = strictcount(statementInMethod(m1))
@@ -109,7 +110,7 @@ predicate duplicateMethod(Method m, Method other) {
109110
exists(int total | duplicateStatements(m, other, total, total))
110111
}
111112

112-
predicate similarLines(File f, int line) {
113+
private predicate similarLines(File f, int line) {
113114
exists(SimilarBlock b | b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()])
114115
}
115116

@@ -148,7 +149,7 @@ private predicate similarLinesCovered(File f, int coveredLines, File otherFile)
148149
)
149150
}
150151

151-
predicate duplicateLines(File f, int line) {
152+
private predicate duplicateLines(File f, int line) {
152153
exists(DuplicateBlock b |
153154
b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()]
154155
)
@@ -189,6 +190,7 @@ private predicate duplicateLinesCovered(File f, int coveredLines, File otherFile
189190
)
190191
}
191192

193+
/** Holds if the two files are not duplicated but have more than 80% similar lines. */
192194
predicate similarFiles(File f, File other, int percent) {
193195
exists(int covered, int total |
194196
similarLinesCovered(f, covered, other) and
@@ -199,6 +201,7 @@ predicate similarFiles(File f, File other, int percent) {
199201
not duplicateFiles(f, other, _)
200202
}
201203

204+
/** Holds if the two files have more than 70% duplicated lines. */
202205
predicate duplicateFiles(File f, File other, int percent) {
203206
exists(int covered, int total |
204207
duplicateLinesCovered(f, covered, other) and
@@ -209,7 +212,7 @@ predicate duplicateFiles(File f, File other, int percent) {
209212
}
210213

211214
pragma[noopt]
212-
predicate duplicateAnonymousClass(AnonymousClass c, AnonymousClass other) {
215+
private predicate duplicateAnonymousClass(AnonymousClass c, AnonymousClass other) {
213216
exists(int numDup |
214217
numDup =
215218
strictcount(Method m1 |
@@ -248,6 +251,7 @@ private predicate mostlyDuplicateClassBase(Class c, Class other, int numDup, int
248251
not other instanceof AnonymousClass
249252
}
250253

254+
/** Holds if the methods in the two classes are more than 80% duplicated. */
251255
predicate mostlyDuplicateClass(Class c, Class other, string message) {
252256
exists(int numDup, int total |
253257
mostlyDuplicateClassBase(c, other, numDup, total) and
@@ -272,19 +276,28 @@ predicate mostlyDuplicateClass(Class c, Class other, string message) {
272276
)
273277
}
274278

279+
/** Holds if the two files are similar or duplicated. */
275280
predicate fileLevelDuplication(File f, File other) {
276281
similarFiles(f, other, _) or duplicateFiles(f, other, _)
277282
}
278283

284+
/**
285+
* Holds if the two classes are duplicated anonymous classes or more than 80% of
286+
* their methods are duplicated.
287+
*/
279288
predicate classLevelDuplication(Class c, Class other) {
280289
duplicateAnonymousClass(c, other) or mostlyDuplicateClass(c, other, _)
281290
}
282291

283-
Element whitelistedDuplicateElement() {
292+
private Element whitelistedDuplicateElement() {
284293
result instanceof UsingNamespaceDirective or
285294
result instanceof UsingStaticDirective
286295
}
287296

297+
/**
298+
* Holds if the `line` in the `file` contains an element, such as a `using`
299+
* directive, that is not considered for code duplication.
300+
*/
288301
predicate whitelistedLineForDuplication(File file, int line) {
289302
exists(Location loc | loc = whitelistedDuplicateElement().getLocation() |
290303
line = loc.getStartLine() and file = loc.getFile()

csharp/ql/src/semmle/code/cil/Access.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class ReadRefAccess extends ReadAccess, ReadRef { }
3131

3232
/** An instruction that writes a variable. */
3333
class WriteAccess extends VariableAccess, @cil_write_access {
34+
/** Gets the expression whose value is used in this variable write. */
3435
Expr getExpr() { none() }
3536
}
3637

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,9 @@ class Operator extends Callable, Member, Attributable, @operator {
437437

438438
override string getName() { operators(this, _, result, _, _, _) }
439439

440+
/**
441+
* Gets the metadata name of the operator, such as `op_implicit` or `op_RightShift`.
442+
*/
440443
string getFunctionName() { none() }
441444

442445
override ValueOrRefType getDeclaringType() { operators(this, _, _, result, _, _) }

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,11 @@ predicate convNullableType(ValueOrRefType fromType, NullableType toType) {
514514
)
515515
}
516516

517+
/**
518+
* Holds if `fromType` is `NullType`, and `toType` is a type that can represent
519+
* the `null` value, such as a reference type, `Nullable<T>` or a type parameter
520+
* with contraints that restrict it to a reference type.
521+
*/
517522
// This is a deliberate, small Cartesian product, so we have manually lifted it to force the
518523
// evaluator to evaluate it in its entirety, rather than trying to optimize it in context.
519524
pragma[noinline]

csharp/ql/src/semmle/code/csharp/dispatch/RuntimeCallable.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class RuntimeMethod extends RuntimeCallable {
2626
this instanceof CIL::Method
2727
}
2828

29+
/** Holds if the method is `static`. */
2930
predicate isStatic() { this.(Method).isStatic() or this.(CIL::Method).isStatic() }
3031
}
3132

csharp/ql/src/semmle/code/csharp/exprs/Expr.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,7 @@ class RangeExpr extends Expr, @range_expr {
10111011

10121012
/** An index expression, for example `^1` meaning "1 from the end". */
10131013
class IndexExpr extends Expr, @index_expr {
1014+
/** Gets the sub expression of this index expression. */
10141015
Expr getExpr() { result.getParent() = this }
10151016

10161017
override string toString() { result = "^..." }

csharp/ql/src/semmle/code/csharp/frameworks/EntityFramework.qll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ private import semmle.code.csharp.frameworks.system.collections.Generic
88
private import semmle.code.csharp.frameworks.Sql
99
private import semmle.code.csharp.dataflow.LibraryTypeDataFlow
1010

11+
/**
12+
* Definitions relating to the `System.ComponentModel.DataAnnotations`
13+
* namespace.
14+
*/
1115
module DataAnnotations {
16+
/** Class for `NotMappedAttribute`. */
1217
class NotMappedAttribute extends Attribute {
1318
NotMappedAttribute() {
1419
this
@@ -18,6 +23,10 @@ module DataAnnotations {
1823
}
1924
}
2025

26+
/**
27+
* Definitions relating to the `Microsoft.EntityFrameworkCore` or
28+
* `System.Data.Entity` namespaces.
29+
*/
2130
module EntityFramework {
2231
/** An EF6 or EFCore namespace. */
2332
class EFNamespace extends Namespace {
@@ -43,12 +52,14 @@ module EntityFramework {
4352
class DbContext extends EFClass {
4453
DbContext() { this.getName() = "DbContext" }
4554

55+
/** Gets a `Find` or `FindAsync` method in the `DbContext`. */
4656
Method getAFindMethod() {
4757
result = this.getAMethod("Find")
4858
or
4959
result = this.getAMethod("FindAsync")
5060
}
5161

62+
/** Gets an `Update` method in the `DbContext`. */
5263
Method getAnUpdateMethod() { result = this.getAMethod("Update") }
5364
}
5465

@@ -119,6 +130,7 @@ module EntityFramework {
119130
preservesValue = false
120131
}
121132

133+
/** Gets a conversion operator from `string` to `RawSqlString`. */
122134
ConversionOperator getAConversionTo() {
123135
result = this.getAMember() and
124136
result.getTargetType() instanceof RawSqlStringStruct and

csharp/ql/src/semmle/code/csharp/frameworks/JsonNET.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,10 @@ module JsonNET {
135135
class JsonSerializerClass extends JsonClass, LibraryTypeDataFlow {
136136
JsonSerializerClass() { this.hasName("JsonSerializer") }
137137

138+
/** Gets the method for `JsonSerializer.Serialize`. */
138139
Method getSerializeMethod() { result = this.getAMethod("Serialize") }
139140

141+
/** Gets the method for `JsonSerializer.Deserialize`. */
140142
Method getDeserializeMethod() { result = this.getAMethod("Deserialize") }
141143

142144
override predicate callableFlow(

csharp/ql/src/semmle/code/csharp/frameworks/NHibernate.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
/**
2+
* Classes for modelling NHibernate.
3+
*/
4+
15
import csharp
26
private import semmle.code.csharp.frameworks.System
37
private import semmle.code.csharp.frameworks.system.Collections
48
private import semmle.code.csharp.frameworks.Sql
59

10+
/** Definitions relating to the `NHibernate` package. */
611
module NHibernate {
712
/** A class that is mapped to the database. */
813
abstract class MappedClass extends Class { }

0 commit comments

Comments
 (0)