Skip to content

Commit 5c23adb

Browse files
committed
Better regex error diagnostics
1 parent bf9c61d commit 5c23adb

File tree

7 files changed

+7784
-75
lines changed

7 files changed

+7784
-75
lines changed

out/DiagnosticCollection.js

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,8 @@ const vscode = require("vscode");
55
const vscodeOniguruma = require("vscode-oniguruma");
66
const TreeSitter_1 = require("./TreeSitter");
77
const extension_1 = require("./extension");
8-
async function initDiagnostics(context) {
8+
function initDiagnostics(context) {
99
// vscode.window.showInformationMessage(JSON.stringify("initDiagnostics"));
10-
// Oniguruma regex parser
11-
// try {
12-
const uri = vscode.Uri.joinPath(context.extensionUri, 'node_modules', 'vscode-oniguruma', 'release', 'onig.wasm');
13-
const wasm = await vscode.workspace.fs.readFile(uri);
14-
const options = {
15-
data: wasm,
16-
print(string) {
17-
console.log(string);
18-
}
19-
};
20-
await vscodeOniguruma.loadWASM(options);
21-
// } catch (error) {
22-
// vscode.window.showInformationMessage(JSON.stringify(error));
23-
// // https://github.com/microsoft/vscode-oniguruma/issues/10
24-
// const response = await fetch('/node_modules/vscode-oniguruma/release/onig.wasm');
25-
// const contentType = response.headers.get('content-type');
26-
// // Using the response directly only works if the server sets the MIME type 'application/wasm'.
27-
// // Otherwise, a TypeError is thrown when using the streaming compiler.
28-
// // We therefore use the non-streaming compiler :(.
29-
// const wasm = contentType === 'application/wasm' ? response : await response.arrayBuffer();
30-
// const options: vscodeOniguruma.IDataOptions = {
31-
// data: wasm,
32-
// print(string: string) {
33-
// console.log(string);
34-
// }
35-
// }
36-
// await vscodeOniguruma.loadWASM(options);
37-
// }
3810
const DiagnosticCollection = vscode.languages.createDiagnosticCollection("textmate");
3911
context.subscriptions.push(DiagnosticCollection);
4012
for (const editor of vscode.window.visibleTextEditors) {
@@ -192,18 +164,19 @@ function Diagnostics(document, Diagnostics) {
192164
// `\\3` could be valid; could be invalid. Who knows?
193165
// Would need to check the `begin` regex first for the number of capture groups
194166
// Then how to tell Oniguruma how many are available??
167+
// Keeping in mind /(?I:...)/
195168
regex = regex.replace(/\\[1-9](\d{2})?(?!\d)/g, '\\0');
196169
}
197-
const string = vscodeOniguruma.createOnigString(''); // blank. Maybe can test against a user provided string?
198-
// const scanner = vscodeOniguruma.createOnigScanner([regex]);
199-
const scanner = new vscodeOniguruma.OnigScanner(['', regex]);
200-
const match = scanner.findNextMatchSync(string, 0); // returns null if `regex` is invalid
201-
// vscode.window.showInformationMessage(JSON.stringify(match));
202-
if (!match) {
170+
const scanner = new vscodeOniguruma.OnigScanner([regex]);
171+
const onigBinding = scanner._onigBinding;
172+
const errorCode = onigBinding.UTF8ToString(onigBinding._getLastOnigError());
173+
// const string = vscodeOniguruma.createOnigString(''); // blank. Maybe can test against a user provided string?
174+
// const match = scanner.findNextMatchSync(string, 0); // returns null if `regex` is invalid
175+
if (errorCode != 'undefined error code') {
203176
const range = (0, TreeSitter_1.toRange)(key);
204177
const diagnostic = {
205178
range: range,
206-
message: `Regex Failed Parse Test.`,
179+
message: errorCode,
207180
severity: vscode.DiagnosticSeverity.Error,
208181
source: 'Oniguruma',
209182
};

out/extension.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
33
exports.deactivate = exports.activate = exports.DocumentSelector = void 0;
44
const vscode = require("vscode");
55
const TreeSitter_1 = require("./TreeSitter");
6+
const oniguruma_1 = require("./oniguruma");
67
const DiagnosticCollection_1 = require("./DiagnosticCollection");
78
const tokenColorCustomizations_1 = require("./tokenColorCustomizations");
89
const RenameProvider_1 = require("./RenameProvider");
@@ -19,6 +20,7 @@ exports.DocumentSelector = [
1920
async function activate(context) {
2021
// vscode.window.showInformationMessage(JSON.stringify("TextMate Extension"));
2122
await (0, TreeSitter_1.initTreeSitter)(context);
23+
await (0, oniguruma_1.initOniguruma)(context);
2224
(0, DiagnosticCollection_1.initDiagnostics)(context);
2325
(0, tokenColorCustomizations_1.initTokenColorCustomizations)(context);
2426
// context.subscriptions.push(vscode.languages.registerHoverProvider(DocumentSelector, HoverProvider)); // Mouse over Hovers

out/oniguruma.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });
3+
exports.initOniguruma = void 0;
4+
const vscode = require("vscode");
5+
const vscodeOniguruma = require("vscode-oniguruma");
6+
async function initOniguruma(context) {
7+
const uri = vscode.Uri.joinPath(context.extensionUri, 'node_modules', 'vscode-oniguruma', 'release', 'onig.wasm');
8+
const wasm = await vscode.workspace.fs.readFile(uri);
9+
const options = {
10+
data: wasm,
11+
print(string) {
12+
console.log(string);
13+
}
14+
};
15+
await vscodeOniguruma.loadWASM(options);
16+
// // https://github.com/microsoft/vscode-oniguruma/issues/10
17+
// const response = await fetch('/node_modules/vscode-oniguruma/release/onig.wasm');
18+
// const contentType = response.headers.get('content-type');
19+
// // Using the response directly only works if the server sets the MIME type 'application/wasm'.
20+
// // Otherwise, a TypeError is thrown when using the streaming compiler.
21+
// // We therefore use the non-streaming compiler :(.
22+
// const wasm = contentType === 'application/wasm' ? response : await response.arrayBuffer();
23+
// const options: vscodeOniguruma.IDataOptions = {
24+
// data: wasm,
25+
// print(string: string) {
26+
// console.log(string);
27+
// }
28+
// }
29+
// await vscodeOniguruma.loadWASM(options);
30+
}
31+
exports.initOniguruma = initOniguruma;

out/web/extension.js

Lines changed: 7675 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/DiagnosticCollection.ts

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,29 @@ import { getTree, getTrees, queryNode, toRange, trueParent } from "./TreeSitter"
44
import { DocumentSelector } from './extension';
55

66

7+
type IOnigBinding = {
8+
HEAPU8: Uint8Array;
9+
HEAPU32: Uint32Array;
710

8-
export async function initDiagnostics(context: vscode.ExtensionContext) {
9-
// vscode.window.showInformationMessage(JSON.stringify("initDiagnostics"));
10-
// Oniguruma regex parser
11-
// try {
12-
const uri = vscode.Uri.joinPath(context.extensionUri, 'node_modules', 'vscode-oniguruma', 'release', 'onig.wasm');
13-
const wasm = await vscode.workspace.fs.readFile(uri);
14-
const options: vscodeOniguruma.IDataOptions = {
15-
data: wasm,
16-
print(string: string) {
17-
console.log(string);
18-
}
19-
}
20-
await vscodeOniguruma.loadWASM(options);
21-
22-
// } catch (error) {
23-
// vscode.window.showInformationMessage(JSON.stringify(error));
24-
// // https://github.com/microsoft/vscode-oniguruma/issues/10
25-
// const response = await fetch('/node_modules/vscode-oniguruma/release/onig.wasm');
26-
// const contentType = response.headers.get('content-type');
11+
_omalloc(count: number): Pointer;
12+
_ofree(ptr: Pointer): void;
13+
UTF8ToString(ptr: Pointer): string;
2714

28-
// // Using the response directly only works if the server sets the MIME type 'application/wasm'.
29-
// // Otherwise, a TypeError is thrown when using the streaming compiler.
30-
// // We therefore use the non-streaming compiler :(.
31-
// const wasm = contentType === 'application/wasm' ? response : await response.arrayBuffer();
32-
// const options: vscodeOniguruma.IDataOptions = {
33-
// data: wasm,
34-
// print(string: string) {
35-
// console.log(string);
36-
// }
37-
// }
38-
// await vscodeOniguruma.loadWASM(options);
39-
// }
15+
_getLastOnigError(): Pointer;
16+
_createOnigScanner(strPtrsPtr: Pointer, strLenPtr: Pointer, count: number, options: number, syntax: Pointer): Pointer;
17+
_freeOnigScanner(ptr: Pointer): void;
18+
_findNextOnigScannerMatch(scanner: Pointer, strCacheId: number, strData: Pointer, strLength: number, position: number, options: number): number;
19+
_findNextOnigScannerMatchDbg(scanner: Pointer, strCacheId: number, strData: Pointer, strLength: number, position: number, options: number): number;
20+
}
21+
type Pointer = number;
22+
type OnigScanner = vscodeOniguruma.OnigScanner & {
23+
readonly _onigBinding: IOnigBinding;
24+
readonly _ptr: Pointer;
25+
readonly _options: vscodeOniguruma.FindOption[];
26+
}
4027

28+
export function initDiagnostics(context: vscode.ExtensionContext) {
29+
// vscode.window.showInformationMessage(JSON.stringify("initDiagnostics"));
4130
const DiagnosticCollection = vscode.languages.createDiagnosticCollection("textmate");
4231
context.subscriptions.push(DiagnosticCollection);
4332

@@ -223,20 +212,23 @@ function Diagnostics(document: vscode.TextDocument, Diagnostics: vscode.Diagnost
223212
// `\\3` could be valid; could be invalid. Who knows?
224213
// Would need to check the `begin` regex first for the number of capture groups
225214
// Then how to tell Oniguruma how many are available??
215+
// Keeping in mind /(?I:...)/
226216
regex = regex.replace(/\\[1-9](\d{2})?(?!\d)/g, '\\0');
227217
}
228218

229-
const string = vscodeOniguruma.createOnigString(''); // blank. Maybe can test against a user provided string?
230-
// const scanner = vscodeOniguruma.createOnigScanner([regex]);
231-
const scanner = new vscodeOniguruma.OnigScanner(['', regex]);
232-
const match = scanner.findNextMatchSync(string, 0); // returns null if `regex` is invalid
219+
const scanner = new vscodeOniguruma.OnigScanner([regex]);
220+
221+
const onigBinding = (<OnigScanner>scanner)._onigBinding;
222+
const errorCode = onigBinding.UTF8ToString(onigBinding._getLastOnigError());
233223

234-
// vscode.window.showInformationMessage(JSON.stringify(match));
235-
if (!match) {
224+
// const string = vscodeOniguruma.createOnigString(''); // blank. Maybe can test against a user provided string?
225+
// const match = scanner.findNextMatchSync(string, 0); // returns null if `regex` is invalid
226+
227+
if (errorCode != 'undefined error code') {
236228
const range = toRange(key);
237229
const diagnostic: vscode.Diagnostic = {
238230
range: range,
239-
message: `Regex Failed Parse Test.`,
231+
message: errorCode,
240232
severity: vscode.DiagnosticSeverity.Error,
241233
source: 'Oniguruma',
242234
};

src/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from 'vscode';
22

33
import { initTreeSitter } from "./TreeSitter";
4+
import { initOniguruma } from './oniguruma';
45
import { initDiagnostics } from "./DiagnosticCollection";
56
import { initTokenColorCustomizations } from './tokenColorCustomizations';
67

@@ -26,6 +27,7 @@ export async function activate(context: vscode.ExtensionContext) {
2627
// vscode.window.showInformationMessage(JSON.stringify("TextMate Extension"));
2728

2829
await initTreeSitter(context);
30+
await initOniguruma(context);
2931
initDiagnostics(context);
3032
initTokenColorCustomizations(context);
3133

src/oniguruma.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import * as vscode from 'vscode';
2+
import * as vscodeOniguruma from "vscode-oniguruma";
3+
4+
export async function initOniguruma(context: vscode.ExtensionContext): Promise<void> {
5+
const uri = vscode.Uri.joinPath(context.extensionUri, 'node_modules', 'vscode-oniguruma', 'release', 'onig.wasm');
6+
const wasm = await vscode.workspace.fs.readFile(uri);
7+
8+
const options: vscodeOniguruma.IDataOptions = {
9+
data: wasm,
10+
print(string: string) {
11+
console.log(string);
12+
}
13+
}
14+
15+
await vscodeOniguruma.loadWASM(options);
16+
17+
18+
19+
// // https://github.com/microsoft/vscode-oniguruma/issues/10
20+
// const response = await fetch('/node_modules/vscode-oniguruma/release/onig.wasm');
21+
// const contentType = response.headers.get('content-type');
22+
23+
// // Using the response directly only works if the server sets the MIME type 'application/wasm'.
24+
// // Otherwise, a TypeError is thrown when using the streaming compiler.
25+
// // We therefore use the non-streaming compiler :(.
26+
// const wasm = contentType === 'application/wasm' ? response : await response.arrayBuffer();
27+
// const options: vscodeOniguruma.IDataOptions = {
28+
// data: wasm,
29+
// print(string: string) {
30+
// console.log(string);
31+
// }
32+
// }
33+
// await vscodeOniguruma.loadWASM(options);
34+
35+
}

0 commit comments

Comments
 (0)