From 5891a787891e2a46daeafe035c7436a8deb4f1dd Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 18 May 2026 11:23:18 +0100 Subject: [PATCH] fix(vscode-ext): pass real callbacks to registerCommand (affinescript#35 P2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit src/extension.affine called registerCommand("my-lang.run", 0) with an Int "wasm-table index" — a Phase-1 assumption. The Phase-2 (#35) stdlib binding is `registerCommand(name: String, handler: fn(Unit) -> Int)`, so the Int literal produced `Unify.TypeMismatch ((Unit -> Int), Int)` and the extension would not compile at all. Pass the handlers as real callbacks using the canonical pattern from affinescript's examples/vscode_extension_minimal.affine: `registerCommand("my-lang.run", fn(u: Unit) => handler_run())` (×3), and replace the now-obsolete wasm-table-index comment. Verified: `affinescript compile --vscode-extension src/extension.affine -o out/extension.cjs` succeeds (against affinescript origin/main stdlib); regenerated out/extension.cjs passes `node --check`; src/index.cjs wires it via require("../out/extension.cjs"). The upstream Vscode stdlib bindings already type-check on affinescript main — no affinescript change needed; this was purely the my-lang port using the stale contract. Refs affinescript#35 Refs affinescript#64 Co-Authored-By: Claude Opus 4.7 (1M context) --- vscode-extension/out/extension.cjs | 22 +++++++++++++++++----- vscode-extension/src/extension.affine | 15 ++++++++------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/vscode-extension/out/extension.cjs b/vscode-extension/out/extension.cjs index cfe631d..04de210 100644 --- a/vscode-extension/out/extension.cjs +++ b/vscode-extension/out/extension.cjs @@ -8,7 +8,7 @@ "use strict"; -const _wasmBase64 = "AGFzbQEAAAABSw5gBH9/f38Bf2ACf38Bf2ABfwF/YAN/f38Bf2AAAX9gBX9/f39/AX9gAn9/AX9gAAF/YAABf2AAAX9gAAF/YAABf2ABfwF/YAABfwLlAxEWd2FzaV9zbmFwc2hvdF9wcmV2aWV3MQhmZF93cml0ZQAABlZzY29kZQ9yZWdpc3RlckNvbW1hbmQAAQZWc2NvZGUQZ2V0Q29uZmlndXJhdGlvbgACBlZzY29kZRh3b3Jrc3BhY2VDb25maWdHZXRTdHJpbmcAAwZWc2NvZGUQc2hvd0Vycm9yTWVzc2FnZQACBlZzY29kZQ5jcmVhdGVUZXJtaW5hbAACBlZzY29kZQx0ZXJtaW5hbFNob3cAAgZWc2NvZGUQdGVybWluYWxTZW5kVGV4dAABBlZzY29kZRBwdXNoU3Vic2NyaXB0aW9uAAEGVnNjb2RlFGVkaXRvckFjdGl2ZUZpbGVQYXRoAAQGVnNjb2RlFmVkaXRvckFjdGl2ZUxhbmd1YWdlSWQABAZWc2NvZGUKY29uc29sZUxvZwACBlZzY29kZQxzdHJpbmdDb25jYXQAAQZWc2NvZGUOc3RyaW5nRW5kc1dpdGgAAQZWc2NvZGUTc3RyaW5nUmVwbGFjZVN1ZmZpeAADFFZzY29kZUxhbmd1YWdlQ2xpZW50EW5ld0xhbmd1YWdlQ2xpZW50AAUUVnNjb2RlTGFuZ3VhZ2VDbGllbnQTbGFuZ3VhZ2VDbGllbnRTdGFydAACAwkIBgcICQoLDA0EAQAFAwEAAQYBAAdPBgZtZW1vcnkCAAtoYW5kbGVyX3J1bgATDWhhbmRsZXJfYnVpbGQAFAxoYW5kbGVyX3Rlc3QAFQhhY3RpdmF0ZQAXCmRlYWN0aXZhdGUAGAkBAArRAggcAQF/IAAQBSECIAIQBhogAiABEAcaQQAPGkEACykBAX8QCiEAIABBgBAQDUEBRgR/EAkPGkEABUGGEBAEGkGaEA8aQQALCzgBAn8QEiEAIABBnhAQDUEARgR/QQAPGkEABUEACxpBpRAgABAMQbEQEAwhAUG2ECABEBEPGkEAC00BA38QEiEAIABBnhAQDUEARgR/QQAPGkEABUEACxogAEGeEEGaEBAOIQFBxRAgABAMQdMQEAwgAUGxEBAMEAwhAkG2ECACEBEPGkEACw4AQd0QQfIQEBEPGkEACzMBA39B/RAQAiEAIABBiBFBlBEQAyEBQf0QQZ4RIAFBmhBBABAPIQIgAhAQGkEADxpBAAs1AEG0ERALGiAAQdcRQQAQARAIGiAAQeYRQQEQARAIGiAAQfcRQQIQARAIGhAWGkEADxpBAAsIAEEADxpBAAsL+gITAEGAEAsGAgAAAG15AEGGEAsUEAAAAE5vIGFjdGl2ZSBlZGl0b3IAQZoQCwQAAAAAAEGeEAsHAwAAAC5teQBBpRALDAgAAABteSBydW4gIgBBsRALBQEAAAAiAEG2EAsPCwAAAE15IExhbmd1YWdlAEHFEAsOCgAAAG15IGJ1aWxkICIAQdMQCwoGAAAAIiAtbyAiAEHdEAsVEQAAAE15IExhbmd1YWdlIFRlc3RzAEHyEAsLBwAAAG15LXRlc3QAQf0QCwsHAAAAbXktbGFuZwBBiBELDAgAAABsc3AucGF0aABBlBELCgYAAABteS1sc3AAQZ4RCxYSAAAATXkgTGFuZ3VhZ2UgU2VydmVyAEG0EQsjHwAAAE15IExhbmd1YWdlIGV4dGVuc2lvbiBhY3RpdmF0ZWQAQdcRCw8LAAAAbXktbGFuZy5ydW4AQeYRCxENAAAAbXktbGFuZy5idWlsZABB9xELEAwAAABteS1sYW5nLnRlc3QAThZhZmZpbmVzY3JpcHQub3duZXJzaGlwCAAAABEAAAACAAAAEgAAAAAAEwAAAAAAFAAAAAAAFQAAAAAAFgAAAAAAFwAAAAEAABgAAAAAAA=="; +const _wasmBase64 = "AGFzbQEAAAABXRFgBH9/f38Bf2ACf38Bf2ABfwF/YAN/f38Bf2AAAX9gBX9/f39/AX9gAn9/AX9gAAF/YAABf2AAAX9gAAF/YAABf2ABfwF/YAJ/fwF/YAJ/fwF/YAJ/fwF/YAABfwLlAxEWd2FzaV9zbmFwc2hvdF9wcmV2aWV3MQhmZF93cml0ZQAABlZzY29kZQ9yZWdpc3RlckNvbW1hbmQAAQZWc2NvZGUQZ2V0Q29uZmlndXJhdGlvbgACBlZzY29kZRh3b3Jrc3BhY2VDb25maWdHZXRTdHJpbmcAAwZWc2NvZGUQc2hvd0Vycm9yTWVzc2FnZQACBlZzY29kZQ5jcmVhdGVUZXJtaW5hbAACBlZzY29kZQx0ZXJtaW5hbFNob3cAAgZWc2NvZGUQdGVybWluYWxTZW5kVGV4dAABBlZzY29kZRBwdXNoU3Vic2NyaXB0aW9uAAEGVnNjb2RlFGVkaXRvckFjdGl2ZUZpbGVQYXRoAAQGVnNjb2RlFmVkaXRvckFjdGl2ZUxhbmd1YWdlSWQABAZWc2NvZGUKY29uc29sZUxvZwACBlZzY29kZQxzdHJpbmdDb25jYXQAAQZWc2NvZGUOc3RyaW5nRW5kc1dpdGgAAQZWc2NvZGUTc3RyaW5nUmVwbGFjZVN1ZmZpeAADFFZzY29kZUxhbmd1YWdlQ2xpZW50EW5ld0xhbmd1YWdlQ2xpZW50AAUUVnNjb2RlTGFuZ3VhZ2VDbGllbnQTbGFuZ3VhZ2VDbGllbnRTdGFydAACAwwLBgcICQoLDBANDg8EBQFwAQMDBQMBAAEGBwF/AUGACAsHTwYGbWVtb3J5AgALaGFuZGxlcl9ydW4AEw1oYW5kbGVyX2J1aWxkABQMaGFuZGxlcl90ZXN0ABUIYWN0aXZhdGUAFwpkZWFjdGl2YXRlABgJCQEAQQALAxkaGwquAwscAQF/IAAQBSECIAIQBhogAiABEAcaQQAPGkEACykBAX8QCiEAIABBgBAQDUEBRgR/EAkPGkEABUGGEBAEGkGaEA8aQQALCzgBAn8QEiEAIABBnhAQDUEARgR/QQAPGkEABUEACxpBpRAgABAMQbEQEAwhAUG2ECABEBEPGkEAC00BA38QEiEAIABBnhAQDUEARgR/QQAPGkEABUEACxogAEGeEEGaEBAOIQFBxRAgABAMQdMQEAwgAUGxEBAMEAwhAkG2ECACEBEPGkEACw4AQd0QQfIQEBEPGkEACzMBA39B/RAQAiEAIABBiBFBlBEQAyEBQf0QQZ4RIAFBmhBBABAPIQIgAhAQGkEADxpBAAuCAQEDf0G0ERALGiAAQdcRIwAjAEEIaiQAIgEgAUEANgIAIAFBADYCBCABEAEQCBogAEHmESMAIwBBCGokACICIAJBATYCACACQQA2AgQgAhABEAgaIABB9xEjACMAQQhqJAAiAyADQQI2AgAgA0EANgIEIAMQARAIGhAWGkEADxpBAAsIAEEADxpBAAsEABATCwQAEBQLBAAQFQsL+gITAEGAEAsGAgAAAG15AEGGEAsUEAAAAE5vIGFjdGl2ZSBlZGl0b3IAQZoQCwQAAAAAAEGeEAsHAwAAAC5teQBBpRALDAgAAABteSBydW4gIgBBsRALBQEAAAAiAEG2EAsPCwAAAE15IExhbmd1YWdlAEHFEAsOCgAAAG15IGJ1aWxkICIAQdMQCwoGAAAAIiAtbyAiAEHdEAsVEQAAAE15IExhbmd1YWdlIFRlc3RzAEHyEAsLBwAAAG15LXRlc3QAQf0QCwsHAAAAbXktbGFuZwBBiBELDAgAAABsc3AucGF0aABBlBELCgYAAABteS1sc3AAQZ4RCxYSAAAATXkgTGFuZ3VhZ2UgU2VydmVyAEG0EQsjHwAAAE15IExhbmd1YWdlIGV4dGVuc2lvbiBhY3RpdmF0ZWQAQdcRCw8LAAAAbXktbGFuZy5ydW4AQeYRCxENAAAAbXktbGFuZy5idWlsZABB9xELEAwAAABteS1sYW5nLnRlc3QAThZhZmZpbmVzY3JpcHQub3duZXJzaGlwCAAAABEAAAACAAAAEgAAAAAAEwAAAAAAFAAAAAAAFQAAAAAAFgAAAAAAFwAAAAEAABgAAAAAAA=="; const _wasmBytes = Buffer.from(_wasmBase64, "base64"); // Per-process opaque-handle table for host objects (ExtensionContext, @@ -51,10 +51,10 @@ function _buildImports() { return 0; }, }; - // Phase 2 hook: callers can replace exports.extraImports with a function - // returning a `{ ModuleName: { exportName: fn, ... } }` map of concrete - // host bindings (e.g. the @hyperpolymath/affine-vscode adapter). Default - // is empty so the shim works standalone. + // Phase 2 hook: a caller may install an `extraImports` factory on the + // exports object returning a `{ ModuleName: { exportName: fn, ... } }` + // map of concrete host bindings (this is what the --vscode-extension + // wiring installs). Default is empty so the shim works standalone. const extras = (typeof exports.extraImports === "function") ? exports.extraImports() : {}; @@ -94,3 +94,15 @@ exports.deactivate = async function deactivate() { exports._registerHandle = _registerHandle; exports._getHandle = _getHandle; exports._freeHandle = _freeHandle; + +// Inserted by --vscode-extension (issue #105): auto-generated glue so this +// file is directly loadable as a VS Code extension's `main`. Replaces the +// previously hand-written index.cjs + vendored adapter boilerplate. +const _makeVscodeBindings = require("@hyperpolymath/affine-vscode"); +exports.extraImports = function() { + return _makeVscodeBindings( + require("vscode"), + require("vscode-languageclient/node"), + exports, + ); +}; diff --git a/vscode-extension/src/extension.affine b/vscode-extension/src/extension.affine index 8c165da..abced83 100644 --- a/vscode-extension/src/extension.affine +++ b/vscode-extension/src/extension.affine @@ -106,13 +106,14 @@ fn start_lsp() -> Int { pub fn activate(ctx: ExtensionContext) -> Int { let _ = consoleLog("My Language extension activated"); - // Register commands. The integer second argument to registerCommand is - // the wasm-table index of the handler — populated by the JS-side adapter - // from the `__indirect_function_table` export. Order must match the - // order handlers appear in this file. - let _ = pushSubscription(ctx, registerCommand("my-lang.run", 0)); - let _ = pushSubscription(ctx, registerCommand("my-lang.build", 1)); - let _ = pushSubscription(ctx, registerCommand("my-lang.test", 2)); + // Register commands. `registerCommand` takes the handler directly as a + // `fn(Unit) -> Int` (Vscode.affine binding); the `--vscode-extension` + // codegen lowers the function reference to the wasm table for us. The + // earlier Int-index form was a Phase-1 assumption, obsolete since the + // Phase-2 (#35) bindings expose real callbacks. + let _ = pushSubscription(ctx, registerCommand("my-lang.run", fn(u: Unit) => handler_run())); + let _ = pushSubscription(ctx, registerCommand("my-lang.build", fn(u: Unit) => handler_build())); + let _ = pushSubscription(ctx, registerCommand("my-lang.test", fn(u: Unit) => handler_test())); let _ = start_lsp(); return 0;