@@ -219,6 +219,15 @@ pub fn fuzz(fuzzer: *Fuzzer) !void {
219219 fuzzer .cycle += 1 ;
220220
221221 if (fuzzer .cycle % fuzzer .config .cycles_per_gen == 0 ) {
222+ var arena_allocator = std .heap .ArenaAllocator .init (fuzzer .allocator );
223+ defer arena_allocator .deinit ();
224+ const arena = arena_allocator .allocator ();
225+
226+ while (fuzzer .connection .callback_map .count () != 0 ) {
227+ _ = arena_allocator .reset (.retain_capacity );
228+ try fuzzer .connection .acceptUntilResponse (arena );
229+ }
230+
222231 while (true ) {
223232 fuzzer .allocator .free (fuzzer .principal_file_source );
224233 fuzzer .principal_file_source = try fuzzer .mode .gen (fuzzer .allocator );
@@ -320,124 +329,171 @@ pub const WhatToFuzz = enum {
320329 rename ,
321330};
322331
332+ fn requestCallback (comptime method : []const u8 ) lsp.RequestCallback (Connection , method ) {
333+ const Context = struct {
334+ pub fn res (_ : * Connection , _ : lsp .Result (method )) ! void {}
335+
336+ pub fn err (_ : * Connection , resperr : lsp_types.ResponseError ) ! void {
337+ return switch (resperr .code ) {
338+ @intFromEnum (lsp_types .ErrorCodes .ParseError ) = > error .ParseError ,
339+ @intFromEnum (lsp_types .ErrorCodes .InvalidRequest ) = > error .InvalidRequest ,
340+ @intFromEnum (lsp_types .ErrorCodes .MethodNotFound ) = > error .MethodNotFound ,
341+ @intFromEnum (lsp_types .ErrorCodes .InvalidParams ) = > error .InvalidParams ,
342+ @intFromEnum (lsp_types .ErrorCodes .InternalError ) = > error .InternalError ,
343+ @intFromEnum (lsp_types .ErrorCodes .ServerNotInitialized ) = > error .ServerNotInitialized ,
344+ @intFromEnum (lsp_types .ErrorCodes .UnknownErrorCode ) = > error .UnknownErrorCode ,
345+ else = > error .InternalError ,
346+ };
347+ }
348+ };
349+ return .{
350+ .onResponse = & Context .res ,
351+ .onError = & Context .err ,
352+ };
353+ }
354+
323355pub fn fuzzFeatureRandom (
324356 fuzzer : * Fuzzer ,
325357 file_uri : []const u8 ,
326358 file_data : []const u8 ,
327359) ! void {
328- var arena_allocator = std .heap .ArenaAllocator .init (fuzzer .allocator );
329- defer arena_allocator .deinit ();
330- const arena = arena_allocator .allocator ();
331-
332360 const rand = fuzzer .random ();
333361 const wtf = rand .enumValue (WhatToFuzz );
334362
335363 switch (wtf ) {
336- .completion = > {
337- _ = try fuzzer .connection .requestSync (arena , "textDocument/completion" , .{
364+ .completion = > try fuzzer .connection .request (
365+ "textDocument/completion" ,
366+ .{
338367 .textDocument = .{ .uri = file_uri },
339368 .position = utils .randomPosition (rand , file_data ),
340- });
341- },
342- .declaration = > {
343- _ = try fuzzer .connection .requestSync (arena , "textDocument/declaration" , .{
369+ },
370+ requestCallback ("textDocument/completion" ),
371+ ),
372+ .declaration = > try fuzzer .connection .request (
373+ "textDocument/declaration" ,
374+ .{
344375 .textDocument = .{ .uri = file_uri },
345376 .position = utils .randomPosition (rand , file_data ),
346- });
347- },
348- .definition = > {
349- _ = try fuzzer .connection .requestSync (arena , "textDocument/definition" , .{
377+ },
378+ requestCallback ("textDocument/declaration" ),
379+ ),
380+ .definition = > try fuzzer .connection .request (
381+ "textDocument/definition" ,
382+ .{
350383 .textDocument = .{ .uri = file_uri },
351384 .position = utils .randomPosition (rand , file_data ),
352- });
353- },
354- .type_definition = > {
355- _ = try fuzzer .connection .requestSync (arena , "textDocument/typeDefinition" , .{
385+ },
386+ requestCallback ("textDocument/definition" ),
387+ ),
388+ .type_definition = > try fuzzer .connection .request (
389+ "textDocument/typeDefinition" ,
390+ .{
356391 .textDocument = .{ .uri = file_uri },
357392 .position = utils .randomPosition (rand , file_data ),
358- });
359- },
360- .implementation = > {
361- _ = try fuzzer .connection .requestSync (arena , "textDocument/implementation" , .{
393+ },
394+ requestCallback ("textDocument/typeDefinition" ),
395+ ),
396+ .implementation = > try fuzzer .connection .request (
397+ "textDocument/implementation" ,
398+ .{
362399 .textDocument = .{ .uri = file_uri },
363400 .position = utils .randomPosition (rand , file_data ),
364- });
365- } ,
366- .references = > {
367- _ = try fuzzer .connection .requestSync ( arena , "textDocument/references" , .{
368- . context = .{
369- . includeDeclaration = rand . boolean (),
370- },
401+ },
402+ requestCallback ( "textDocument/implementation" ) ,
403+ ),
404+ .references = > try fuzzer .connection .request (
405+ "textDocument/references" ,
406+ .{
407+ . context = .{ . includeDeclaration = rand . boolean () },
371408 .textDocument = .{ .uri = file_uri },
372409 .position = utils .randomPosition (rand , file_data ),
373- });
374- },
375- .signature_help = > {
376- _ = try fuzzer .connection .requestSync (arena , "textDocument/signatureHelp" , .{
410+ },
411+ requestCallback ("textDocument/references" ),
412+ ),
413+ .signature_help = > try fuzzer .connection .request (
414+ "textDocument/signatureHelp" ,
415+ .{
377416 .textDocument = .{ .uri = file_uri },
378417 .position = utils .randomPosition (rand , file_data ),
379- });
380- },
381- .hover = > {
382- _ = try fuzzer .connection .requestSync (arena , "textDocument/hover" , .{
418+ },
419+ requestCallback ("textDocument/signatureHelp" ),
420+ ),
421+ .hover = > try fuzzer .connection .request (
422+ "textDocument/hover" ,
423+ .{
383424 .textDocument = .{ .uri = file_uri },
384425 .position = utils .randomPosition (rand , file_data ),
385- });
386- },
387- .semantic = > {
388- _ = try fuzzer .connection .requestSync (arena , "textDocument/semanticTokens/full" , .{
389- .textDocument = .{ .uri = file_uri },
390- });
391- },
392- .document_symbol = > {
393- _ = try fuzzer .connection .requestSync (arena , "textDocument/documentSymbol" , .{
394- .textDocument = .{ .uri = file_uri },
395- });
396- },
426+ },
427+ requestCallback ("textDocument/hover" ),
428+ ),
429+ .semantic = > try fuzzer .connection .request (
430+ "textDocument/semanticTokens/full" ,
431+ .{ .textDocument = .{ .uri = file_uri } },
432+ requestCallback ("textDocument/semanticTokens/full" ),
433+ ),
434+ .document_symbol = > try fuzzer .connection .request (
435+ "textDocument/documentSymbol" ,
436+ .{ .textDocument = .{ .uri = file_uri } },
437+ requestCallback ("textDocument/documentSymbol" ),
438+ ),
397439 .folding_range = > {
398- _ = try fuzzer .connection .requestSync (arena , "textDocument/foldingRange" , .{
399- .textDocument = .{ .uri = file_uri },
400- });
440+ _ = try fuzzer .connection .request (
441+ "textDocument/foldingRange" ,
442+ .{ .textDocument = .{ .uri = file_uri } },
443+ requestCallback ("textDocument/foldingRange" ),
444+ );
401445 },
402- .formatting = > {
403- _ = try fuzzer .connection .requestSync (arena , "textDocument/formatting" , .{
446+ .formatting = > try fuzzer .connection .request (
447+ "textDocument/formatting" ,
448+ .{
404449 .textDocument = .{ .uri = file_uri },
405450 .options = .{
406451 .tabSize = 4 ,
407452 .insertSpaces = true ,
408453 },
409- });
410- },
411- .document_highlight = > {
412- _ = try fuzzer .connection .requestSync (arena , "textDocument/documentHighlight" , .{
454+ },
455+ requestCallback ("textDocument/formatting" ),
456+ ),
457+ .document_highlight = > try fuzzer .connection .request (
458+ "textDocument/documentHighlight" ,
459+ .{
413460 .textDocument = .{ .uri = file_uri },
414461 .position = utils .randomPosition (rand , file_data ),
415- });
416- },
417- .inlay_hint = > {
418- _ = try fuzzer .connection .requestSync (arena , "textDocument/inlayHint" , .{
462+ },
463+ requestCallback ("textDocument/documentHighlight" ),
464+ ),
465+ .inlay_hint = > try fuzzer .connection .request (
466+ "textDocument/inlayHint" ,
467+ .{
419468 .textDocument = .{ .uri = file_uri },
420469 .range = utils .randomRange (rand , file_data ),
421- });
422- },
470+ },
471+ requestCallback ("textDocument/inlayHint" ),
472+ ),
423473 // TODO: Nest positions properly to avoid crash
424474 // .selection_range => {
425475 // var positions: [16]lsp_types.Position = undefined;
426476 // for (positions) |*pos| {
427477 // pos.* = utils.randomPosition(rand, file_data);
428478 // }
429- // _ = try fuzzer.connection.requestSync(arena, "textDocument/selectionRange", .{
430- // .textDocument = .{ .uri = file_uri, },
431- // .positions = &positions,
432- // });
479+ // try fuzzer.connection.request(
480+ // "textDocument/selectionRange",
481+ // .{
482+ // .textDocument = .{ .uri = file_uri },
483+ // .positions = &positions,
484+ // },
485+ // requestCallback("textDocument/selectionRange"),
486+ // );
433487 // },
434- .rename = > {
435- _ = try fuzzer .connection .requestSync (arena , "textDocument/rename" , .{
488+ .rename = > try fuzzer .connection .request (
489+ "textDocument/rename" ,
490+ .{
436491 .textDocument = .{ .uri = file_uri },
437492 .position = utils .randomPosition (rand , file_data ),
438493 .newName = "helloWorld" ,
439- });
440- },
494+ },
495+ requestCallback ("textDocument/rename" ),
496+ ),
441497 }
442498}
443499
0 commit comments