Skip to content

Commit b14cac6

Browse files
authored
Merge pull request github#12689 from asgerf/rb/perf-diagnostics
Ruby: performance diagnostics query
2 parents a826c83 + 59c7283 commit b14cac6

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/**
2+
* @id rb/performance-diagnostics
3+
* @kind table
4+
*/
5+
6+
/*
7+
* This query outputs some numbers that can be used to help narrow down the cause of performance
8+
* issues in a codebase, without leaking any actual code or identifiers from the codebase.
9+
*/
10+
11+
import ruby
12+
import codeql.ruby.ApiGraphs
13+
14+
query int numberOfModuleBases() { result = count(Ast::ModuleBase cls) }
15+
16+
query int numberOfClasses() { result = count(Ast::ClassDeclaration cls) }
17+
18+
query int numberOfMethods() { result = count(Ast::MethodBase method) }
19+
20+
query int numberOfCallables() { result = count(Ast::Callable c) }
21+
22+
query int numberOfMethodCalls() { result = count(Ast::MethodCall call) }
23+
24+
query int numberOfCalls() { result = count(Ast::Call call) }
25+
26+
signature module HistogramSig {
27+
bindingset[this]
28+
class Bucket;
29+
30+
int getCounts(Bucket bucket);
31+
}
32+
33+
module MakeHistogram<HistogramSig H> {
34+
predicate histogram(int bucketSize, int frequency) {
35+
frequency = strictcount(H::Bucket bucket | H::getCounts(bucket) = bucketSize)
36+
}
37+
}
38+
39+
module MethodNames implements HistogramSig {
40+
class Bucket = string;
41+
42+
int getCounts(string name) {
43+
result = strictcount(Ast::MethodBase method | method.getName() = name) and
44+
name != "initialize"
45+
}
46+
}
47+
48+
query predicate numberOfMethodsWithNameHistogram = MakeHistogram<MethodNames>::histogram/2;
49+
50+
module CallTargets implements HistogramSig {
51+
class Bucket = Ast::Call;
52+
53+
int getCounts(Ast::Call call) { result = count(call.getATarget()) }
54+
}
55+
56+
query predicate numberOfCallTargetsHistogram = MakeHistogram<CallTargets>::histogram/2;
57+
58+
module Callers implements HistogramSig {
59+
class Bucket = Ast::Callable;
60+
61+
int getCounts(Ast::Callable callable) {
62+
result = count(Ast::Call call | call.getATarget() = callable)
63+
}
64+
}
65+
66+
query predicate numberOfCallersHistogram = MakeHistogram<Callers>::histogram/2;
67+
68+
private DataFlow::MethodNode getAnOverriddenMethod(DataFlow::MethodNode method) {
69+
exists(DataFlow::ModuleNode cls, string name |
70+
method = cls.getInstanceMethod(name) and
71+
result = cls.getAnAncestor().getInstanceMethod(name) and
72+
result != method
73+
)
74+
}
75+
76+
module MethodOverrides implements HistogramSig {
77+
class Bucket = DataFlow::MethodNode;
78+
79+
int getCounts(DataFlow::MethodNode method) { result = count(getAnOverriddenMethod(method)) }
80+
}
81+
82+
query predicate numberOfOverriddenMethodsHistogram = MakeHistogram<MethodOverrides>::histogram/2;
83+
84+
module MethodOverriddenBy implements HistogramSig {
85+
class Bucket = DataFlow::MethodNode;
86+
87+
int getCounts(DataFlow::MethodNode method) {
88+
result = count(DataFlow::MethodNode overrider | method = getAnOverriddenMethod(overrider))
89+
}
90+
}
91+
92+
query predicate numberOfOverridingMethodsHistogram = MakeHistogram<MethodOverriddenBy>::histogram/2;
93+
94+
module Ancestors implements HistogramSig {
95+
class Bucket = DataFlow::ModuleNode;
96+
97+
int getCounts(DataFlow::ModuleNode mod) {
98+
result =
99+
count(DataFlow::ModuleNode ancestor | ancestor = mod.getAnAncestor() and ancestor != mod)
100+
}
101+
}
102+
103+
query predicate numberOfAncestorsHistogram = MakeHistogram<Ancestors>::histogram/2;
104+
105+
module Descendents implements HistogramSig {
106+
class Bucket = DataFlow::ModuleNode;
107+
108+
int getCounts(DataFlow::ModuleNode mod) {
109+
not mod.getQualifiedName() = ["Object", "Kernel", "BasicObject", "Class", "Module"] and
110+
result =
111+
count(DataFlow::ModuleNode descendent |
112+
descendent = mod.getADescendent() and descendent != mod
113+
)
114+
}
115+
}
116+
117+
query predicate numberOfDescendentsHistogram = MakeHistogram<Descendents>::histogram/2;

0 commit comments

Comments
 (0)