mirror of
https://github.com/github/codeql.git
synced 2025-12-23 04:06:37 +01:00
C++: Autoformat Architecture + Best Practices
This commit is contained in:
@@ -10,11 +10,12 @@
|
||||
* statistical
|
||||
* non-attributable
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
predicate functionUsesVariable(Function source, Variable v, File target) {
|
||||
v.getAnAccess().getEnclosingFunction() = source and
|
||||
not (v.(LocalScopeVariable).getFunction() = source) and
|
||||
not v.(LocalScopeVariable).getFunction() = source and
|
||||
v.getFile() = target
|
||||
}
|
||||
|
||||
@@ -25,15 +26,15 @@ predicate functionUsesFunction(Function source, Function f, File target) {
|
||||
|
||||
predicate dependencyCount(Function source, File target, int res) {
|
||||
res = strictcount(Declaration d |
|
||||
functionUsesVariable(source, d, target) or
|
||||
functionUsesFunction(source, d, target)
|
||||
)
|
||||
functionUsesVariable(source, d, target) or
|
||||
functionUsesFunction(source, d, target)
|
||||
)
|
||||
}
|
||||
|
||||
predicate selfDependencyCountOrZero(Function source, int res) {
|
||||
exists(File target
|
||||
| target = source.getFile() and onlyInFile(source, target)
|
||||
| res = max(int i | dependencyCount(source, target, i) or i = 0))
|
||||
exists(File target | target = source.getFile() and onlyInFile(source, target) |
|
||||
res = max(int i | dependencyCount(source, target, i) or i = 0)
|
||||
)
|
||||
}
|
||||
|
||||
predicate dependsHighlyOn(Function source, File target, int res) {
|
||||
@@ -41,7 +42,7 @@ predicate dependsHighlyOn(Function source, File target, int res) {
|
||||
target.fromSource() and
|
||||
exists(int selfCount |
|
||||
selfDependencyCountOrZero(source, selfCount) and
|
||||
res > 2*selfCount and
|
||||
res > 2 * selfCount and
|
||||
res > 4
|
||||
)
|
||||
}
|
||||
@@ -52,14 +53,18 @@ predicate onlyInFile(Function f, File file) {
|
||||
}
|
||||
|
||||
from Function f, File other, int selfCount, int depCount, string selfDeps
|
||||
where dependsHighlyOn(f, other, depCount) and
|
||||
selfDependencyCountOrZero(f, selfCount) and
|
||||
not exists(File yetAnother | dependsHighlyOn(f, yetAnother, _) and yetAnother != other) and
|
||||
not other instanceof HeaderFile and
|
||||
not f instanceof MemberFunction
|
||||
and if selfCount = 0 then selfDeps = "0 dependencies"
|
||||
else if selfCount = 1 then selfDeps = "only 1 dependency"
|
||||
else selfDeps = "only " + selfCount.toString() + " dependencies"
|
||||
select f, "Function " + f.getName() + " could be moved to file $@" +
|
||||
" since it has " + depCount.toString() + " dependencies to that file, but " +
|
||||
selfDeps + " to its own file.", other, other.getBaseName()
|
||||
where
|
||||
dependsHighlyOn(f, other, depCount) and
|
||||
selfDependencyCountOrZero(f, selfCount) and
|
||||
not exists(File yetAnother | dependsHighlyOn(f, yetAnother, _) and yetAnother != other) and
|
||||
not other instanceof HeaderFile and
|
||||
not f instanceof MemberFunction and
|
||||
if selfCount = 0
|
||||
then selfDeps = "0 dependencies"
|
||||
else
|
||||
if selfCount = 1
|
||||
then selfDeps = "only 1 dependency"
|
||||
else selfDeps = "only " + selfCount.toString() + " dependencies"
|
||||
select f,
|
||||
"Function " + f.getName() + " could be moved to file $@" + " since it has " + depCount.toString() +
|
||||
" dependencies to that file, but " + selfDeps + " to its own file.", other, other.getBaseName()
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* @result_ondemand succeed 48
|
||||
* @tags maintainability
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from Class s
|
||||
|
||||
@@ -7,11 +7,10 @@
|
||||
* @treemap.warnOn highValues
|
||||
* @tags maintainability
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from Class c
|
||||
where c.fromSource()
|
||||
select c as Class,
|
||||
c.getMetrics().getAfferentCoupling() as AfferentCoupling,
|
||||
c.getMetrics().getEfferentSourceCoupling() as EfferentCoupling
|
||||
order by AfferentCoupling desc
|
||||
select c as Class, c.getMetrics().getAfferentCoupling() as AfferentCoupling,
|
||||
c.getMetrics().getEfferentSourceCoupling() as EfferentCoupling order by AfferentCoupling desc
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* @result_ondemand succeed 48
|
||||
* @tags maintainability
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
/** does source class c have inheritance depth d? */
|
||||
@@ -18,6 +19,5 @@ predicate hasInheritanceDepth(Class c, int d) {
|
||||
|
||||
from int depth
|
||||
where hasInheritanceDepth(_, depth)
|
||||
select depth as InheritanceDepth,
|
||||
count(Class c | hasInheritanceDepth(c, depth)) as NumberOfClasses
|
||||
order by InheritanceDepth
|
||||
select depth as InheritanceDepth, count(Class c | hasInheritanceDepth(c, depth)) as NumberOfClasses
|
||||
order by InheritanceDepth
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* @tags maintainability
|
||||
* modularity
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from MetricNamespace a, MetricNamespace b
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
* @tags maintainability
|
||||
* modularity
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from Class c
|
||||
where c.fromSource()
|
||||
and c.isTopLevel()
|
||||
and c.getParentScope() instanceof GlobalNamespace
|
||||
where
|
||||
c.fromSource() and
|
||||
c.isTopLevel() and
|
||||
c.getParentScope() instanceof GlobalNamespace
|
||||
select c, "This class is not declared in any namespace"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* @tags maintainability
|
||||
* modularity
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from MetricNamespace a, MetricNamespace b
|
||||
|
||||
@@ -5,31 +5,57 @@
|
||||
* @id cpp/architecture/general-statistics
|
||||
* @tags maintainability
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from string l, string n
|
||||
where (l = "Number of Namespaces" and
|
||||
n = count(Namespace p | p.fromSource()).toString())
|
||||
or (l = "Number of Files" and
|
||||
n = count(File f | f.fromSource()).toString())
|
||||
or (l = "Number of Header Files" and
|
||||
n = count(HeaderFile f | f.fromSource()).toString())
|
||||
or (l = "Number of C Files" and
|
||||
n = count(CFile f | f.fromSource()).toString())
|
||||
or (l = "Number of C++ Files" and
|
||||
n = count(CppFile f | f.fromSource()).toString())
|
||||
or (l = "Number of Classes" and
|
||||
n = count(Class c | c.fromSource() and not c instanceof Struct).toString())
|
||||
or (l = "Number of Structs" and
|
||||
n = count(Struct s | s.fromSource()and not s instanceof Union).toString())
|
||||
or (l = "Number of Unions" and
|
||||
n = count(Union u | u.fromSource()).toString())
|
||||
or (l = "Number of Functions" and
|
||||
n = count(Function f | f.fromSource()).toString())
|
||||
or (l = "Number of Lines Of Code" and
|
||||
n = sum(File f, int toSum | (f.fromSource()) and (toSum = f.getMetrics().getNumberOfLinesOfCode()) | toSum).toString())
|
||||
or (l = "Self-Containedness" and
|
||||
n = (100 * sum(Class c, int toSum | (c.fromSource()) and (toSum = c.getMetrics().getEfferentSourceCoupling()) | toSum)
|
||||
/ sum(Class c, int toSum | (c.fromSource()) and (toSum = c.getMetrics().getEfferentCoupling()) | toSum)).toString()
|
||||
+ "%")
|
||||
where
|
||||
l = "Number of Namespaces" and
|
||||
n = count(Namespace p | p.fromSource()).toString()
|
||||
or
|
||||
l = "Number of Files" and
|
||||
n = count(File f | f.fromSource()).toString()
|
||||
or
|
||||
l = "Number of Header Files" and
|
||||
n = count(HeaderFile f | f.fromSource()).toString()
|
||||
or
|
||||
l = "Number of C Files" and
|
||||
n = count(CFile f | f.fromSource()).toString()
|
||||
or
|
||||
l = "Number of C++ Files" and
|
||||
n = count(CppFile f | f.fromSource()).toString()
|
||||
or
|
||||
l = "Number of Classes" and
|
||||
n = count(Class c | c.fromSource() and not c instanceof Struct).toString()
|
||||
or
|
||||
l = "Number of Structs" and
|
||||
n = count(Struct s | s.fromSource() and not s instanceof Union).toString()
|
||||
or
|
||||
l = "Number of Unions" and
|
||||
n = count(Union u | u.fromSource()).toString()
|
||||
or
|
||||
l = "Number of Functions" and
|
||||
n = count(Function f | f.fromSource()).toString()
|
||||
or
|
||||
l = "Number of Lines Of Code" and
|
||||
n = sum(File f, int toSum |
|
||||
f.fromSource() and toSum = f.getMetrics().getNumberOfLinesOfCode()
|
||||
|
|
||||
toSum
|
||||
).toString()
|
||||
or
|
||||
l = "Self-Containedness" and
|
||||
n = (
|
||||
100 *
|
||||
sum(Class c, int toSum |
|
||||
c.fromSource() and toSum = c.getMetrics().getEfferentSourceCoupling()
|
||||
|
|
||||
toSum
|
||||
) /
|
||||
sum(Class c, int toSum |
|
||||
c.fromSource() and toSum = c.getMetrics().getEfferentCoupling()
|
||||
|
|
||||
toSum
|
||||
)
|
||||
).toString() + "%"
|
||||
select l as Title, n as Value
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
* statistical
|
||||
* non-attributable
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
predicate remoteVarAccess(File source, File target, VariableAccess va) {
|
||||
@@ -48,16 +49,19 @@ predicate highDependencyCount(File source, File target, int res) {
|
||||
variableDependencyCount(source, target, varCount) and
|
||||
functionDependencyCount(source, target, funCount) and
|
||||
res = varCount + funCount and
|
||||
res > 20)
|
||||
res > 20
|
||||
)
|
||||
}
|
||||
|
||||
from File a, File b, int ca, int cb
|
||||
where highDependencyCount(a, b, ca) and
|
||||
highDependencyCount(b, a, cb) and
|
||||
ca >= cb and
|
||||
a != b and
|
||||
not a instanceof HeaderFile and
|
||||
not b instanceof HeaderFile and
|
||||
b.getShortName().trim().length() > 0
|
||||
select a, "File is too closely tied to $@ (" + ca.toString() + " dependencies one way and " + cb.toString() + " the other).",
|
||||
b, b.getBaseName()
|
||||
where
|
||||
highDependencyCount(a, b, ca) and
|
||||
highDependencyCount(b, a, cb) and
|
||||
ca >= cb and
|
||||
a != b and
|
||||
not a instanceof HeaderFile and
|
||||
not b instanceof HeaderFile and
|
||||
b.getShortName().trim().length() > 0
|
||||
select a,
|
||||
"File is too closely tied to $@ (" + ca.toString() + " dependencies one way and " + cb.toString() +
|
||||
" the other).", b, b.getBaseName()
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
* statistical
|
||||
* non-attributable
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from Class t, int n
|
||||
where t.fromSource() and
|
||||
n = t.getMetrics().getEfferentSourceCoupling() and
|
||||
n > 10
|
||||
where
|
||||
t.fromSource() and
|
||||
n = t.getMetrics().getEfferentSourceCoupling() and
|
||||
n > 10
|
||||
select t as Class, "This class has too many dependencies (" + n.toString() + ")"
|
||||
|
||||
@@ -9,41 +9,51 @@
|
||||
* statistical
|
||||
* non-attributable
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
string kindstr(Class c)
|
||||
{
|
||||
string kindstr(Class c) {
|
||||
exists(int kind | usertypes(unresolveElement(c), _, kind) |
|
||||
(kind = 1 and result = "Struct") or
|
||||
(kind = 2 and result = "Class") or
|
||||
(kind = 6 and result = "Template class")
|
||||
kind = 1 and result = "Struct"
|
||||
or
|
||||
kind = 2 and result = "Class"
|
||||
or
|
||||
kind = 6 and result = "Template class"
|
||||
)
|
||||
}
|
||||
|
||||
predicate vdeInfo(VariableDeclarationEntry vde, Class c, File f, int line)
|
||||
{
|
||||
predicate vdeInfo(VariableDeclarationEntry vde, Class c, File f, int line) {
|
||||
c = vde.getVariable().getDeclaringType() and
|
||||
f = vde.getLocation().getFile() and
|
||||
line = vde.getLocation().getStartLine()
|
||||
}
|
||||
|
||||
predicate previousVde(VariableDeclarationEntry previous, VariableDeclarationEntry vde)
|
||||
{
|
||||
predicate previousVde(VariableDeclarationEntry previous, VariableDeclarationEntry vde) {
|
||||
exists(Class c, File f, int line | vdeInfo(vde, c, f, line) |
|
||||
vdeInfo(previous, c, f, line - 3) or
|
||||
vdeInfo(previous, c, f, line - 2) or
|
||||
vdeInfo(previous, c, f, line - 1) or
|
||||
(vdeInfo(previous, c, f, line) and exists(int prevCol, int vdeCol |
|
||||
prevCol = previous.getLocation().getStartColumn() and vdeCol = vde.getLocation().getStartColumn() |
|
||||
prevCol < vdeCol or (prevCol = vdeCol and previous.getName() < vde.getName())
|
||||
))
|
||||
vdeInfo(previous, c, f, line - 3)
|
||||
or
|
||||
vdeInfo(previous, c, f, line - 2)
|
||||
or
|
||||
vdeInfo(previous, c, f, line - 1)
|
||||
or
|
||||
vdeInfo(previous, c, f, line) and
|
||||
exists(int prevCol, int vdeCol |
|
||||
prevCol = previous.getLocation().getStartColumn() and
|
||||
vdeCol = vde.getLocation().getStartColumn()
|
||||
|
|
||||
prevCol < vdeCol
|
||||
or
|
||||
prevCol = vdeCol and previous.getName() < vde.getName()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate masterVde(VariableDeclarationEntry master, VariableDeclarationEntry vde)
|
||||
{
|
||||
(not previousVde(_, vde) and master = vde) or
|
||||
exists(VariableDeclarationEntry previous | previousVde(previous, vde) and masterVde(master, previous))
|
||||
predicate masterVde(VariableDeclarationEntry master, VariableDeclarationEntry vde) {
|
||||
not previousVde(_, vde) and master = vde
|
||||
or
|
||||
exists(VariableDeclarationEntry previous |
|
||||
previousVde(previous, vde) and masterVde(master, previous)
|
||||
)
|
||||
}
|
||||
|
||||
class VariableDeclarationGroup extends ElementBase {
|
||||
@@ -51,9 +61,8 @@ class VariableDeclarationGroup extends ElementBase {
|
||||
this instanceof VariableDeclarationEntry and
|
||||
not previousVde(_, this)
|
||||
}
|
||||
Class getClass() {
|
||||
vdeInfo(this, result, _, _)
|
||||
}
|
||||
|
||||
Class getClass() { vdeInfo(this, result, _, _) }
|
||||
|
||||
// pragma[noopt] since otherwise the two locationInfo relations get join-ordered
|
||||
// after each other
|
||||
@@ -63,7 +72,9 @@ class VariableDeclarationGroup extends ElementBase {
|
||||
masterVde(this, last) and
|
||||
this instanceof VariableDeclarationGroup and
|
||||
not previousVde(last, _) and
|
||||
exists(VariableDeclarationEntry vde | vde=this and vde instanceof VariableDeclarationEntry and vde.getLocation() = lstart) and
|
||||
exists(VariableDeclarationEntry vde |
|
||||
vde = this and vde instanceof VariableDeclarationEntry and vde.getLocation() = lstart
|
||||
) and
|
||||
last.getLocation() = lend and
|
||||
lstart.hasLocationInfo(path, startline, startcol, _, _) and
|
||||
lend.hasLocationInfo(path, _, _, endline, endcol)
|
||||
@@ -71,15 +82,16 @@ class VariableDeclarationGroup extends ElementBase {
|
||||
}
|
||||
|
||||
string describeGroup() {
|
||||
if previousVde(this, _) then
|
||||
result = "group of "
|
||||
+ strictcount(string name
|
||||
| exists(VariableDeclarationEntry vde
|
||||
| masterVde(this, vde) and
|
||||
name = vde.getName()))
|
||||
+ " fields here"
|
||||
else
|
||||
result = "declaration of " + this.(VariableDeclarationEntry).getVariable().getName()
|
||||
if previousVde(this, _)
|
||||
then
|
||||
result = "group of " +
|
||||
strictcount(string name |
|
||||
exists(VariableDeclarationEntry vde |
|
||||
masterVde(this, vde) and
|
||||
name = vde.getName()
|
||||
)
|
||||
) + " fields here"
|
||||
else result = "declaration of " + this.(VariableDeclarationEntry).getVariable().getName()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,26 +101,32 @@ class ExtClass extends Class {
|
||||
}
|
||||
|
||||
predicate hasLocationInfo(string path, int startline, int startcol, int endline, int endcol) {
|
||||
if hasOneVariableGroup() then
|
||||
exists(VariableDeclarationGroup vdg | vdg.getClass() = this | vdg.hasLocationInfo(path, startline, startcol, endline, endcol))
|
||||
else
|
||||
getLocation().hasLocationInfo(path, startline, startcol, endline, endcol)
|
||||
if hasOneVariableGroup()
|
||||
then
|
||||
exists(VariableDeclarationGroup vdg | vdg.getClass() = this |
|
||||
vdg.hasLocationInfo(path, startline, startcol, endline, endcol)
|
||||
)
|
||||
else getLocation().hasLocationInfo(path, startline, startcol, endline, endcol)
|
||||
}
|
||||
}
|
||||
|
||||
from ExtClass c, int n, VariableDeclarationGroup vdg, string suffix
|
||||
where n = strictcount(string fieldName
|
||||
| exists(Field f
|
||||
| f.getDeclaringType() = c and
|
||||
fieldName = f.getName() and
|
||||
// IBOutlet's are a way of building GUIs
|
||||
// automatically out of ObjC properties.
|
||||
// We don't want to count those for the
|
||||
// purposes of this query.
|
||||
not (f.getType().getAnAttribute().hasName("iboutlet")))) and
|
||||
n > 15 and
|
||||
not c.isConstructedFrom(_) and
|
||||
c = vdg.getClass() and
|
||||
if c.hasOneVariableGroup() then suffix = "" else suffix = " - see $@"
|
||||
select c, kindstr(c) + " " + c.getName() + " has " + n + " fields; we suggest refactoring to 15 fields or fewer" + suffix + ".",
|
||||
vdg, vdg.describeGroup()
|
||||
where
|
||||
n = strictcount(string fieldName |
|
||||
exists(Field f |
|
||||
f.getDeclaringType() = c and
|
||||
fieldName = f.getName() and
|
||||
// IBOutlet's are a way of building GUIs
|
||||
// automatically out of ObjC properties.
|
||||
// We don't want to count those for the
|
||||
// purposes of this query.
|
||||
not f.getType().getAnAttribute().hasName("iboutlet")
|
||||
)
|
||||
) and
|
||||
n > 15 and
|
||||
not c.isConstructedFrom(_) and
|
||||
c = vdg.getClass() and
|
||||
if c.hasOneVariableGroup() then suffix = "" else suffix = " - see $@"
|
||||
select c,
|
||||
kindstr(c) + " " + c.getName() + " has " + n +
|
||||
" fields; we suggest refactoring to 15 fields or fewer" + suffix + ".", vdg, vdg.describeGroup()
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
* statistical
|
||||
* non-attributable
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from Function f, int n
|
||||
where f.fromSource() and
|
||||
n = f.getMetrics().getNumberOfCalls() and
|
||||
n > 99 and
|
||||
not f.isMultiplyDefined()
|
||||
where
|
||||
f.fromSource() and
|
||||
n = f.getMetrics().getNumberOfCalls() and
|
||||
n > 99 and
|
||||
not f.isMultiplyDefined()
|
||||
select f as Function, "This function makes too many calls (" + n.toString() + ")"
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
* statistical
|
||||
* non-attributable
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from Function f, int complexity
|
||||
where complexity = f.getMetrics().getCyclomaticComplexity()
|
||||
and complexity > 250
|
||||
where
|
||||
complexity = f.getMetrics().getCyclomaticComplexity() and
|
||||
complexity > 250
|
||||
select f, "Function has high cyclomatic complexity: " + complexity.toString()
|
||||
|
||||
@@ -9,10 +9,13 @@
|
||||
* statistical
|
||||
* non-attributable
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from Function f
|
||||
where f.fromSource() and
|
||||
f.getMetrics().getNumberOfParameters() > 15
|
||||
select f, "This function has too many parameters ("
|
||||
+ f.getMetrics().getNumberOfParameters().toString() + ")"
|
||||
where
|
||||
f.fromSource() and
|
||||
f.getMetrics().getNumberOfParameters() > 15
|
||||
select f,
|
||||
"This function has too many parameters (" + f.getMetrics().getNumberOfParameters().toString() +
|
||||
")"
|
||||
|
||||
Reference in New Issue
Block a user