code-gauge 4.7.0 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +1 -1
  2. package/THIRD-PARTY-NOTICES.txt +595 -29
  3. package/dist/cli.cjs +1 -1
  4. package/dist/cli.cjs.map +1 -1
  5. package/dist/cli.js +1 -1
  6. package/dist/cli.js.map +1 -1
  7. package/dist/cliConfig.cjs +1 -1
  8. package/dist/cliConfig.cjs.map +1 -1
  9. package/dist/cliConfig.js +1 -1
  10. package/dist/cliConfig.js.map +1 -1
  11. package/dist/crossFileDuplication.cjs +1 -1
  12. package/dist/crossFileDuplication.cjs.map +1 -1
  13. package/dist/crossFileDuplication.js +1 -1
  14. package/dist/crossFileDuplication.js.map +1 -1
  15. package/dist/crossFileNearMiss.cjs +1 -1
  16. package/dist/crossFileNearMiss.cjs.map +1 -1
  17. package/dist/crossFileNearMiss.js +1 -1
  18. package/dist/crossFileNearMiss.js.map +1 -1
  19. package/dist/diffCommand.cjs +3 -3
  20. package/dist/diffCommand.cjs.map +1 -1
  21. package/dist/diffCommand.js +3 -3
  22. package/dist/diffCommand.js.map +1 -1
  23. package/dist/duplicateSelection.cjs +1 -1
  24. package/dist/duplicateSelection.cjs.map +1 -1
  25. package/dist/duplicateSelection.js +1 -1
  26. package/dist/duplicateSelection.js.map +1 -1
  27. package/dist/duplication.cjs +1 -1
  28. package/dist/duplication.cjs.map +1 -1
  29. package/dist/duplication.js +1 -1
  30. package/dist/duplication.js.map +1 -1
  31. package/dist/git.cjs +1 -1
  32. package/dist/git.cjs.map +1 -1
  33. package/dist/git.js +1 -1
  34. package/dist/git.js.map +1 -1
  35. package/dist/languages.cjs +1 -1
  36. package/dist/languages.cjs.map +1 -1
  37. package/dist/languages.js +1 -1
  38. package/dist/languages.js.map +1 -1
  39. package/dist/metrics.cjs +1 -1
  40. package/dist/metrics.cjs.map +1 -1
  41. package/dist/metrics.d.ts +8 -3
  42. package/dist/metrics.js +1 -1
  43. package/dist/metrics.js.map +1 -1
  44. package/dist/nativeMetrics.cjs +3 -3
  45. package/dist/nativeMetrics.cjs.map +1 -1
  46. package/dist/nativeMetrics.d.ts +19 -3
  47. package/dist/nativeMetrics.js +3 -3
  48. package/dist/nativeMetrics.js.map +1 -1
  49. package/dist/regressionGate.cjs +1 -1
  50. package/dist/regressionGate.cjs.map +1 -1
  51. package/dist/regressionGate.js +1 -1
  52. package/dist/regressionGate.js.map +1 -1
  53. package/dist/scan.cjs +1 -1
  54. package/dist/scan.cjs.map +1 -1
  55. package/dist/scan.d.ts +2 -2
  56. package/dist/scan.js +1 -1
  57. package/dist/scan.js.map +1 -1
  58. package/dist/wasmBinding.cjs +1 -1
  59. package/dist/wasmBinding.cjs.map +1 -1
  60. package/dist/wasmBinding.js +1 -1
  61. package/dist/wasmBinding.js.map +1 -1
  62. package/native/Cargo.lock +48 -15
  63. package/native/Cargo.toml +11 -10
  64. package/native/code-gauge.wasm +0 -0
  65. package/native/src/complexity.rs +152 -255
  66. package/native/src/dep_degree.rs +79 -65
  67. package/native/src/duplication.rs +114 -97
  68. package/native/src/functions.rs +181 -206
  69. package/native/src/languages.rs +48 -7
  70. package/native/src/lib.rs +10 -5
  71. package/native/src/measure.rs +125 -150
  72. package/native/src/napi.rs +61 -2
  73. package/native/src/ncss.rs +108 -104
  74. package/native/src/near_miss.rs +7 -7
  75. package/native/src/tree_index.rs +119 -0
  76. package/native/src/util.rs +15 -55
  77. package/native/src/worker_pool.rs +53 -0
  78. package/package.json +10 -10
@@ -1,2 +1,2 @@
1
- import{NativeAddonError as e}from"./nativeMetrics.js";const t=new TextEncoder,n=new TextDecoder;function r(e){let t,r,s=a=>{if(!t){if(r)throw r;try{t=i(e)}catch(e){throw r=e,e}}let{exports:o,stderr:s}=t;s.length=0;let c;try{c=a(o)}catch(e){throw t=void 0,Error(`The code-gauge WebAssembly module crashed: ${s.join(``).trim()||String(e)}`,{cause:e})}let l=n.decode(new Uint8Array(o.memory.buffer,o.result_ptr(),o.result_len()));if(c!==0)throw Error(l);return l};return{measureCodeNative:(e,t,n,r,i,c,l)=>s(s=>s.measure_code(...a(s,e),...a(s,t),Number(n),o(r),o(i),o(c),Number(l??!1))),collectCrossFileDataNative:(e,t,n)=>s(r=>r.collect_cross_file_data(...a(r,e),...a(r,t),o(n))),collectFunctionTokenSequencesNative:(e,t)=>s(n=>n.collect_function_token_sequences(...a(n,e),...a(n,t)))}}function i(t){let n=[],r,i=new WebAssembly.Instance(t,{wasi_snapshot_preview1:c(()=>r,n)}).exports;r=i.memory;let a=i.payload_version();if(a!==7)throw new e(`The code-gauge WebAssembly module has payload version ${a}, but 7 is expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with \`bun run build-wasm\``);return{exports:i,stderr:n}}function a(e,n){let r=t.encode(n),i=e.alloc(r.length);return new Uint8Array(e.memory.buffer,i,r.length).set(r),[i,r.length]}function o(e){return e??-1}const s=65536;function c(e,t){let r=()=>new DataView(e().buffer),i=()=>8;return{environ_get:()=>0,environ_sizes_get:(e,t)=>(r().setUint32(e,0,!0),r().setUint32(t,0,!0),0),clock_time_get:(e,t,n)=>(r().setBigUint64(n,BigInt(Date.now())*1000000n,!0),0),random_get:(t,n)=>{for(let r=0;r<n;r+=s)crypto.getRandomValues(new Uint8Array(e().buffer,t+r,Math.min(s,n-r)));return 0},fd_write:(i,a,o,s)=>{let c=r(),l=0;for(let r=0;r<o;r++){let o=c.getUint32(a+r*8,!0),s=c.getUint32(a+r*8+4,!0);i===2&&t.push(n.decode(new Uint8Array(e().buffer,o,s))),l+=s}return c.setUint32(s,l,!0),0},fd_close:i,fd_fdstat_get:i,fd_fdstat_set_flags:i,fd_read:i,fd_seek:i,proc_exit:e=>{throw Error(`The code-gauge WebAssembly module exited with code ${e}`)}}}export{r as createWasmBinding};
1
+ import{NativeAddonError as e}from"./nativeMetrics.js";const t=new TextEncoder,n=new TextDecoder;function r(e){let t,r,s=a=>{if(!t){if(r)throw r;try{t=i(e)}catch(e){throw r=e,e}}let{exports:o,stderr:s}=t;s.length=0;let c;try{c=a(o)}catch(e){throw t=void 0,Error(`The code-gauge WebAssembly module crashed: ${s.join(``).trim()||String(e)}`,{cause:e})}let l=n.decode(new Uint8Array(o.memory.buffer,o.result_ptr(),o.result_len()));if(c!==0)throw Error(l);return l},c=(e,t,n,r,i,c,l)=>s(s=>s.measure_code(...a(s,e),...a(s,t),Number(n),o(r),o(i),o(c),Number(l)));return{measureCodeNative:c,measureCodeNativeAsync:async(...e)=>c(...e),collectCrossFileDataNative:(e,t,n)=>s(r=>r.collect_cross_file_data(...a(r,e),...a(r,t),o(n))),collectFunctionTokenSequencesNative:(e,t)=>s(n=>n.collect_function_token_sequences(...a(n,e),...a(n,t)))}}function i(t){let n=[],r,i=new WebAssembly.Instance(t,{wasi_snapshot_preview1:c(()=>r,n)}).exports;r=i.memory;let a=i.payload_version();if(a!==8)throw new e(`The code-gauge WebAssembly module has payload version ${a}, but 8 is expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with \`bun run build-wasm\``);return{exports:i,stderr:n}}function a(e,n){let r=t.encode(n),i=e.alloc(r.length);return new Uint8Array(e.memory.buffer,i,r.length).set(r),[i,r.length]}function o(e){return e??-1}const s=65536;function c(e,t){let r=()=>new DataView(e().buffer),i=()=>8;return{environ_get:()=>0,environ_sizes_get:(e,t)=>(r().setUint32(e,0,!0),r().setUint32(t,0,!0),0),clock_time_get:(e,t,n)=>(r().setBigUint64(n,BigInt(Date.now())*1000000n,!0),0),random_get:(t,n)=>{for(let r=0;r<n;r+=s)crypto.getRandomValues(new Uint8Array(e().buffer,t+r,Math.min(s,n-r)));return 0},fd_write:(i,a,o,s)=>{let c=r(),l=0;for(let r=0;r<o;r++){let o=c.getUint32(a+r*8,!0),s=c.getUint32(a+r*8+4,!0);i===2&&t.push(n.decode(new Uint8Array(e().buffer,o,s))),l+=s}return c.setUint32(s,l,!0),0},fd_close:i,fd_fdstat_get:i,fd_fdstat_set_flags:i,fd_read:i,fd_seek:i,proc_exit:e=>{throw Error(`The code-gauge WebAssembly module exited with code ${e}`)}}}export{r as createWasmBinding};
2
2
  //# sourceMappingURL=wasmBinding.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wasmBinding.js","names":[],"sources":["../src/wasmBinding.ts"],"sourcesContent":["import { expectedPayloadVersion, NativeAddonError, type NativeBinding } from './nativeMetrics.js';\n\n/** The C ABI exported by native/src/wasm.rs. */\ninterface WasmExports {\n memory: WebAssembly.Memory;\n payload_version(): number;\n alloc(length: number): number;\n result_ptr(): number;\n result_len(): number;\n measure_code(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n includeSyntaxTree: number,\n minTokens: number,\n maxGapTokens: number,\n minSimilarityPercent: number,\n includeCrossFileData: number\n ): number;\n collect_cross_file_data(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n minTokens: number\n ): number;\n collect_function_token_sequences(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number\n ): number;\n}\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/**\n * Wraps the WebAssembly build of the native addon (native/src/wasm.rs) as a NativeBinding. The\n * module is instantiated synchronously on first use and again after a trap (a panic or stack\n * overflow), because a trap leaves the instance's memory and stack pointer in an undefined state.\n * An instantiation failure (e.g., a payload version mismatch) is memoized like the N-API loader's,\n * since instantiating the same module again would fail again.\n */\nexport function createWasmBinding(module: WebAssembly.Module): NativeBinding {\n let instance: { exports: WasmExports; stderr: string[] } | undefined;\n let instantiationFailure: unknown;\n\n const call = (invoke: (exports: WasmExports) => number): string => {\n if (!instance) {\n if (instantiationFailure) {\n throw instantiationFailure;\n }\n try {\n instance = instantiate(module);\n } catch (error) {\n instantiationFailure = error;\n throw error;\n }\n }\n const { exports, stderr } = instance;\n stderr.length = 0;\n let status: number;\n try {\n status = invoke(exports);\n } catch (error) {\n instance = undefined;\n throw new Error(`The code-gauge WebAssembly module crashed: ${stderr.join('').trim() || String(error)}`, {\n cause: error,\n });\n }\n const result = decoder.decode(new Uint8Array(exports.memory.buffer, exports.result_ptr(), exports.result_len()));\n if (status !== 0) {\n throw new Error(result);\n }\n return result;\n };\n\n return {\n measureCodeNative: (\n code,\n language,\n includeSyntaxTree,\n minTokens,\n maxGapTokens,\n minSimilarityPercent,\n includeCrossFileData\n ) =>\n call((exports) =>\n exports.measure_code(\n ...passString(exports, code),\n ...passString(exports, language),\n Number(includeSyntaxTree),\n toOptionalU32(minTokens),\n toOptionalU32(maxGapTokens),\n toOptionalU32(minSimilarityPercent),\n Number(includeCrossFileData ?? false)\n )\n ),\n collectCrossFileDataNative: (code, language, minTokens) =>\n call((exports) =>\n exports.collect_cross_file_data(\n ...passString(exports, code),\n ...passString(exports, language),\n toOptionalU32(minTokens)\n )\n ),\n collectFunctionTokenSequencesNative: (code, language) =>\n call((exports) =>\n exports.collect_function_token_sequences(...passString(exports, code), ...passString(exports, language))\n ),\n };\n}\n\nfunction instantiate(module: WebAssembly.Module): { exports: WasmExports; stderr: string[] } {\n const stderr: string[] = [];\n let memory: WebAssembly.Memory | undefined;\n const instance = new WebAssembly.Instance(module, {\n wasi_snapshot_preview1: createWasiImports(() => memory as WebAssembly.Memory, stderr),\n });\n const exports = instance.exports as unknown as WasmExports;\n memory = exports.memory;\n const version = exports.payload_version();\n if (version !== expectedPayloadVersion) {\n throw new NativeAddonError(\n `The code-gauge WebAssembly module has payload version ${version}, but ${expectedPayloadVersion} is ` +\n 'expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with `bun run build-wasm`'\n );\n }\n return { exports, stderr };\n}\n\n/** Copies a string into a buffer whose ownership passes to the called export. */\nfunction passString(exports: WasmExports, text: string): [number, number] {\n // TextEncoder replaces lone surrogates with U+FFFD, like toWellFormed() does for the N-API addon.\n const bytes = encoder.encode(text);\n const pointer = exports.alloc(bytes.length);\n new Uint8Array(exports.memory.buffer, pointer, bytes.length).set(bytes);\n return [pointer, bytes.length];\n}\n\n/** native/src/wasm.rs reads a negative value as an absent setting. */\nfunction toOptionalU32(value: number | undefined): number {\n return value ?? -1;\n}\n\nconst WASI_ERRNO_SUCCESS = 0;\nconst WASI_ERRNO_BADF = 8;\n// crypto.getRandomValues() rejects requests larger than this.\nconst MAX_RANDOM_BYTES = 65_536;\n\n/**\n * The WASI preview 1 functions the module imports. The metrics code performs no I/O, so file\n * descriptors are unavailable except for writes, whose stderr output (e.g., a panic message) is\n * kept for the error raised when the module traps.\n */\nfunction createWasiImports(\n getMemory: () => WebAssembly.Memory,\n stderr: string[]\n): Record<string, (...args: never[]) => number> {\n const view = (): DataView => new DataView(getMemory().buffer);\n const unavailable = (): number => WASI_ERRNO_BADF;\n return {\n environ_get: () => WASI_ERRNO_SUCCESS,\n environ_sizes_get: (countPointer: number, sizePointer: number) => {\n view().setUint32(countPointer, 0, true);\n view().setUint32(sizePointer, 0, true);\n return WASI_ERRNO_SUCCESS;\n },\n clock_time_get: (_clockId: number, _precision: bigint, timePointer: number) => {\n view().setBigUint64(timePointer, BigInt(Date.now()) * 1_000_000n, true);\n return WASI_ERRNO_SUCCESS;\n },\n random_get: (pointer: number, length: number) => {\n for (let offset = 0; offset < length; offset += MAX_RANDOM_BYTES) {\n crypto.getRandomValues(\n new Uint8Array(getMemory().buffer, pointer + offset, Math.min(MAX_RANDOM_BYTES, length - offset))\n );\n }\n return WASI_ERRNO_SUCCESS;\n },\n fd_write: (fd: number, iovsPointer: number, iovsLength: number, writtenPointer: number) => {\n const memoryView = view();\n let written = 0;\n for (let index = 0; index < iovsLength; index++) {\n const pointer = memoryView.getUint32(iovsPointer + index * 8, true);\n const length = memoryView.getUint32(iovsPointer + index * 8 + 4, true);\n if (fd === 2) {\n stderr.push(decoder.decode(new Uint8Array(getMemory().buffer, pointer, length)));\n }\n written += length;\n }\n memoryView.setUint32(writtenPointer, written, true);\n return WASI_ERRNO_SUCCESS;\n },\n fd_close: unavailable,\n fd_fdstat_get: unavailable,\n fd_fdstat_set_flags: unavailable,\n fd_read: unavailable,\n fd_seek: unavailable,\n proc_exit: (code: number) => {\n throw new Error(`The code-gauge WebAssembly module exited with code ${code}`);\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"wasmBinding.js","names":[],"sources":["../src/wasmBinding.ts"],"sourcesContent":["import { expectedPayloadVersion, NativeAddonError, type NativeBinding } from './nativeMetrics.js';\n\n/** The C ABI exported by native/src/wasm.rs. */\ninterface WasmExports {\n memory: WebAssembly.Memory;\n payload_version(): number;\n alloc(length: number): number;\n result_ptr(): number;\n result_len(): number;\n measure_code(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n includeSyntaxTree: number,\n minTokens: number,\n maxGapTokens: number,\n minSimilarityPercent: number,\n includeCrossFileData: number\n ): number;\n collect_cross_file_data(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number,\n minTokens: number\n ): number;\n collect_function_token_sequences(\n codePtr: number,\n codeLength: number,\n languagePtr: number,\n languageLength: number\n ): number;\n}\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/**\n * Wraps the WebAssembly build of the native addon (native/src/wasm.rs) as a NativeBinding. The\n * module is instantiated synchronously on first use and again after a trap (a panic or stack\n * overflow), because a trap leaves the instance's memory and stack pointer in an undefined state.\n * An instantiation failure (e.g., a payload version mismatch) is memoized like the N-API loader's,\n * since instantiating the same module again would fail again.\n */\nexport function createWasmBinding(module: WebAssembly.Module): NativeBinding {\n let instance: { exports: WasmExports; stderr: string[] } | undefined;\n let instantiationFailure: unknown;\n\n const call = (invoke: (exports: WasmExports) => number): string => {\n if (!instance) {\n if (instantiationFailure) {\n throw instantiationFailure;\n }\n try {\n instance = instantiate(module);\n } catch (error) {\n instantiationFailure = error;\n throw error;\n }\n }\n const { exports, stderr } = instance;\n stderr.length = 0;\n let status: number;\n try {\n status = invoke(exports);\n } catch (error) {\n instance = undefined;\n throw new Error(`The code-gauge WebAssembly module crashed: ${stderr.join('').trim() || String(error)}`, {\n cause: error,\n });\n }\n const result = decoder.decode(new Uint8Array(exports.memory.buffer, exports.result_ptr(), exports.result_len()));\n if (status !== 0) {\n throw new Error(result);\n }\n return result;\n };\n\n const measureCodeNative: NativeBinding['measureCodeNative'] = (\n code,\n language,\n includeSyntaxTree,\n minTokens,\n maxGapTokens,\n minSimilarityPercent,\n includeCrossFileData\n ) =>\n call((exports) =>\n exports.measure_code(\n ...passString(exports, code),\n ...passString(exports, language),\n Number(includeSyntaxTree),\n toOptionalU32(minTokens),\n toOptionalU32(maxGapTokens),\n toOptionalU32(minSimilarityPercent),\n Number(includeCrossFileData)\n )\n );\n\n return {\n measureCodeNative,\n // The WebAssembly build has no threads, so the asynchronous form measures in place.\n measureCodeNativeAsync: async (...args) => measureCodeNative(...args),\n collectCrossFileDataNative: (code, language, minTokens) =>\n call((exports) =>\n exports.collect_cross_file_data(\n ...passString(exports, code),\n ...passString(exports, language),\n toOptionalU32(minTokens)\n )\n ),\n collectFunctionTokenSequencesNative: (code, language) =>\n call((exports) =>\n exports.collect_function_token_sequences(...passString(exports, code), ...passString(exports, language))\n ),\n };\n}\n\nfunction instantiate(module: WebAssembly.Module): { exports: WasmExports; stderr: string[] } {\n const stderr: string[] = [];\n let memory: WebAssembly.Memory | undefined;\n const instance = new WebAssembly.Instance(module, {\n wasi_snapshot_preview1: createWasiImports(() => memory as WebAssembly.Memory, stderr),\n });\n const exports = instance.exports as unknown as WasmExports;\n memory = exports.memory;\n const version = exports.payload_version();\n if (version !== expectedPayloadVersion) {\n throw new NativeAddonError(\n `The code-gauge WebAssembly module has payload version ${version}, but ${expectedPayloadVersion} is ` +\n 'expected; reinstall code-gauge, or in a code-gauge repository checkout, rebuild it with `bun run build-wasm`'\n );\n }\n return { exports, stderr };\n}\n\n/** Copies a string into a buffer whose ownership passes to the called export. */\nfunction passString(exports: WasmExports, text: string): [number, number] {\n // TextEncoder replaces lone surrogates with U+FFFD, like toWellFormed() does for the N-API addon.\n const bytes = encoder.encode(text);\n const pointer = exports.alloc(bytes.length);\n new Uint8Array(exports.memory.buffer, pointer, bytes.length).set(bytes);\n return [pointer, bytes.length];\n}\n\n/** native/src/wasm.rs reads a negative value as an absent setting. */\nfunction toOptionalU32(value: number | undefined): number {\n return value ?? -1;\n}\n\nconst WASI_ERRNO_SUCCESS = 0;\nconst WASI_ERRNO_BADF = 8;\n// crypto.getRandomValues() rejects requests larger than this.\nconst MAX_RANDOM_BYTES = 65_536;\n\n/**\n * The WASI preview 1 functions the module imports. The metrics code performs no I/O, so file\n * descriptors are unavailable except for writes, whose stderr output (e.g., a panic message) is\n * kept for the error raised when the module traps.\n */\nfunction createWasiImports(\n getMemory: () => WebAssembly.Memory,\n stderr: string[]\n): Record<string, (...args: never[]) => number> {\n const view = (): DataView => new DataView(getMemory().buffer);\n const unavailable = (): number => WASI_ERRNO_BADF;\n return {\n environ_get: () => WASI_ERRNO_SUCCESS,\n environ_sizes_get: (countPointer: number, sizePointer: number) => {\n view().setUint32(countPointer, 0, true);\n view().setUint32(sizePointer, 0, true);\n return WASI_ERRNO_SUCCESS;\n },\n clock_time_get: (_clockId: number, _precision: bigint, timePointer: number) => {\n view().setBigUint64(timePointer, BigInt(Date.now()) * 1_000_000n, true);\n return WASI_ERRNO_SUCCESS;\n },\n random_get: (pointer: number, length: number) => {\n for (let offset = 0; offset < length; offset += MAX_RANDOM_BYTES) {\n crypto.getRandomValues(\n new Uint8Array(getMemory().buffer, pointer + offset, Math.min(MAX_RANDOM_BYTES, length - offset))\n );\n }\n return WASI_ERRNO_SUCCESS;\n },\n fd_write: (fd: number, iovsPointer: number, iovsLength: number, writtenPointer: number) => {\n const memoryView = view();\n let written = 0;\n for (let index = 0; index < iovsLength; index++) {\n const pointer = memoryView.getUint32(iovsPointer + index * 8, true);\n const length = memoryView.getUint32(iovsPointer + index * 8 + 4, true);\n if (fd === 2) {\n stderr.push(decoder.decode(new Uint8Array(getMemory().buffer, pointer, length)));\n }\n written += length;\n }\n memoryView.setUint32(writtenPointer, written, true);\n return WASI_ERRNO_SUCCESS;\n },\n fd_close: unavailable,\n fd_fdstat_get: unavailable,\n fd_fdstat_set_flags: unavailable,\n fd_read: unavailable,\n fd_seek: unavailable,\n proc_exit: (code: number) => {\n throw new Error(`The code-gauge WebAssembly module exited with code ${code}`);\n },\n };\n}\n"],"mappings":"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"}
package/native/Cargo.lock CHANGED
@@ -19,9 +19,13 @@ checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
19
19
 
20
20
  [[package]]
21
21
  name = "cc"
22
- version = "1.0.106"
22
+ version = "1.4.7"
23
23
  source = "registry+https://github.com/rust-lang/crates.io-index"
24
- checksum = "066fce287b1d4eafef758e89e09d724a24808a9196fe9756b8ca90e86d0719a2"
24
+ checksum = "54413ede23c2daf518f35156dfde027feb2374004d63bd497f983c8db9c0e313"
25
+ dependencies = [
26
+ "find-msvc-tools",
27
+ "shlex",
28
+ ]
25
29
 
26
30
  [[package]]
27
31
  name = "cfg-if"
@@ -38,6 +42,7 @@ dependencies = [
38
42
  "napi-build",
39
43
  "napi-derive",
40
44
  "regex",
45
+ "rustc-hash",
41
46
  "serde",
42
47
  "serde_json",
43
48
  "tree-sitter",
@@ -47,11 +52,11 @@ dependencies = [
47
52
  "tree-sitter-go",
48
53
  "tree-sitter-java",
49
54
  "tree-sitter-javascript",
50
- "tree-sitter-kotlin",
51
55
  "tree-sitter-python",
52
56
  "tree-sitter-ruby",
53
57
  "tree-sitter-rust",
54
58
  "tree-sitter-typescript",
59
+ "willbooster-tree-sitter-kotlin",
55
60
  ]
56
61
 
57
62
  [[package]]
@@ -75,6 +80,12 @@ version = "1.0.2"
75
80
  source = "registry+https://github.com/rust-lang/crates.io-index"
76
81
  checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
77
82
 
83
+ [[package]]
84
+ name = "find-msvc-tools"
85
+ version = "0.1.13"
86
+ source = "registry+https://github.com/rust-lang/crates.io-index"
87
+ checksum = "ef25905e51abafe4dcea6c15fec58c57b601cdbd0ee53d22ea1d3016c587d39b"
88
+
78
89
  [[package]]
79
90
  name = "futures"
80
91
  version = "0.3.33"
@@ -365,6 +376,7 @@ version = "1.0.150"
365
376
  source = "registry+https://github.com/rust-lang/crates.io-index"
366
377
  checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
367
378
  dependencies = [
379
+ "indexmap",
368
380
  "itoa",
369
381
  "memchr",
370
382
  "serde",
@@ -372,12 +384,24 @@ dependencies = [
372
384
  "zmij",
373
385
  ]
374
386
 
387
+ [[package]]
388
+ name = "shlex"
389
+ version = "2.0.1"
390
+ source = "registry+https://github.com/rust-lang/crates.io-index"
391
+ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
392
+
375
393
  [[package]]
376
394
  name = "slab"
377
395
  version = "0.4.12"
378
396
  source = "registry+https://github.com/rust-lang/crates.io-index"
379
397
  checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
380
398
 
399
+ [[package]]
400
+ name = "streaming-iterator"
401
+ version = "0.1.9"
402
+ source = "registry+https://github.com/rust-lang/crates.io-index"
403
+ checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"
404
+
381
405
  [[package]]
382
406
  name = "syn"
383
407
  version = "2.0.119"
@@ -402,12 +426,16 @@ dependencies = [
402
426
 
403
427
  [[package]]
404
428
  name = "tree-sitter"
405
- version = "0.22.6"
429
+ version = "0.25.10"
406
430
  source = "registry+https://github.com/rust-lang/crates.io-index"
407
- checksum = "df7cc499ceadd4dcdf7ec6d4cbc34ece92c3fa07821e287aedecd4416c516dca"
431
+ checksum = "78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87"
408
432
  dependencies = [
409
433
  "cc",
410
434
  "regex",
435
+ "regex-syntax",
436
+ "serde_json",
437
+ "streaming-iterator",
438
+ "tree-sitter-language",
411
439
  ]
412
440
 
413
441
  [[package]]
@@ -462,23 +490,19 @@ dependencies = [
462
490
 
463
491
  [[package]]
464
492
  name = "tree-sitter-javascript"
465
- version = "0.21.4"
493
+ version = "0.25.0"
466
494
  source = "registry+https://github.com/rust-lang/crates.io-index"
467
- checksum = "8710a71bc6779e33811a8067bdda3ed08bed1733296ff915e44faf60f8c533d7"
495
+ checksum = "68204f2abc0627a90bdf06e605f5c470aa26fdcb2081ea553a04bdad756693f5"
468
496
  dependencies = [
469
497
  "cc",
470
- "tree-sitter",
498
+ "tree-sitter-language",
471
499
  ]
472
500
 
473
501
  [[package]]
474
- name = "tree-sitter-kotlin"
475
- version = "0.3.8"
502
+ name = "tree-sitter-language"
503
+ version = "0.1.8"
476
504
  source = "registry+https://github.com/rust-lang/crates.io-index"
477
- checksum = "54ff60aeb036f5762515ceb31404512ea4f9599764bcd3857074bb82867bdd34"
478
- dependencies = [
479
- "cc",
480
- "tree-sitter",
481
- ]
505
+ checksum = "ca0d1bf6fdd806e43ae5198f82f527056d359def39e54e67a0f478ac09dac081"
482
506
 
483
507
  [[package]]
484
508
  name = "tree-sitter-python"
@@ -532,6 +556,15 @@ version = "1.13.3"
532
556
  source = "registry+https://github.com/rust-lang/crates.io-index"
533
557
  checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8"
534
558
 
559
+ [[package]]
560
+ name = "willbooster-tree-sitter-kotlin"
561
+ version = "0.0.0"
562
+ source = "git+https://github.com/WillBooster/tree-sitter-kotlin?tag=v1.1.0#a05912e6f07e2cedd44bfb117940361089d4c3e3"
563
+ dependencies = [
564
+ "cc",
565
+ "tree-sitter-language",
566
+ ]
567
+
535
568
  [[package]]
536
569
  name = "windows-link"
537
570
  version = "0.2.1"
package/native/Cargo.toml CHANGED
@@ -13,22 +13,23 @@ serde = { version = "1", features = ["derive"] }
13
13
  serde_json = "1"
14
14
  indexmap = "2"
15
15
  regex = "1"
16
+ rustc-hash = "2"
16
17
 
17
18
  # Grammar crates are pinned exactly: every metric (and the golden-based test suite) is calibrated
18
- # against these grammar versions, so upgrades are deliberate, test-verified changes. The versions
19
- # match the npm grammar packages the former node-tree-sitter backend used, keeping historical
20
- # outputs stable. Core 0.22.6 parses identically to node-tree-sitter 0.21.1's vendored core
21
- # (0.21.0 does not: it lacks several parser fixes and can abort on malformed input); its one
22
- # behavioral difference — extra (error-recovery) children no longer inherit fields in
23
- # ts_node_field_name_for_child — is compensated in util::find_children_by_field_name.
24
- tree-sitter = "=0.22.6"
19
+ # against these grammar versions, so upgrades are deliberate, test-verified changes. The Kotlin
20
+ # grammar is WillBooster's fork, which is not on crates.io, pinned to a release tag. Core 0.25 is
21
+ # the first to load that grammar's ABI 15 parser, and tree-sitter-javascript 0.21.x pins
22
+ # `cc ~1.0`, which conflicts with the core's `cc ^1.2`, hence 0.25.0. The core reports no field for
23
+ # extra (error-recovery) children in ts_node_field_name_for_child, which
24
+ # util::find_children_by_field_name compensates for.
25
+ tree-sitter = "=0.25.10"
25
26
  tree-sitter-c = "=0.21.4"
26
27
  tree-sitter-c-sharp = "=0.21.3"
27
28
  tree-sitter-cpp = "=0.22.3"
28
29
  tree-sitter-go = "=0.21.2"
29
30
  tree-sitter-java = "=0.21.0"
30
- tree-sitter-kotlin = "=0.3.8"
31
- tree-sitter-javascript = "=0.21.4"
31
+ tree-sitter-kotlin = { package = "willbooster-tree-sitter-kotlin", git = "https://github.com/WillBooster/tree-sitter-kotlin", tag = "v1.1.0" }
32
+ tree-sitter-javascript = "=0.25.0"
32
33
  tree-sitter-python = "=0.21.0"
33
34
  tree-sitter-ruby = "=0.21.0"
34
35
  # 0.21.0 breaks MSVC (its build script passes the GCC-only -Wno-unused-parameter
@@ -39,7 +40,7 @@ tree-sitter-typescript = "=0.21.2"
39
40
 
40
41
  # The WebAssembly build (src/wasm.rs) exports a plain C ABI instead of N-API.
41
42
  [target.'cfg(not(target_family = "wasm"))'.dependencies]
42
- napi = { version = "3", default-features = false }
43
+ napi = { version = "3", default-features = false, features = ["napi4"] }
43
44
  napi-derive = "3"
44
45
 
45
46
  [build-dependencies]
Binary file