@@ -83,20 +83,24 @@ struct DependencyRecorder {
83
83
84
84
public:
85
85
// / Push a new empty set onto the activeRequestReferences stack.
86
- void beginRequest (const swift::ActiveRequest &req);
86
+ template <typename Request>
87
+ void beginRequest ();
87
88
88
89
// / Pop the activeRequestReferences stack, and insert recorded references
89
90
// / into the requestReferences map, as well as the next innermost entry in
90
91
// / activeRequestReferences.
91
- void endRequest (const swift::ActiveRequest &req);
92
+ template <typename Request>
93
+ void endRequest (const Request &req);
92
94
93
95
// / When replaying a request whose value has already been cached, we need
94
96
// / to update the innermost set in the activeRequestReferences stack.
95
- void replayCachedRequest (const swift::ActiveRequest &req);
97
+ template <typename Request>
98
+ void replayCachedRequest (const Request &req);
96
99
97
100
// / Upon completion of a dependency source request, we update the
98
101
// / fileReferences map.
99
- void handleDependencySourceRequest (const swift::ActiveRequest &req,
102
+ template <typename Request>
103
+ void handleDependencySourceRequest (const Request &req,
100
104
SourceFile *source);
101
105
102
106
private:
@@ -120,6 +124,70 @@ struct DependencyRecorder {
120
124
void enumerateReferencesInFile (const SourceFile *SF,
121
125
ReferenceEnumerator f) const ;
122
126
};
127
+
128
+ template <typename Request>
129
+ void evaluator::DependencyRecorder::beginRequest () {
130
+ if (!Request::isEverCached && !Request::isDependencySource)
131
+ return ;
132
+
133
+ activeRequestReferences.push_back ({});
134
+ }
135
+
136
+ template <typename Request>
137
+ void evaluator::DependencyRecorder::endRequest (const Request &req) {
138
+ if (!Request::isEverCached && !Request::isDependencySource)
139
+ return ;
140
+
141
+ // Grab all the dependencies we've recorded so far, and pop
142
+ // the stack.
143
+ auto recorded = std::move (activeRequestReferences.back ());
144
+ activeRequestReferences.pop_back ();
145
+
146
+ // If we didn't record anything, there is nothing to do.
147
+ if (recorded.empty ())
148
+ return ;
149
+
150
+ // Convert the set of dependencies into a vector.
151
+ std::vector<DependencyCollector::Reference>
152
+ vec (recorded.begin (), recorded.end ());
153
+
154
+ // The recorded dependencies bubble up to the parent request.
155
+ if (!activeRequestReferences.empty ()) {
156
+ activeRequestReferences.back ().insert (vec.begin (),
157
+ vec.end ());
158
+ }
159
+
160
+ // Finally, record the dependencies so we can replay them
161
+ // later when the request is re-evaluated.
162
+ requestReferences.insert ({AnyRequest (req), std::move (vec)});
163
+ }
164
+
165
+ template <typename Request>
166
+ void evaluator::DependencyRecorder::replayCachedRequest (const Request &req) {
167
+ assert (req.isCached ());
168
+
169
+ if (activeRequestReferences.empty ())
170
+ return ;
171
+
172
+ auto found = requestReferences.find_as (req);
173
+ if (found == requestReferences.end ())
174
+ return ;
175
+
176
+ activeRequestReferences.back ().insert (found->second .begin (),
177
+ found->second .end ());
178
+ }
179
+
180
+ template <typename Request>
181
+ void evaluator::DependencyRecorder::handleDependencySourceRequest (
182
+ const Request &req,
183
+ SourceFile *source) {
184
+ auto found = requestReferences.find_as (req);
185
+ if (found != requestReferences.end ()) {
186
+ fileReferences[source].insert (found->second .begin (),
187
+ found->second .end ());
188
+ }
189
+ }
190
+
123
191
} // end namespace evaluator
124
192
125
193
} // end namespace swift
0 commit comments