Skip to content

Commit 2772d4d

Browse files
committed
fix: add context to WIT content parsing errors
Signed-off-by: Gordon Smith <[email protected]>
1 parent 4a47867 commit 2772d4d

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

.github/copilot-instructions.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,54 @@ Big picture architecture
77
- Validation: `src/validator.ts` calls `validateWitSyntaxDetailedFromWasm` from `src/wasmUtils.ts`, parses errors with `src/errorParser.ts`, and writes VS Code diagnostics. Prefer Problems pane over popups.
88
- WASM integration: `src/wasmUtils.ts` lazy-loads local package `wit-bindgen-wasm` and initializes its wasm binary. Primary APIs: `getWitBindgenVersionFromWasm`, `validateWitSyntaxDetailedFromWasm`, `generateBindingsFromWasm` (returns JSON map of files with latin1-encoded content).
99
- Grammar/snippets: `syntaxes/wit.tmLanguage.json`, `snippets.json` (Language id: `wit`, scope: `source.wit`).
10-
- Rust subproject: `wit-bindgen-wasm/` builds a wasm-pack package consumed at runtime (`wit_bindgen_wasm_bg.wasm`).
10+
- Rust subproject: `wit-bindgen-wasm/` builds a wasm-pack package consumed at runtime (`wit_bindgen_wasm_bg.wasm`). Uses `wit-parser` 0.241, `wit-component` 0.241, and `wasmparser` 0.241.
1111

1212
Build and dev workflows
1313
- One-time setup (requires Rust + cargo): `npm run setup-wasm` (installs wasm-pack 0.13.1 and wasm32 target).
1414
- Dev watch: `npm run dev` (parallel: `gen-watch` for d.ts, `build-extension-watch` for esbuild).
1515
- Full build: `npm run build` (build wasm via wasm-pack, then bundle the extension with esbuild).
16+
- Build WASM only: `npm run build-wasm` (dev) or `npm run build-wasm-prod` (release).
1617
- Pack/install locally: `npm run package` then `npm run install-extension` (uses `vsce` and `code --install-extension`).
1718
- Tests: `npm test` runs lint, prettier check, build, package, grammar tests, and unit tests. Quick loops: `npm run test-unit` or `npm run test-grammar`. Update grammar snapshots: `npm run update-snapshot`.
19+
- Verify WASM build: `npm run verify-wasm` checks that the built WASM file exists and is valid.
1820

1921
Bundling details (esbuild.mjs)
2022
- ESM build targeting Node 22 with `external: ["vscode"]`, injects `src/node-polyfills.js`.
2123
- Plugins auto-discover and copy dynamic WASM references and worker JS to `dist/`. `src/wasmUtils.ts` first looks for `dist/wit_bindgen_wasm_bg.wasm` and falls back to module default init. If you introduce new wasm or worker assets referenced via `new URL('file.ext', import.meta.url)`, the plugin will attempt to copy them.
2224

2325
Runtime behaviors and contracts
2426
- Extract WIT from components: command `wit-idl.extractWit` shells out to `wasm-tools component wit <file.wasm>`; ensure `wasm-tools` is on PATH. Enablement uses a context key set when active editor is a `.wasm` with component version 0x0A.
25-
- Binding generation: `generateBindingsFromWasm` returns a JSON map of filename -> content (latin1). When writing to disk, create buffers via `Buffer.from(content, 'latin1')`. See usage in `src/extension.ts`.
27+
- Extract Core WASM: command `wit-idl.extractCoreWasm` uses `wasm-tools component wit <file.wasm> --raw` to extract the core module.
28+
- Binding generation: `generateBindingsFromWasm` returns a JSON map of filename -> content (latin1). When writing to disk, create buffers via `Buffer.from(content, 'latin1')`. See usage in `src/extension.ts`. Supports Rust, C, C#, Go, and MoonBit.
2629
- Diagnostics: use `WitSyntaxValidator.createDiagnosticFromError` and keep `diagnostic.source` consistent (`wit-syntax` or `wit-bindgen`). Workspace validation streams progress via `withProgress` and writes a dedicated output channel.
30+
- Format Document: command `wit-idl.formatDocument` formats WIT files using the WASM module's formatting capability.
2731

2832
Coding conventions specific to this repo
2933
- ESM TypeScript: use explicit `.js` extensions in relative imports (e.g., `import { X } from './validator.js'`). Keep explicit param/return types; avoid `any`.
3034
- File layout: implementation in `src/`, tests in `tests/` (Vitest), grammar tests under `tests/grammar/**`. Type declarations generated to `types/` by `npm run gen-types`.
3135
- VS Code contributions: update `package.json` for languages, grammars, snippets, menus, keybindings, and new commands. Match command IDs with registrations in `extension.ts`.
36+
- Use 4 spaces for indentation. Follow ESLint and Prettier rules.
37+
38+
wit-parser API changes (v0.239.0+, currently using 0.241)
39+
- `resolve.select_world(package_id, world_name)` now expects first argument as a slice: `resolve.select_world(&[package_id], world_name)`.
40+
- When calling `select_world`, always wrap package IDs in a slice: `&[pkg_id]`.
41+
- This applies to all direct uses of `wit_parser::Resolve::select_world` in the Rust codebase.
42+
- The project is currently using wit-parser 0.241, which maintains this API contract.
3243

3344
Adding a feature safely
3445
- Register a command in `package.json` and implement it in `src/extension.ts`; push to `context.subscriptions`.
3546
- If it relies on `wit-bindgen-wasm`, add a thin wrapper in `src/wasmUtils.ts` and write unit tests in `tests/` (Vitest). Use Problems pane diagnostics over modal errors.
3647
- If you need WIT extraction or inspection, prefer `wasm-tools` CLI calls (as in `extractWitWithWasmTools`).
3748

3849
Common pitfalls and fixes
39-
- “Failed to initialize WIT bindgen WASM module”: ensure `npm run build` copied `wit_bindgen_wasm_bg.wasm` to `dist/` or run `npm run setup-wasm && npm run build-wasm`.
40-
- “wasm-tools not found” when extracting WIT: install wasm-tools and ensure PATH is set for the VS Code environment.
50+
- "Failed to initialize WIT bindgen WASM module": ensure `npm run build` copied `wit_bindgen_wasm_bg.wasm` to `dist/` or run `npm run setup-wasm && npm run build-wasm`. Verify with `npm run verify-wasm`.
51+
- "wasm-tools not found" when extracting WIT: install wasm-tools and ensure PATH is set for the VS Code environment.
52+
- `select_world` signature errors: ensure you're wrapping package IDs in a slice `&[pkg_id]` when calling `resolve.select_world()`.
4153

4254
Key references
4355
- Additional instructions: `.github/instructions/*`
4456
- Entry point: `src/extension.ts`
4557
- Validation: `src/validator.ts`, `src/errorParser.ts`, `src/wasmUtils.ts`
4658
- Build: `esbuild.mjs`, `package.json` scripts
4759
- WASM package: `wit-bindgen-wasm/README.md`, `wit-bindgen-wasm/pkg/*`
60+
- Dependencies: `wit-parser` 0.241, `wit-component` 0.241, `wasmparser` 0.241, `wasm-tools` CLI

wit-bindgen-wasm/src/lib.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ impl WitBindgen {
262262
fn generate_c_with_wit_bindgen(&self, content: &str, world_name: Option<&str>) -> Result<HashMap<String, String>, anyhow::Error> {
263263
let inline_path = Path::new("inline.wit");
264264
let mut resolve = Resolve::default();
265-
let package_id = resolve.push_str(inline_path, content)?;
265+
let package_id = resolve.push_str(inline_path, content)
266+
.with_context(|| "Failed to parse WIT content for C binding generation")?;
266267

267268
let world_id = if let Some(world_name) = world_name {
268269
resolve.select_world(&[package_id], Some(world_name))?
@@ -304,7 +305,8 @@ impl WitBindgen {
304305
fn generate_rust_with_wit_bindgen(&self, content: &str, world_name: Option<&str>) -> Result<HashMap<String, String>, anyhow::Error> {
305306
let inline_path = Path::new("inline.wit");
306307
let mut resolve = Resolve::default();
307-
let package_id = resolve.push_str(inline_path, content)?;
308+
let package_id = resolve.push_str(inline_path, content)
309+
.with_context(|| "Failed to parse WIT content for Rust binding generation")?;
308310

309311
let world_id = if let Some(world_name) = world_name {
310312
resolve.select_world(&[package_id], Some(world_name))?
@@ -349,7 +351,8 @@ impl WitBindgen {
349351
fn generate_csharp_with_wit_bindgen(&self, content: &str, world_name: Option<&str>) -> Result<HashMap<String, String>, anyhow::Error> {
350352
let inline_path = Path::new("inline.wit");
351353
let mut resolve = Resolve::default();
352-
let package_id = resolve.push_str(inline_path, content)?;
354+
let package_id = resolve.push_str(inline_path, content)
355+
.with_context(|| "Failed to parse WIT content for C# binding generation")?;
353356

354357
let world_id = if let Some(world_name) = world_name {
355358
resolve.select_world(&[package_id], Some(world_name))?
@@ -412,7 +415,8 @@ impl WitBindgen {
412415
fn generate_moonbit_with_wit_bindgen(&self, content: &str, world_name: Option<&str>) -> Result<HashMap<String, String>, anyhow::Error> {
413416
let inline_path = Path::new("inline.wit");
414417
let mut resolve = Resolve::default();
415-
let package_id = resolve.push_str(inline_path, content)?;
418+
let package_id = resolve.push_str(inline_path, content)
419+
.with_context(|| "Failed to parse WIT content for MoonBit binding generation")?;
416420

417421
let world_id = if let Some(world_name) = world_name {
418422
resolve.select_world(&[package_id], Some(world_name))?

0 commit comments

Comments
 (0)