@@ -101,11 +101,13 @@ static SourceKitRequest ActiveRequest = SourceKitRequest::None;
101
101
static sourcekitd_uid_t SemaDiagnosticStage;
102
102
103
103
static sourcekitd_uid_t NoteDocUpdate;
104
-
105
104
static SourceKit::Semaphore semaSemaphore (0 );
106
105
static sourcekitd_response_t semaResponse;
107
106
static const char *semaName;
108
107
108
+ static sourcekitd_uid_t NoteTest;
109
+ static SourceKit::Semaphore noteSyncSemaphore (0 );
110
+
109
111
namespace {
110
112
struct AsyncResponseInfo {
111
113
SourceKit::Semaphore semaphore{0 };
@@ -139,7 +141,28 @@ struct NotificationBuffer {
139
141
};
140
142
static NotificationBuffer notificationBuffer;
141
143
142
- static void printBufferedNotifications () {
144
+ static void syncNotificationsWithService () {
145
+ // Send TestNotification request, then wait for the notification. This ensures
146
+ // that all notifications previously posted on the service side have been
147
+ // passed to our notification handler.
148
+ sourcekitd_object_t req = sourcekitd_request_dictionary_create (nullptr , nullptr , 0 );
149
+ sourcekitd_request_dictionary_set_uid (req, KeyRequest, RequestTestNotification);
150
+ auto resp = sourcekitd_send_request_sync (req);
151
+ if (sourcekitd_response_is_error (resp)) {
152
+ sourcekitd_response_description_dump (resp);
153
+ exit (1 );
154
+ }
155
+ sourcekitd_response_dispose (resp);
156
+ sourcekitd_request_release (req);
157
+ if (noteSyncSemaphore.wait (60 * 1000 )) {
158
+ llvm::report_fatal_error (" Test notification not received" );
159
+ }
160
+ }
161
+
162
+ static void printBufferedNotifications (bool syncWithService = true ) {
163
+ if (syncWithService) {
164
+ syncNotificationsWithService ();
165
+ }
143
166
notificationBuffer.handleNotifications ([](sourcekitd_response_t note) {
144
167
sourcekitd_response_description_dump_filedesc (note, STDOUT_FILENO);
145
168
});
@@ -171,6 +194,7 @@ static int skt_main(int argc, const char **argv) {
171
194
SemaDiagnosticStage = sourcekitd_uid_get_from_cstr (" source.diagnostic.stage.swift.sema" );
172
195
173
196
NoteDocUpdate = sourcekitd_uid_get_from_cstr (" source.notification.editor.documentupdate" );
197
+ NoteTest = sourcekitd_uid_get_from_cstr (" source.notification.test" );
174
198
175
199
#define REQUEST (NAME, CONTENT ) Request##NAME = sourcekitd_uid_get_from_cstr(CONTENT);
176
200
#define KIND (NAME, CONTENT ) Kind##NAME = sourcekitd_uid_get_from_cstr(CONTENT);
@@ -342,11 +366,12 @@ static int handleTestInvocation(ArrayRef<const char *> Args,
342
366
343
367
assert (Opts.repeatRequest >= 1 );
344
368
for (unsigned i = 0 ; i < Opts.repeatRequest ; ++i) {
345
- int ret = handleTestInvocation (Opts, InitOpts);
346
- printBufferedNotifications ();
347
- if (ret) {
369
+ if (int ret = handleTestInvocation (Opts, InitOpts)) {
370
+ printBufferedNotifications (/* syncWithService=*/ true );
348
371
return ret;
349
372
}
373
+ // We will sync with the service before exiting; don't do so here.
374
+ printBufferedNotifications (/* syncWithService=*/ false );
350
375
}
351
376
return 0 ;
352
377
}
@@ -1169,6 +1194,8 @@ static void notification_receiver(sourcekitd_response_t resp) {
1169
1194
semaResponse = sourcekitd_send_request_sync (edReq);
1170
1195
sourcekitd_request_release (edReq);
1171
1196
semaSemaphore.signal ();
1197
+ } else if (note == NoteTest) {
1198
+ noteSyncSemaphore.signal ();
1172
1199
} else {
1173
1200
notificationBuffer.add (resp);
1174
1201
}
0 commit comments