Repository: software-mansion/TypeGPU (ts)

Issue:
fix: Unplugin hoisting error
Currently, rollup unplugin throws if I define tests like these:

```typescript
it('names function expression', () => {
  const myFun = function () {
    'kernel & js';
    return 0;
  };

  const myGpuFun = tgpu['~unstable'].fn([], d.u32)(myFun);

  expect(getName(myFun)).toBe('myFun');
  expect(getName(myGpuFun)).toBe('myGpuFun');
});

it('names function definition', () => {
  function myFun() {
    'kernel & js';
    return 0;
  }

  const myGpuFun = tgpu['~unstable'].fn([], d.u32)(myFun);

  expect(getName(myFun)).toBe('myFun');
  expect(getName(myGpuFun)).toBe('myGpuFun');
});
```

`function "myFun", containing kernel & js directive, is referenced before its usage. Function statements are no longer hoisted after being transformed by the plugin.`

This is because we search using a regex, without regard for context names.

One possible solution to the problem is to just replace the throw with a warn. 
It is also worth noting, that babel version of the plugin does not detect this as of right now.

Pull request:
fix: Replace unplugin hoisting error with a warning
closes #1353 

Patch:
diff --git a/packages/unplugin-typegpu/src/index.ts b/packages/unplugin-typegpu/src/index.ts
index 4fedd068..b7afa8d1 100644
--- a/packages/unplugin-typegpu/src/index.ts
+++ b/packages/unplugin-typegpu/src/index.ts
@@ -153,10 +153,10 @@ const typegpu: UnpluginInstance<Options, false> = createUnplugin(
                   .slice(0, def.start)
                   .search(new RegExp(`(?<![\\w_.])${name}(?![\\w_])`)) !== -1
             ) {
-              throw new Error(
+              console.warn(
                 `File ${id}: function "${name}", containing ${
                   removeJsImplementation ? 'kernel' : 'kernel & js'
-                } directive, is referenced before its usage. Function statements are no longer hoisted after being transformed by the plugin.`,
+                } directive, might have been referenced before its usage. Function statements are no longer hoisted after being transformed by the plugin.`,
               );
             }
 


Test patch:
diff --git a/packages/unplugin-typegpu/test/kernel-and-js-directive.test.ts b/packages/unplugin-typegpu/test/kernel-and-js-directive.test.ts
index 9cd122e5..8919ac36 100644
--- a/packages/unplugin-typegpu/test/kernel-and-js-directive.test.ts
+++ b/packages/unplugin-typegpu/test/kernel-and-js-directive.test.ts
@@ -1,4 +1,4 @@
-import { describe, expect, it } from 'vitest';
+import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
 import { babelTransform, rollupTransform } from './transform.ts';
 
 describe('[BABEL] "kernel & js" directive', () => {
@@ -229,6 +229,16 @@ describe('[BABEL] "kernel & js" directive', () => {
 });
 
 describe('[ROLLUP] "kernel & js" directive', () => {
+  let consoleWarnSpy: ReturnType<typeof vi.spyOn>;
+
+  beforeEach(() => {
+    consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
+  });
+
+  afterEach(() => {
+    consoleWarnSpy.mockRestore();
+  });
+
   it('makes plugin transpile marked arrow functions', async () => {
     const code = `\
       import tgpu from 'typegpu';
@@ -469,11 +479,10 @@ describe('[ROLLUP] "kernel & js" directive', () => {
       };
     `;
 
-    expect(rollupTransform(code))
-      .rejects
-      .toThrowErrorMatchingInlineSnapshot(
-        `[Error: File virtual:code: function "add", containing kernel & js directive, is referenced before its usage. Function statements are no longer hoisted after being transformed by the plugin.]`,
-      );
+    await rollupTransform(code);
+    expect(consoleWarnSpy).toHaveBeenCalledWith(
+      `File virtual:code: function "add", containing kernel & js directive, might have been referenced before its usage. Function statements are no longer hoisted after being transformed by the plugin.`,
+    );
   });
 
   it('parses when no typegpu import', async () => {