Skip to content

Commit cec40a1

Browse files
Move task file generation to worker thread to fix bug
1 parent a41a729 commit cec40a1

5 files changed

Lines changed: 165 additions & 60 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ IDL 9.1 introduces new, command-line based progress bars. We have a first-pass o
2222

2323
Fixed an issue with the IDL Webview that showed a blank tab when opened. This affect things like the profiler in the extension.
2424

25-
If there are unexpected errors in the webview, we now try to catch them and alert the user. Errors should be printed to the logs and a button will appear to make it easy to report an issue.
25+
If there are unexpected errors in the webview, we now try to catch them and alert the user. Errors should be printed to the logs and a button will appear to make it easy to report an issue if this happens in the future.
2626

2727
Added basic support for symbolic links and managing files that have symbolic links. This includes tests for baseline user experience as well.
2828

2929
When we encounter a file with a symbolic link, we report problems for the true file on disk (not the path including the link). This means you won't see problems actively reported for the file if you edit it as a link.
3030

31+
Resolved an issue where task file generation wouldn't update your original code with a main level program if you didn't have one.
32+
3133
## 4.7.0 - November 2024
3234

3335
Added the ability to statically determine the return types for functions and function methods that don't have documentation. This means that, for the following example, we properly detect that we return an IDL Long (because of `compile_opt idl2`):

apps/parsing-worker/src/main.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
import { AssembleWithIndex } from '@idl/assembler';
22
import { Migrator } from '@idl/assembling/migrators';
3+
import {
4+
GenerateENVITask,
5+
GenerateENVITaskMainLevelProgram,
6+
} from '@idl/generators/envi-task';
7+
import {
8+
GenerateIDLTask,
9+
GenerateIDLTaskMainLevelProgram,
10+
} from '@idl/generators/idl-task';
11+
import { GenerateTaskResult } from '@idl/generators/tasks-shared';
312
import { IDL_WORKER_THREAD_CONSOLE, LogManager } from '@idl/logger';
413
import { PrepareNotebookCell } from '@idl/notebooks/idl-index';
514
import { ParseFileSync } from '@idl/parser';
@@ -17,6 +26,7 @@ import {
1726
IParsedLightWeight,
1827
RemoveScopeDetail,
1928
} from '@idl/parsing/syntax-tree';
29+
import { TOKEN_NAMES } from '@idl/tokenizer';
2030
import { IDL_TRANSLATION } from '@idl/translation';
2131
import {
2232
ChangeDetectionResponse,
@@ -215,6 +225,75 @@ client.on(LSP_WORKER_THREAD_MESSAGE_LOOKUP.CLEAN_UP, async (message) => {
215225
await WORKER_INDEX.cleanUp();
216226
});
217227

228+
/**
229+
* Handle requests to make a task file
230+
*/
231+
client.on(
232+
LSP_WORKER_THREAD_MESSAGE_LOOKUP.GENERATE_TASK,
233+
async (message, cancel) => {
234+
// index the file
235+
const parsed = await GetParsedPROCode(
236+
WORKER_INDEX,
237+
message.fsPath,
238+
message.code,
239+
cancel,
240+
{
241+
postProcess: true,
242+
}
243+
);
244+
245+
/**
246+
* Do we write to disk or not?
247+
*/
248+
const WRITE_TASK = true;
249+
250+
/**
251+
* Make our task
252+
*/
253+
const result =
254+
message.type === 'envi'
255+
? await GenerateENVITask(
256+
message.fsPath,
257+
parsed,
258+
message.config,
259+
WRITE_TASK
260+
)
261+
: await GenerateIDLTask(
262+
message.fsPath,
263+
parsed,
264+
message.config,
265+
WRITE_TASK
266+
);
267+
268+
/** Return value for PRO code */
269+
let proCode: string;
270+
271+
// if we made a task, then make PRO code
272+
if (result.success) {
273+
// check of we have a main level program
274+
if (parsed.tree[parsed.tree.length - 1].name !== TOKEN_NAMES.MAIN_LEVEL) {
275+
const mainAdd =
276+
message.type === 'envi'
277+
? GenerateENVITaskMainLevelProgram(
278+
result as GenerateTaskResult<true>
279+
)
280+
: GenerateIDLTaskMainLevelProgram(
281+
result as GenerateTaskResult<true>
282+
);
283+
284+
// make new text
285+
proCode = message.code + '\n' + mainAdd;
286+
}
287+
}
288+
289+
// return
290+
return {
291+
result,
292+
proCode,
293+
};
294+
}
295+
);
296+
218297
/**
219298
* Get auto complete for files we manage
220299
*/

libs/vscode/server/src/lib/events/custom-events/on-generate-task.ts

Lines changed: 36 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
1-
import { CancellationToken } from '@idl/cancellation-tokens';
2-
import {
3-
GenerateENVITask,
4-
GenerateENVITaskMainLevelProgram,
5-
} from '@idl/generators/envi-task';
6-
import {
7-
GenerateIDLTask,
8-
GenerateIDLTaskMainLevelProgram,
9-
} from '@idl/generators/idl-task';
101
import { GenerateTaskResult } from '@idl/generators/tasks-shared';
112
import { IDL_LSP_LOG } from '@idl/logger';
12-
import { GetParsedPROCode } from '@idl/parsing/index';
13-
import { GetFSPath, IDLFileHelper, Sleep } from '@idl/shared';
14-
import { TOKEN_NAMES } from '@idl/tokenizer';
3+
import { IDLFileHelper, Sleep } from '@idl/shared';
154
import { IDL_TRANSLATION } from '@idl/translation';
165
import {
176
GenerateTaskMessage,
187
LanguageServerPayload,
198
} from '@idl/vscode/events/messages';
9+
import { LSP_WORKER_THREAD_MESSAGE_LOOKUP } from '@idl/workers/parsing';
2010

21-
import { GetFileStrings } from '../../helpers/get-file-strings';
2211
import { GetFormattingConfigForFile } from '../../helpers/get-formatting-config-for-file';
12+
import { ResolveFSPathAndCodeForURI } from '../../helpers/resolve-fspath-and-code-for-uri';
2313
import { UpdateDocument } from '../../helpers/update-document';
2414
import { IDL_LANGUAGE_SERVER_LOGGER } from '../../initialize-server';
2515
import { IDL_INDEX } from '../initialize-document-manager';
@@ -41,56 +31,53 @@ export const ON_GENERATE_TASK = async (
4131
await SERVER_INITIALIZED;
4232
try {
4333
/**
44-
* File we want to make a task for
34+
* Resolve the fspath to our cell and retrieve code
4535
*/
46-
const fsPath = GetFSPath(payload.uri);
36+
const info = await ResolveFSPathAndCodeForURI(payload.uri);
4737

48-
// return if not PRO code
49-
if (!IDLFileHelper.isPROCode(fsPath)) {
50-
return;
38+
// return if nothing found
39+
if (info === undefined) {
40+
return undefined;
41+
}
42+
43+
// do nothing
44+
if (!IDLFileHelper.isPROCode(info.fsPath)) {
45+
return undefined;
5146
}
5247

48+
/** Formatting config for info.fsPath */
49+
const config = GetFormattingConfigForFile(info.fsPath);
50+
5351
IDL_LANGUAGE_SERVER_LOGGER.log({
5452
log: IDL_LSP_LOG,
5553
type: 'info',
56-
content: `Init/update task for file: "${fsPath}"`,
54+
content: `Init/update task for file: "${info.fsPath}"`,
5755
});
5856

59-
/** Formatting config for file */
60-
const config = GetFormattingConfigForFile(fsPath);
61-
62-
/** Content of our PRO file */
63-
const proCode = await GetFileStrings(payload.uri, fsPath);
64-
65-
// re-index the file
66-
const parsed = await GetParsedPROCode(
67-
IDL_INDEX,
68-
fsPath,
69-
proCode,
70-
new CancellationToken(),
71-
{
72-
postProcess: true,
73-
}
74-
);
75-
7657
/**
77-
* Make our task
58+
* Formatted code
7859
*/
79-
const result =
80-
payload.type === 'envi'
81-
? await GenerateENVITask(fsPath, parsed, config, WRITE_TASK)
82-
: await GenerateIDLTask(fsPath, parsed, config, WRITE_TASK);
60+
const response = await IDL_INDEX.indexerPool.workerio.postAndReceiveMessage(
61+
IDL_INDEX.getWorkerID(info.fsPath),
62+
LSP_WORKER_THREAD_MESSAGE_LOOKUP.GENERATE_TASK,
63+
{
64+
...payload,
65+
fsPath: info.fsPath,
66+
code: info.code,
67+
config,
68+
}
69+
).response;
8370

8471
// check for error
85-
if (!result.success) {
72+
if (!response.result.success) {
8673
IDL_LANGUAGE_SERVER_LOGGER.log({
8774
log: IDL_LSP_LOG,
8875
type: 'error',
8976
content: [
9077
'Error while initializing/updating task file',
91-
(result as GenerateTaskResult<false>).failureReason,
78+
(response.result as GenerateTaskResult<false>).failureReason,
9279
],
93-
alert: (result as GenerateTaskResult<false>).failureReason,
80+
alert: (response.result as GenerateTaskResult<false>).failureReason,
9481
});
9582
return;
9683
}
@@ -115,28 +102,19 @@ export const ON_GENERATE_TASK = async (
115102
IDL_LANGUAGE_SERVER_LOGGER.log({
116103
log: IDL_LSP_LOG,
117104
type: 'info',
118-
content: `Initialized/updated task for file: "${fsPath}"`,
105+
content: `Initialized/updated task for file: "${info.fsPath}"`,
119106
alert: IDL_TRANSLATION.commands.notifications.initTask.created,
120107
alertMeta: {
121-
openFile: (result as GenerateTaskResult<true>).taskFile,
108+
openFile: (response.result as GenerateTaskResult<true>).taskFile,
122109
},
123110
});
124111

125112
// slight pause, to allow server to parse task file
126113
await Sleep(200);
127114

128-
// check of we have a main level program
129-
if (parsed.tree[parsed.tree.length - 1].name !== TOKEN_NAMES.MAIN_LEVEL) {
130-
const mainAdd =
131-
payload.type === 'envi'
132-
? GenerateENVITaskMainLevelProgram(result as GenerateTaskResult<true>)
133-
: GenerateIDLTaskMainLevelProgram(result as GenerateTaskResult<true>);
134-
135-
// make new text
136-
const newContent = proCode + '\n' + mainAdd;
137-
138-
// send content
139-
await UpdateDocument(payload.uri, newContent);
115+
// update main level program if needed
116+
if (response.proCode) {
117+
await UpdateDocument(payload.uri, response.proCode);
140118
}
141119
} catch (err) {
142120
IDL_LANGUAGE_SERVER_LOGGER.log({

libs/workers/parsing/src/lib/lsp-worker-thread.messages.interface.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { FormatterType, IAssemblerOptions } from '@idl/assembling/config';
22
import { MigrationType } from '@idl/assembling/migrators-types';
3+
import { GenerateTaskResult } from '@idl/generators/tasks-shared';
34
import { ILogOptions } from '@idl/logger';
45
import { IDLNotebookDocument } from '@idl/notebooks/shared';
56
import { IParsedLightWeight, ParsedType } from '@idl/parsing/syntax-tree';
@@ -11,7 +12,10 @@ import {
1112
} from '@idl/types/core';
1213
import { IDisabledProblems, SyntaxProblems } from '@idl/types/problem-codes';
1314
import { PositionArray } from '@idl/types/tokenizer';
14-
import { PrepareNotebookCellMessage } from '@idl/vscode/events/messages';
15+
import {
16+
IGenerateTaskPayload,
17+
PrepareNotebookCellMessage,
18+
} from '@idl/vscode/events/messages';
1519
import { IDLExtensionConfig } from '@idl/vscode/extension-config';
1620
import { WorkerIOBaseMessage } from '@idl/workers/workerio';
1721
import {
@@ -123,6 +127,35 @@ export type CleanUpPayload = {
123127
*/
124128
export type CleanUpResponse = void;
125129

130+
/**
131+
* Message to generate a task file
132+
*/
133+
export type GenerateTaskMessage = 'generate-task';
134+
135+
/**
136+
* Payload on cleanup
137+
*/
138+
export type GenerateTaskPayload = {
139+
/** FS path on disk */
140+
fsPath: string;
141+
/** Code for the file */
142+
code: string;
143+
/** Formatting config */
144+
config: IAssemblerOptions<FormatterType>;
145+
} & IGenerateTaskPayload;
146+
147+
/**
148+
* Response from cleanup
149+
*/
150+
export type GenerateTaskResponse = {
151+
/** Type for return from generating a task */
152+
result: GenerateTaskResult<boolean>;
153+
/**
154+
* New PRO code to save, if we have main level program
155+
*/
156+
proCode?: string;
157+
};
158+
126159
/**
127160
* Message when we want to get auto complete for a file
128161
*/
@@ -506,6 +539,7 @@ export type LSPWorkerThreadMessage =
506539
| AutoCompleteRecipeMessage
507540
| ChangeDetectionMessage
508541
| CleanUpMessage
542+
| GenerateTaskMessage
509543
| GetAutoCompleteMessage
510544
| GetHoverHelpLookupMessage
511545
| GetNotebookCellMessage
@@ -549,6 +583,10 @@ interface ILSPWorkerThreadMessageLookup {
549583
* Message to clean up
550584
*/
551585
CLEAN_UP: CleanUpMessage;
586+
/**
587+
* Generate a task file
588+
*/
589+
GENERATE_TASK: GenerateTaskMessage;
552590
/**
553591
* Message when we want to get auto complete for a file
554592
*/
@@ -632,6 +670,7 @@ export const LSP_WORKER_THREAD_MESSAGE_LOOKUP: ILSPWorkerThreadMessageLookup = {
632670
AUTO_COMPLETE_RECIPE: 'auto-complete-recipe',
633671
CHANGE_DETECTION: 'change-detection',
634672
CLEAN_UP: 'clean-up',
673+
GENERATE_TASK: 'generate-task',
635674
GET_AUTO_COMPLETE: 'get-auto-complete',
636675
GET_HOVER_HELP_LOOKUP: 'get-hover-help-lookup',
637676
GET_NOTEBOOK_CELL: 'get-notebook-cell',

libs/workers/parsing/src/lib/lsp-worker-thread.payloads.interface.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ import {
2626
CleanUpMessage,
2727
CleanUpPayload,
2828
CleanUpResponse,
29+
GenerateTaskMessage,
30+
GenerateTaskPayload,
31+
GenerateTaskResponse,
2932
GetAutoCompleteMessage,
3033
GetAutoCompletePayload,
3134
GetAutoCompleteResponse,
@@ -91,6 +94,8 @@ export type PayloadToLSPWorker<T extends LSPWorkerThreadMessage> =
9194
? ChangeDetectionPayload
9295
: T extends CleanUpMessage
9396
? CleanUpPayload
97+
: T extends GenerateTaskMessage
98+
? GenerateTaskPayload
9499
: T extends GetAutoCompleteMessage
95100
? GetAutoCompletePayload
96101
: T extends GetHoverHelpLookupMessage
@@ -145,6 +150,8 @@ export type PayloadFromLSPWorker<T extends LSPWorkerThreadMessage> =
145150
? ChangeDetectionResponse
146151
: T extends CleanUpMessage
147152
? CleanUpResponse
153+
: T extends GenerateTaskMessage
154+
? GenerateTaskResponse
148155
: T extends GetAutoCompleteMessage
149156
? GetAutoCompleteResponse
150157
: T extends GetHoverHelpLookupMessage

0 commit comments

Comments
 (0)