Skip to content

Commit 7732142

Browse files
committed
fix: add typedef.list preprocessing with its caching
1 parent 0a8ed37 commit 7732142

File tree

2 files changed

+96
-12
lines changed

2 files changed

+96
-12
lines changed

src/formatter.ts

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,22 @@ class LineDiffGroup {
2121
/* Small trick to make all lines end with new line */
2222
diff.lines.push('');
2323
edits.push(vscode.TextEdit.insert(document.lineAt(diff.num).range.start,
24-
diff.lines.join('\n')));
24+
diff.lines.join('\n')));
25+
try {
26+
continue;
27+
} catch (err: any) {
28+
if (!(document.lineCount < diff.num && diff.lines[0].startsWith('/**INDENT')))
29+
throw err;
30+
}
31+
32+
/*
33+
* pg_bsd_indent complains if there is no new line
34+
* at the end of file, so we add it ourselves
35+
*/
36+
const lastLine = document.lineAt(document.lineCount - 1);
37+
const lastPos = document.lineAt(document.lineCount - 1).range.start;
38+
edits.push(vscode.TextEdit.insert(lastPos, `${lastLine.text}\n`));
2539
} else {
26-
2740
/*
2841
* document.lineAt().range returns range of line
2942
* NOT including new line, so just passing it
@@ -269,6 +282,7 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
269282
];
270283

271284
private savedPgbsdPath?: vscode.Uri;
285+
private savedProcessedTypedef?: vscode.Uri;
272286
constructor(private logger: utils.ILogger) {}
273287

274288
private async findExistingPgbsdindent(workspace: vscode.WorkspaceFolder) {
@@ -365,6 +379,45 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
365379
}
366380
}
367381

382+
private async getProcessedTypedefs(pg_bsd_indent: vscode.Uri) {
383+
const processedTypedef = utils.joinPath(vscode.Uri.file(os.tmpdir()),
384+
'pg-hacker-helper.typedefs.list');
385+
386+
if (this.savedProcessedTypedef) {
387+
if (await utils.fileExists(this.savedProcessedTypedef))
388+
return this.savedProcessedTypedef;
389+
390+
this.savedProcessedTypedef = undefined;
391+
} else if (await utils.fileExists(processedTypedef)) {
392+
/* After restart be */
393+
this.savedProcessedTypedef = processedTypedef;
394+
return processedTypedef;
395+
}
396+
397+
/*
398+
* Add and remove some entries from `typedefs.list` file
399+
* downloaded from buildfarm
400+
*/
401+
const rawTypedef = await this.getTypedefs(pg_bsd_indent);
402+
const contents = await utils.readFile(rawTypedef);
403+
const entries = new Set(contents.split('\n'));
404+
405+
[
406+
'ANY', 'FD_SET', 'U', 'abs', 'allocfunc', 'boolean', 'date',
407+
'digit', 'ilist', 'interval', 'iterator', 'other', 'pointer',
408+
'printfunc', 'reference', 'string', 'timestamp', 'type', 'wrap'
409+
].forEach(e => entries.delete(e));
410+
411+
entries.add('bool');
412+
entries.delete('');
413+
const arr = Array.from(entries.values());
414+
arr.sort();
415+
416+
await utils.writeFile(processedTypedef, arr.join('\n'));
417+
this.savedProcessedTypedef = processedTypedef;
418+
return processedTypedef;
419+
}
420+
368421
private async getPgbsdindent(workspace: vscode.WorkspaceFolder) {
369422
if (this.savedPgbsdPath) {
370423
return this.savedPgbsdPath;
@@ -394,9 +447,9 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
394447
// Prevent indenting of code in 'extern "C"' blocks
395448
// we replace the braces with comments which we'll reverse later
396449
replace(/(^#ifdef[ \t]+__cplusplus.*\nextern[ \t]+"C"[ \t]*\n)\{[ \t]*$/gm,
397-
'$1/\* Open extern "C" */');
450+
'$1/* Open extern "C" */');
398451
replace(/(^#ifdef[ \t]+__cplusplus.*\n)\}[ \t]*$/gm,
399-
'$1/\* Close extern "C" */');
452+
'$1/* Close extern "C" */');
400453

401454
// Protect wrapping in CATALOG()
402455
replace(/^(CATALOG\(.*)$/gm, '/*$1*/');
@@ -438,18 +491,27 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
438491
* happens - we can not track these files (main reason)
439492
*/
440493

441-
let typedefs = await this.getTypedefs(utils.joinPath(pg_bsd_indent, '..'));
442-
const contents = this.runPreIndent(document.getText());
443-
const {stdout} = await utils.execShell(
494+
let typedefs = await this.getProcessedTypedefs(pg_bsd_indent);
495+
const preProcessed = this.runPreIndent(document.getText());
496+
const {stdout: processed} = await utils.execShell(
444497
pg_bsd_indent.fsPath, [
445498
...PgindentDocumentFormatterProvider.pg_bsd_indentDefaultFlags,
446499
`-U${typedefs.fsPath}`],
447-
{stdin: contents});
448-
const result = this.runPostIndent(stdout);
500+
{
501+
stdin: preProcessed,
502+
/*
503+
* pg_bsd_indent returns non-zero code if it encountered some
504+
* errors, but for us they are not important. i.e. no newline
505+
* at end of file causes to return code 1
506+
*/
507+
throwOnError: false,
508+
});
509+
const postProcessed = this.runPostIndent(processed);
510+
// const result = stdout;
449511

450512
/* On success cache pg_bsd_indent path */
451513
this.savedPgbsdPath = pg_bsd_indent;
452-
return result;
514+
return postProcessed;
453515
}
454516

455517
private async runPgindent(document: vscode.TextDocument,
@@ -490,7 +552,7 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
490552

491553
private async getTypedefs(pg_bsd_indent: vscode.Uri) {
492554
try {
493-
const typedefsFile = utils.joinPath(pg_bsd_indent, 'typedefs.list');
555+
const typedefsFile = utils.joinPath(pg_bsd_indent, '..', 'typedefs.list');
494556
if (await utils.fileExists(typedefsFile)) {
495557
return typedefsFile;
496558
}

src/utils.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ export async function execShell(cmd: string, args?: string[],
542542

543543
child.on('close', (code) => {
544544
if (code !== 0 && (throwOnError === undefined || throwOnError)) {
545-
reject(new Error(`command failed to execute. error stack: ${stderr.join('')}`));
545+
reject(new Error(`command failed to execute. error stack: ${stdout.join('')}`));
546546
} else {
547547
resolve({
548548
code: code ?? 0,
@@ -593,6 +593,28 @@ export async function deleteFile(file: vscode.Uri) {
593593
}
594594
}
595595

596+
export function readFile(path: vscode.Uri) {
597+
if (Features.hasWorkspaceFs()) {
598+
return vscode.workspace.fs.readFile(path)
599+
.then(value => new TextDecoder().decode(value));
600+
} else {
601+
return new Promise<string>((resolve, reject) => {
602+
fs.readFile(path.fsPath, (err, value) => {
603+
if (err) {
604+
reject(err);
605+
return;
606+
}
607+
608+
try {
609+
resolve(new TextDecoder().decode(value));
610+
} catch (err: any) {
611+
reject(err);
612+
}
613+
})
614+
})
615+
}
616+
}
617+
596618
export function writeFile(path: vscode.Uri, data: string): Thenable<void> {
597619
if (Features.hasWorkspaceFs()) {
598620
return vscode.workspace.fs.writeFile(path, new TextEncoder().encode(data));

0 commit comments

Comments
 (0)