Skip to content

Commit 8237a65

Browse files
feat: W-18903474 - add diagnostics LSP handling (#102)
* feat: lsp diagnostic * chore: pr comments. treat everything as error, simplify, copy/paste error * chore: enablePullDiagnostics flag * chore: pr suggestions * chore: type * chore: merge conflict --------- Co-authored-by: peternhale <[email protected]>
1 parent 91566bb commit 8237a65

File tree

15 files changed

+1594
-16
lines changed

15 files changed

+1594
-16
lines changed

packages/apex-ls-browser/src/index.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
dispatchProcessOnSaveDocument,
3434
dispatchProcessOnDocumentSymbol,
3535
dispatchProcessOnFoldingRange,
36+
dispatchProcessOnDiagnostic,
3637
ApexStorage,
3738
} from '@salesforce/apex-lsp-compliant-services';
3839
import {
@@ -89,6 +90,10 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
8990
hoverProvider: false,
9091
documentSymbolProvider: true,
9192
foldingRangeProvider: true, // Enable folding range support
93+
diagnosticProvider: {
94+
interFileDependencies: false,
95+
workspaceDiagnostics: false,
96+
},
9297
},
9398
};
9499
});
@@ -127,6 +132,31 @@ connection.onDocumentSymbol(async (params: DocumentSymbolParams) => {
127132
}
128133
});
129134

135+
// Handle diagnostic requests
136+
connection.onRequest(
137+
'textDocument/diagnostic',
138+
async (params: DocumentSymbolParams) => {
139+
logger.info(
140+
`[SERVER] Received diagnostic request for: ${params.textDocument.uri}`,
141+
);
142+
logger.info(`[SERVER] DiagnosticParams: ${JSON.stringify(params)}`);
143+
144+
try {
145+
const result = await dispatchProcessOnDiagnostic(params);
146+
logger.info(
147+
`[SERVER] Result for diagnostic (${params.textDocument.uri}): ${JSON.stringify(result)}`,
148+
);
149+
return result;
150+
} catch (error) {
151+
logger.error(
152+
`[SERVER] Error processing diagnostic for ${params.textDocument.uri}: ${error}`,
153+
);
154+
// Return empty array in case of error, as per LSP spec for graceful failure
155+
return [];
156+
}
157+
},
158+
);
159+
130160
// Add a handler for folding ranges
131161
connection.onFoldingRanges(
132162
async (params: FoldingRangeParams): Promise<FoldingRange[] | null> => {

packages/apex-ls-browser/test/index.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type OnDocumentSymbolHandler = (
3535
type OnFoldingRangeHandler = (
3636
params: FoldingRangeParams,
3737
) => Promise<FoldingRange[] | null>;
38+
type OnRequestHandler = (params: DocumentSymbolParams) => Promise<any[]>;
3839

3940
// Define mock handlers type
4041
interface MockHandlerStore {
@@ -48,6 +49,7 @@ interface MockHandlerStore {
4849
onDidSave: OnDidSaveHandler | null;
4950
onDocumentSymbol: OnDocumentSymbolHandler | null;
5051
onFoldingRange: OnFoldingRangeHandler | null;
52+
onRequest: OnRequestHandler | null;
5153
}
5254

5355
// Store mock handlers
@@ -62,6 +64,7 @@ const mockHandlers: MockHandlerStore = {
6264
onDidSave: null,
6365
onDocumentSymbol: null,
6466
onFoldingRange: null,
67+
onRequest: null,
6568
};
6669

6770
// Set up the mock connection with proper type safety
@@ -80,6 +83,7 @@ interface MockConnection {
8083
onHover: jest.Mock;
8184
onDocumentSymbol: jest.Mock;
8285
onFoldingRanges: jest.Mock;
86+
onRequest: jest.Mock;
8387
listen: jest.Mock;
8488
console: typeof mockConsole;
8589
sendNotification: jest.Mock;
@@ -97,6 +101,7 @@ const mockConnection: MockConnection = {
97101
onHover: jest.fn(),
98102
onDocumentSymbol: jest.fn(),
99103
onFoldingRanges: jest.fn(),
104+
onRequest: jest.fn(),
100105
listen: jest.fn(),
101106
console: mockConsole,
102107
sendNotification: jest.fn(),
@@ -152,6 +157,15 @@ mockConnection.onFoldingRanges.mockImplementation(
152157
},
153158
);
154159

160+
mockConnection.onRequest.mockImplementation(
161+
(method: string, handler: OnRequestHandler) => {
162+
if (method === 'textDocument/diagnostic') {
163+
mockHandlers.onRequest = handler;
164+
}
165+
return mockConnection;
166+
},
167+
);
168+
155169
mockDocuments.onDidOpen.mockImplementation((handler: OnDidOpenHandler) => {
156170
mockHandlers.onDidOpen = handler;
157171
return mockDocuments;
@@ -220,6 +234,7 @@ const mockDispatchProcessOnCloseDocument = jest.fn().mockResolvedValue([]);
220234
const mockDispatchProcessOnSaveDocument = jest.fn().mockResolvedValue([]);
221235
const mockDispatchProcessOnDocumentSymbol = jest.fn().mockResolvedValue([]);
222236
const mockDispatchProcessOnFoldingRange = jest.fn().mockResolvedValue([]);
237+
const mockDispatchProcessOnDiagnostic = jest.fn().mockResolvedValue([]);
223238

224239
jest.mock('@salesforce/apex-lsp-compliant-services', () => ({
225240
...jest.requireActual('@salesforce/apex-lsp-compliant-services'),
@@ -229,6 +244,7 @@ jest.mock('@salesforce/apex-lsp-compliant-services', () => ({
229244
dispatchProcessOnSaveDocument: mockDispatchProcessOnSaveDocument,
230245
dispatchProcessOnDocumentSymbol: mockDispatchProcessOnDocumentSymbol,
231246
dispatchProcessOnFoldingRange: mockDispatchProcessOnFoldingRange,
247+
dispatchProcessOnDiagnostic: mockDispatchProcessOnDiagnostic,
232248
ApexStorageManager: {
233249
getInstance: jest.fn().mockReturnValue({
234250
getStorage: jest.fn(),

packages/apex-ls-node/src/index.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
dispatchProcessOnSaveDocument,
3131
dispatchProcessOnDocumentSymbol,
3232
dispatchProcessOnFoldingRange,
33+
dispatchProcessOnDiagnostic,
3334
ApexStorageManager,
3435
ApexSettingsManager,
3536
LSPConfigurationManager,
@@ -141,6 +142,10 @@ export function startServer() {
141142
hoverProvider: false,
142143
documentSymbolProvider: true,
143144
foldingRangeProvider: true, // Enable folding range support
145+
diagnosticProvider: {
146+
interFileDependencies: false,
147+
workspaceDiagnostics: false,
148+
},
144149
workspace: {
145150
workspaceFolders: {
146151
supported: true,
@@ -206,6 +211,31 @@ export function startServer() {
206211
}
207212
});
208213

214+
// Handle diagnostic requests
215+
connection.onRequest(
216+
'textDocument/diagnostic',
217+
async (params: DocumentSymbolParams) => {
218+
logger.debug(
219+
`[SERVER] Received diagnostic request for: ${params.textDocument.uri}`,
220+
);
221+
logger.debug(`[SERVER] DiagnosticParams: ${JSON.stringify(params)}`);
222+
223+
try {
224+
const result = await dispatchProcessOnDiagnostic(params);
225+
logger.debug(
226+
`[SERVER] Result for diagnostic (${params.textDocument.uri}): ${JSON.stringify(result)}`,
227+
);
228+
return result;
229+
} catch (error) {
230+
logger.error(
231+
`[SERVER] Error processing diagnostic for ${params.textDocument.uri}: ${error}`,
232+
);
233+
// Return empty array in case of error, as per LSP spec for graceful failure
234+
return [];
235+
}
236+
},
237+
);
238+
209239
// Configuration change handling is now managed by the LSPConfigurationManager
210240
// through its enhanced registration system in registerForConfigurationChanges()
211241

packages/apex-ls-node/test/index.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ describe('Apex Language Server', () => {
345345
triggerCharacters: ['.'],
346346
},
347347
hoverProvider: false,
348+
diagnosticProvider: {
349+
interFileDependencies: false,
350+
workspaceDiagnostics: false,
351+
},
348352
documentSymbolProvider: true,
349353
foldingRangeProvider: true,
350354
workspace: {

0 commit comments

Comments
 (0)