@@ -56,5 +56,70 @@ module ActiveSupport {
56
56
}
57
57
}
58
58
}
59
+
60
+ /**
61
+ * Extensions to the `Enumerable` module.
62
+ */
63
+ module Enumerable {
64
+ private class ArrayIndex extends int {
65
+ ArrayIndex ( ) { this = any ( DataFlow:: Content:: KnownElementContent c ) .getIndex ( ) .getInt ( ) }
66
+ }
67
+
68
+ private class CompactBlankSummary extends SimpleSummarizedCallable {
69
+ CompactBlankSummary ( ) { this = "compact_blank" }
70
+
71
+ override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
72
+ input = "Argument[self].Element[any]" and
73
+ output = "ReturnValue.Element[?]" and
74
+ preservesValue = true
75
+ }
76
+ }
77
+
78
+ private class ExcludingSummary extends SimpleSummarizedCallable {
79
+ ExcludingSummary ( ) { this = [ "excluding" , "without" ] }
80
+
81
+ override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
82
+ input = "Argument[self].Element[any]" and
83
+ output = "ReturnValue.Element[?]" and
84
+ preservesValue = true
85
+ }
86
+ }
87
+
88
+ private class InOrderOfSummary extends SimpleSummarizedCallable {
89
+ InOrderOfSummary ( ) { this = "in_order_of" }
90
+
91
+ override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
92
+ input = "Argument[self].Element[any]" and
93
+ output = "ReturnValue.Element[?]" and
94
+ preservesValue = true
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Like `Array#push` but doesn't update the receiver.
100
+ */
101
+ private class IncludingSummary extends SimpleSummarizedCallable {
102
+ IncludingSummary ( ) { this = "including" }
103
+
104
+ override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
105
+ (
106
+ exists ( ArrayIndex i |
107
+ input = "Argument[self].Element[" + i + "]" and
108
+ output = "ReturnValue.Element[" + i + "]"
109
+ )
110
+ or
111
+ input = "Argument[self].Element[?]" and
112
+ output = "ReturnValue.Element[?]"
113
+ or
114
+ exists ( int i | i in [ 0 .. ( mc .getNumberOfArguments ( ) - 1 ) ] |
115
+ input = "Argument[" + i + "]" and
116
+ output = [ "ReturnValue.Element[?]" ]
117
+ )
118
+ ) and
119
+ preservesValue = true
120
+ }
121
+ }
122
+ // TODO: index_by, index_with, pick, pluck (they require Hash dataflow)
123
+ }
59
124
}
60
125
}
0 commit comments