@@ -35,27 +35,37 @@ class MethodBase extends Callable, BodyStmt, Scope, TMethodBase {
35
35
or
36
36
result = BodyStmt .super .getAChild ( pred )
37
37
}
38
- }
39
38
40
- /** A call to ` private` . */
41
- private class Private extends MethodCall {
42
- Private ( ) { this . getMethodName ( ) = "private" }
39
+ /** Holds if this method is private. */
40
+ predicate isPrivate ( ) { none ( ) }
41
+ }
43
42
44
- /** Gets the method that this `private` call applies to, if any */
45
- Expr getMethod ( ) { result = this .getArgument ( 0 ) }
43
+ /**
44
+ * A method call which modifies another method in some way.
45
+ * For example, `private :foo` makes the method `foo` private.
46
+ */
47
+ private class MethodModifier extends MethodCall {
48
+ /** Gets the name of the method that this call applies to. */
49
+ Expr getMethodArgument ( ) { result = this .getArgument ( 0 ) }
46
50
47
- /**
48
- * Holds if this `private` call happens inside `c`, and refers to a
49
- * method named `name`.
50
- */
51
- pragma [ noinline]
52
- predicate isRef ( Namespace c , string name ) {
53
- this = c .getAStmt ( ) and
54
- name = this .getMethod ( ) .( SymbolLiteral ) .getValueText ( )
51
+ /** Gets the method that this call applies to. */
52
+ MethodBase getMethod ( ) {
53
+ result = this .getMethodArgument ( )
54
+ or
55
+ exists ( Namespace n |
56
+ n .getAStmt ( ) = this and
57
+ n .getAStmt ( ) = result and
58
+ result .getName ( ) = this .getMethodArgument ( ) .( StringlikeLiteral ) .getValueText ( )
59
+ )
55
60
}
61
+ }
62
+
63
+ /** A call to `private` or `private_class_method`. */
64
+ private class Private extends MethodModifier {
65
+ Private ( ) { this .getMethodName ( ) = "private" }
56
66
57
67
/**
58
- * Holds if this `private` call happens at position `i` inside `c`,
68
+ * Holds if this call happens at position `i` inside `c`,
59
69
* and the call has no arguments.
60
70
*/
61
71
pragma [ noinline]
@@ -65,6 +75,11 @@ private class Private extends MethodCall {
65
75
}
66
76
}
67
77
78
+ /** A call to `private_class_method`. */
79
+ private class PrivateClassMethod extends MethodModifier {
80
+ PrivateClassMethod ( ) { this .getMethodName ( ) = "private_class_method" }
81
+ }
82
+
68
83
/** A normal method. */
69
84
class Method extends MethodBase , TMethod {
70
85
private Ruby:: Method g ;
@@ -90,12 +105,6 @@ class Method extends MethodBase, TMethod {
90
105
*/
91
106
final predicate isSetter ( ) { g .getName ( ) instanceof Ruby:: Setter }
92
107
93
- pragma [ noinline]
94
- private predicate isDeclaredIn ( Namespace c , string name ) {
95
- this = c .getAStmt ( ) and
96
- name = this .getName ( )
97
- }
98
-
99
108
/**
100
109
* Holds if this method is private. All methods with the name prefix
101
110
* `private` are private below:
@@ -122,14 +131,9 @@ class Method extends MethodBase, TMethod {
122
131
* end
123
132
* ```
124
133
*/
125
- predicate isPrivate ( ) {
134
+ override predicate isPrivate ( ) {
126
135
this = any ( Private p ) .getMethod ( )
127
136
or
128
- exists ( Namespace c , Private p , string name |
129
- this .isDeclaredIn ( c , name ) and
130
- p .isRef ( c , name )
131
- )
132
- or
133
137
exists ( Namespace c , Private p , int i , int j |
134
138
p .hasNoArg ( c , i ) and
135
139
this = c .getStmt ( j ) and
@@ -175,6 +179,31 @@ class SingletonMethod extends MethodBase, TSingletonMethod {
175
179
or
176
180
pred = "getObject" and result = this .getObject ( )
177
181
}
182
+
183
+ /**
184
+ * Holds if this method is private. All methods with the name prefix
185
+ * `private` are private below:
186
+ *
187
+ * ```rb
188
+ * class C
189
+ * private_class_method def self.private1
190
+ * end
191
+ *
192
+ * def self.public
193
+ * end
194
+ *
195
+ * def self.private2
196
+ * end
197
+ * private_class_method :private2
198
+ *
199
+ * private # this has no effect on singleton methods
200
+ *
201
+ * def self.public2
202
+ * end
203
+ * end
204
+ * ```
205
+ */
206
+ override predicate isPrivate ( ) { this = any ( PrivateClassMethod p ) .getMethod ( ) }
178
207
}
179
208
180
209
/**
0 commit comments