diff --git a/npm-packages/cadence-language-server/README.md b/npm-packages/cadence-language-server/README.md index 49d19a9e..7852ee70 100644 --- a/npm-packages/cadence-language-server/README.md +++ b/npm-packages/cadence-language-server/README.md @@ -6,5 +6,16 @@ so it can be used in tools written in JavaScript. ## Releasing -To release a new version of the Language server NPM package all you need to do is create a release of Langauge server and GitHub action will also publish a new version of WebAssembly built binary to NPM. +To release a new version of the Language server NPM package all you need to do is create a release of Langauge server and GitHub action will also publish a new version of WebAssembly built binary to NPM. That newly build NPM package using the WebAssembly will be published and can be found on NPM https://www.npmjs.com/package/@onflow/cadence-language-server + +## Development + +### Updating `src/go.js` + +- Copy `misc/wasm/wasm_exec.js` of appropriate Go version into `src/go.js`. + Keep the last line (`export const go = new Go();`) +- Update the version in the header +- Remove the anonymous function wrapper +- Change `globalThis.Go = class {` to `class Go {` +- Run `npx prettier -w src/go.js` diff --git a/npm-packages/cadence-language-server/package-lock.json b/npm-packages/cadence-language-server/package-lock.json index 49df09de..7619ad12 100644 --- a/npm-packages/cadence-language-server/package-lock.json +++ b/npm-packages/cadence-language-server/package-lock.json @@ -16,6 +16,7 @@ "@types/node": "^20.9.0", "jest": "^29.7.0", "node-fetch": "^2.6.1", + "prettier": "^3.2.5", "ts-jest": "^29.1.1", "typescript": "^5.2.2", "vscode-languageserver-protocol": "^3.17.5" @@ -3585,6 +3586,21 @@ "node": ">=8" } }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", @@ -6949,6 +6965,12 @@ "find-up": "^4.0.0" } }, + "prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true + }, "pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", diff --git a/npm-packages/cadence-language-server/package.json b/npm-packages/cadence-language-server/package.json index 29b055a6..f0c9eb41 100644 --- a/npm-packages/cadence-language-server/package.json +++ b/npm-packages/cadence-language-server/package.json @@ -20,7 +20,8 @@ "node-fetch": "^2.6.1", "ts-jest": "^29.1.1", "typescript": "^5.2.2", - "vscode-languageserver-protocol": "^3.17.5" + "vscode-languageserver-protocol": "^3.17.5", + "prettier": "^3.2.5" }, "files": [ "dist/**/*" diff --git a/npm-packages/cadence-language-server/src/go.js b/npm-packages/cadence-language-server/src/go.js index 04633bd0..64d398da 100644 --- a/npm-packages/cadence-language-server/src/go.js +++ b/npm-packages/cadence-language-server/src/go.js @@ -1,9 +1,11 @@ -// Adapted from https://github.com/golang/go/blob/go1.20.14/misc/wasm/wasm_exec.js +// Adapted from https://github.com/golang/go/blob/go1.21.9/misc/wasm/wasm_exec.js // Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +"use strict"; + const enosys = () => { const err = new Error("not implemented"); err.code = "ENOSYS"; @@ -143,13 +145,13 @@ if (!globalThis.process) { if (!globalThis.crypto) { throw new Error( - "globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)" + "globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)", ); } if (!globalThis.performance) { throw new Error( - "globalThis.performance is not available, polyfill required (performance.now only)" + "globalThis.performance is not available, polyfill required (performance.now only)", ); } @@ -185,6 +187,10 @@ class Go { this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true); }; + const setInt32 = (addr, v) => { + this.mem.setUint32(addr + 0, v, true); + }; + const getInt64 = (addr) => { const low = this.mem.getUint32(addr + 0, true); const high = this.mem.getInt32(addr + 4, true); @@ -274,13 +280,16 @@ class Go { const saddr = getInt64(addr + 0); const len = getInt64(addr + 8); return decoder.decode( - new DataView(this._inst.exports.mem.buffer, saddr, len) + new DataView(this._inst.exports.mem.buffer, saddr, len), ); }; const timeOrigin = Date.now() - performance.now(); this.importObject = { - go: { + _gotest: { + add: (a, b) => a + b, + }, + gojs: { // Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters) // may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported // function. A goroutine can switch to a new stack if the current stack is too small (see morestack function). @@ -345,8 +354,8 @@ class Go { this._resume(); } }, - getInt64(sp + 8) + 1 // setTimeout has been seen to fire up to 1 millisecond early - ) + getInt64(sp + 8), + ), ); this.mem.setInt32(sp + 16, id, true); }, @@ -398,7 +407,7 @@ class Go { Reflect.set( loadValue(sp + 8), loadString(sp + 16), - loadValue(sp + 32) + loadValue(sp + 32), ); }, @@ -413,7 +422,7 @@ class Go { sp >>>= 0; storeValue( sp + 24, - Reflect.get(loadValue(sp + 8), getInt64(sp + 16)) + Reflect.get(loadValue(sp + 8), getInt64(sp + 16)), ); }, @@ -501,7 +510,7 @@ class Go { sp >>>= 0; this.mem.setUint8( sp + 24, - loadValue(sp + 8) instanceof loadValue(sp + 16) ? 1 : 0 + loadValue(sp + 8) instanceof loadValue(sp + 16) ? 1 : 0, ); }, @@ -615,7 +624,7 @@ class Go { const wasmMinDataAddr = 4096 + 8192; if (offset >= wasmMinDataAddr) { throw new Error( - "total length of command line and environment variables exceeds limit" + "total length of command line and environment variables exceeds limit", ); } @@ -645,6 +654,6 @@ class Go { return event.result; }; } -} +}; export const go = new Go();