-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathMissedReadonlyOpportunity.ql
More file actions
38 lines (33 loc) · 1.06 KB
/
MissedReadonlyOpportunity.ql
File metadata and controls
38 lines (33 loc) · 1.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
* @name Missed 'readonly' opportunity
* @description A private field where all assignments occur as part of the declaration or
* in a constructor in the same class can be 'readonly'.
* @kind problem
* @problem.severity recommendation
* @precision high
* @id cs/missed-readonly-modifier
* @tags maintainability
* language-features
*/
import csharp
predicate defTargetsField(AssignableDefinition def, Field f) {
def.getTarget().getUnboundDeclaration() = f
}
predicate isReadonlyCompatibleDefinition(AssignableDefinition def, Field f) {
defTargetsField(def, f) and
(
def.getEnclosingCallable().(Constructor).getDeclaringType() = f.getDeclaringType()
or
def instanceof AssignableDefinitions::InitializerDefinition
)
}
predicate canBeReadonly(Field f) {
forex(AssignableDefinition def | defTargetsField(def, f) | isReadonlyCompatibleDefinition(def, f))
}
from Field f
where
canBeReadonly(f) and
not f.isConst() and
not f.isReadOnly() and
not f.isEffectivelyPublic()
select f, "Field '" + f.getName() + "' can be 'readonly'."