Files
codeql/csharp/ql/src/Performance/StringConcatenationInLoop.ql
Anders Schack-Mulligen fc9c7ea55a CSharp: Autoformat qls
2019-02-12 14:38:42 +01:00

56 lines
1.5 KiB
Plaintext

/**
* @name String concatenation in loop
* @description Finds code that performs string concatenation in a loop using the + operator.
* @kind problem
* @problem.severity recommendation
* @precision very-high
* @id cs/string-concatenation-in-loop
* @tags efficiency
* maintainability
*/
import csharp
// any use of + that has string type
class StringCat extends AddExpr {
StringCat() { this.getType() instanceof StringType }
}
/**
* Holds if `e` is an assignment of the form
* `v = ... + ... v ...`
* where `v` is a simple variable (and not, for example, a property).
*/
predicate isSelfConcatAssignExpr(AssignExpr e, Variable v) {
not e = any(AssignAddExpr a).getExpandedAssignment() and
exists(VariableAccess use |
stringCatContains(e.getRValue(), use) and
use.getTarget() = e.getTargetVariable() and
v = use.getTarget()
)
}
predicate stringCatContains(StringCat expr, Expr child) {
child = expr or
stringCatContains(expr, child.getParent())
}
/**
* Holds if `e` is an assignment of the form
* `v += ...`
* where `v` is a simple variable (and not, for example, a property).
*/
predicate isConcatExpr(AssignAddExpr e, Variable v) {
e.getLValue().getType() instanceof StringType and
v = e.getTargetVariable()
}
from Expr e
where
exists(LoopStmt loop, Variable v |
e.getEnclosingStmt().getParent*() = loop and
(isSelfConcatAssignExpr(e, v) or isConcatExpr(e, v)) and
forall(LocalVariableDeclExpr l | l.getVariable() = v | not l.getParent*() = loop)
)
select e, "String concatenation in loop: use 'StringBuilder'."