gofront 1.3.5 → 1.3.7

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.
@@ -185,12 +185,55 @@ export class TypeChecker {
185
185
  }
186
186
  }
187
187
  }
188
+ const all = [];
188
189
  for (const p of programs) {
189
- this._setCurrentFile(p);
190
- for (const d of p.decls) if (d.kind === "TypeDecl") this.collectType(d);
190
+ for (const d of p.decls) if (d.kind === "TypeDecl") all.push({ p, d });
191
+ }
192
+ // Collect in dependency order so aliases, generics, embedded and by-value
193
+ // field types declared later (or in other files) are ready when needed.
194
+ let pending = all;
195
+ while (pending.length > 0) {
196
+ const pendingNames = new Map(pending.map((x) => [x.d.name, x.d]));
197
+ const ready = pending.filter(
198
+ (x) => !this._typeDeclBlocked(x.d, pendingNames),
199
+ );
200
+ const batch = ready.length > 0 ? ready : pending;
201
+ for (const { p, d } of batch) {
202
+ this._setCurrentFile(p);
203
+ this.collectType(d);
204
+ }
205
+ pending =
206
+ ready.length > 0 ? pending.filter((x) => !ready.includes(x)) : [];
191
207
  }
192
208
  }
193
209
 
210
+ _typeDeclBlocked(decl, pendingNames) {
211
+ const visit = (node, indirect) => {
212
+ if (!node || typeof node !== "object") return false;
213
+ if (Array.isArray(node)) return node.some((n) => visit(n, indirect));
214
+ if (
215
+ (node.kind === "TypeName" || node.kind === "GenericTypeName") &&
216
+ node.name !== decl.name
217
+ ) {
218
+ const dep = pendingNames.get(node.name);
219
+ if (dep && (!indirect || dep.isAlias || dep.typeParams)) return true;
220
+ }
221
+ const nextIndirect =
222
+ indirect ||
223
+ [
224
+ "PointerType",
225
+ "SliceType",
226
+ "MapType",
227
+ "FuncType",
228
+ "ChanType",
229
+ ].includes(node.kind);
230
+ return Object.keys(node).some(
231
+ (k) => !k.startsWith("_") && visit(node[k], nextIndirect),
232
+ );
233
+ };
234
+ return visit(decl.type, false);
235
+ }
236
+
194
237
  _collectFuncsPass(programs) {
195
238
  for (const p of programs) {
196
239
  this._setCurrentFile(p);
@@ -390,6 +433,7 @@ export class TypeChecker {
390
433
  }
391
434
 
392
435
  _attachMethod(decl, funcType) {
436
+ funcType._ptrRecv = Boolean(decl.recvPointer);
393
437
  const recvNamedType = this.types.get(decl.recvType.name);
394
438
  if (recvNamedType?._generic)
395
439
  this._attachGenericMethod(recvNamedType, decl, funcType);
@@ -461,7 +505,10 @@ export class TypeChecker {
461
505
  const recvNamedType = this.types.get(recvTypeName);
462
506
  this._injectGenericReceiverTypeParams(inner, recvNamedType);
463
507
  const recvType = this.resolveTypeNodeName(decl.recvType, outer);
464
- inner.define(decl.recvName, recvType);
508
+ inner.define(
509
+ decl.recvName,
510
+ decl.recvPointer ? { kind: "pointer", base: recvType } : recvType,
511
+ );
465
512
  for (const p of decl.params) {
466
513
  inner.define(p.name, this.resolveTypeNode(p.type, inner));
467
514
  }
@@ -411,6 +411,8 @@ export const resolveMethods = {
411
411
  _fieldTypeInterface(base, baseType, field, node) {
412
412
  if (base.methods?.has(field)) return base.methods.get(field);
413
413
  if (base.fields?.has(field)) return base.fields.get(field);
414
+ if (base._excluded?.has(field))
415
+ return this.err(`No member '${field}' on ${typeStr(baseType)}`, node);
414
416
  if (base._isOpen) return ANY;
415
417
  return this.err(`No method '${field}' on ${typeStr(baseType)}`, node);
416
418
  },
@@ -148,8 +148,17 @@ export const statementCheckMethods = {
148
148
  for (let i = 0; i < lhsTypes.length; i++) {
149
149
  if (stmt.lhs[i]?.kind === "Ident" && stmt.lhs[i]?.name === "_") continue;
150
150
  const r = rhsFlat[i] ?? ANY;
151
- if (!isAny(lhsTypes[i]) && !isAny(r))
151
+ if (stmt.rhs.length === lhsTypes.length && lhsTypes[i] && r)
152
+ this._markIfaceBox(
153
+ this.resolveType(lhsTypes[i]),
154
+ this.resolveType(r),
155
+ stmt.rhs[i],
156
+ );
157
+ if (!isAny(lhsTypes[i]) && !isAny(r)) {
158
+ this._skipIfaceMark = true;
152
159
  this.assertAssignable(lhsTypes[i], r, stmt.lhs[i]);
160
+ this._skipIfaceMark = false;
161
+ }
153
162
  }
154
163
  },
155
164
 
@@ -23,6 +23,25 @@ const func = (params, returns = [VOID], variadic = false) => ({
23
23
  variadic,
24
24
  });
25
25
 
26
+ // Last parameter is optional (modelled as variadic).
27
+ const optLast = (params, returns = [VOID]) => func(params, returns, true);
28
+
29
+ const WEBGL2_ONLY_CONSTANTS = new Set([
30
+ "UNIFORM_BUFFER",
31
+ "HALF_FLOAT",
32
+ "RGBA8",
33
+ "RGBA32F",
34
+ ]);
35
+
36
+ const WEBGL2_ONLY_METHODS = new Set([
37
+ "VertexAttribIPointer",
38
+ "DrawArraysInstanced",
39
+ "DrawElementsInstanced",
40
+ "CreateVertexArray",
41
+ "BindVertexArray",
42
+ "DeleteVertexArray",
43
+ ]);
44
+
26
45
  const WEBGL_CONSTANTS_LIST = {
27
46
  ARRAY_BUFFER: 0x8892,
28
47
  ELEMENT_ARRAY_BUFFER: 0x8893,
@@ -113,7 +132,7 @@ function buildArrayBufferType() {
113
132
  methods,
114
133
  };
115
134
  named.underlying = iface;
116
- methods.set("slice", func([INT, INT], [named]));
135
+ methods.set("slice", optLast([INT, INT], [named]));
117
136
  return named;
118
137
  }
119
138
 
@@ -126,20 +145,20 @@ function buildDataViewType(arrayBufferType) {
126
145
  const methods = new Map([
127
146
  ["getInt8", func([INT], [INT8])],
128
147
  ["getUint8", func([INT], [UINT8])],
129
- ["getInt16", func([INT, BOOL], [INT16])],
130
- ["getUint16", func([INT, BOOL], [UINT16])],
131
- ["getInt32", func([INT, BOOL], [INT32])],
132
- ["getUint32", func([INT, BOOL], [UINT32])],
133
- ["getFloat32", func([INT, BOOL], [FLOAT32])],
134
- ["getFloat64", func([INT, BOOL], [FLOAT64])],
148
+ ["getInt16", optLast([INT, BOOL], [INT16])],
149
+ ["getUint16", optLast([INT, BOOL], [UINT16])],
150
+ ["getInt32", optLast([INT, BOOL], [INT32])],
151
+ ["getUint32", optLast([INT, BOOL], [UINT32])],
152
+ ["getFloat32", optLast([INT, BOOL], [FLOAT32])],
153
+ ["getFloat64", optLast([INT, BOOL], [FLOAT64])],
135
154
  ["setInt8", func([INT, INT8])],
136
155
  ["setUint8", func([INT, UINT8])],
137
- ["setInt16", func([INT, INT16, BOOL])],
138
- ["setUint16", func([INT, UINT16, BOOL])],
139
- ["setInt32", func([INT, INT32, BOOL])],
140
- ["setUint32", func([INT, UINT32, BOOL])],
141
- ["setFloat32", func([INT, FLOAT32, BOOL])],
142
- ["setFloat64", func([INT, FLOAT64, BOOL])],
156
+ ["setInt16", optLast([INT, INT16, BOOL])],
157
+ ["setUint16", optLast([INT, UINT16, BOOL])],
158
+ ["setInt32", optLast([INT, INT32, BOOL])],
159
+ ["setUint32", optLast([INT, UINT32, BOOL])],
160
+ ["setFloat32", optLast([INT, FLOAT32, BOOL])],
161
+ ["setFloat64", optLast([INT, FLOAT64, BOOL])],
143
162
  ]);
144
163
  const named = { kind: "named", name: "DataView", underlying: null };
145
164
  named.underlying = { kind: "interface", name: "DataView", fields, methods };
@@ -164,15 +183,16 @@ function buildTypedArrayType(name, elemType, arrayBufferType) {
164
183
  _isTypedArray: true,
165
184
  };
166
185
  named.underlying = iface;
167
- methods.set("subarray", func([INT, INT], [named]));
168
- methods.set("slice", func([INT, INT], [named]));
169
- methods.set("set", func([ANY, INT], [VOID]));
186
+ methods.set("subarray", optLast([INT, INT], [named]));
187
+ methods.set("slice", optLast([INT, INT], [named]));
188
+ methods.set("set", optLast([ANY, INT], [VOID]));
170
189
  return named;
171
190
  }
172
191
 
173
- function createWebGLMethods() {
192
+ function createWebGLMethods(isWebGL2) {
174
193
  const methods = new Map();
175
194
  const add = (name, fn) => {
195
+ if (!isWebGL2 && WEBGL2_ONLY_METHODS.has(name)) return;
176
196
  methods.set(name, fn);
177
197
  const camel = name[0].toLowerCase() + name.slice(1);
178
198
  if (camel !== name) methods.set(camel, fn);
@@ -296,7 +316,7 @@ function createWebGPUMethods() {
296
316
  addDev("CreateShaderModule", func([ANY], [ANY]));
297
317
  addDev("CreateRenderPipeline", func([ANY], [ANY]));
298
318
  addDev("CreateComputePipeline", func([ANY], [ANY]));
299
- addDev("CreateCommandEncoder", func([ANY], [ANY]));
319
+ addDev("CreateCommandEncoder", optLast([ANY], [ANY]));
300
320
  addDev("CreateBindGroup", func([ANY], [ANY]));
301
321
  addDev("CreateBindGroupLayout", func([ANY], [ANY]));
302
322
  addDev("CreatePipelineLayout", func([ANY], [ANY]));
@@ -307,7 +327,7 @@ function createWebGPUMethods() {
307
327
  const camel = name[0].toLowerCase() + name.slice(1);
308
328
  if (camel !== name) adapterMethods.set(camel, fn);
309
329
  };
310
- addAdapt("RequestDevice", func([ANY], [ANY]));
330
+ addAdapt("RequestDevice", optLast([ANY], [ANY]));
311
331
 
312
332
  return { queueMethods, deviceMethods, adapterMethods };
313
333
  }
@@ -339,21 +359,29 @@ export function setupWebGlobals(globals, types) {
339
359
  }
340
360
 
341
361
  // WebGL constants map
342
- const constFields = new Map();
362
+ const constFields2 = new Map();
343
363
  for (const [k] of Object.entries(WEBGL_CONSTANTS_LIST)) {
344
- constFields.set(k, INT);
364
+ constFields2.set(k, INT);
365
+ }
366
+ const constFields1 = new Map(
367
+ [...constFields2].filter(([k]) => !WEBGL2_ONLY_CONSTANTS.has(k)),
368
+ );
369
+ const webgl2Only = new Set(WEBGL2_ONLY_CONSTANTS);
370
+ for (const m of WEBGL2_ONLY_METHODS) {
371
+ webgl2Only.add(m);
372
+ webgl2Only.add(m[0].toLowerCase() + m.slice(1));
345
373
  }
346
374
 
347
- const webglMethods = createWebGLMethods();
348
375
  const webglContext = {
349
376
  kind: "named",
350
377
  name: "WebGLRenderingContext",
351
378
  underlying: {
352
379
  kind: "interface",
353
380
  name: "WebGLRenderingContext",
354
- fields: constFields,
355
- methods: webglMethods,
381
+ fields: constFields1,
382
+ methods: createWebGLMethods(false),
356
383
  _isOpen: true,
384
+ _excluded: webgl2Only,
357
385
  },
358
386
  };
359
387
  const webgl2Context = {
@@ -362,8 +390,8 @@ export function setupWebGlobals(globals, types) {
362
390
  underlying: {
363
391
  kind: "interface",
364
392
  name: "WebGL2RenderingContext",
365
- fields: constFields,
366
- methods: webglMethods,
393
+ fields: constFields2,
394
+ methods: createWebGLMethods(true),
367
395
  _isOpen: true,
368
396
  },
369
397
  };
@@ -55,7 +55,7 @@ export const UINT16 = { kind: "basic", name: "uint16" };
55
55
  export const UINT32 = { kind: "basic", name: "uint32" };
56
56
  export const UINT64 = { kind: "basic", name: "uint64" };
57
57
  export const UINTPTR = { kind: "basic", name: "uintptr" };
58
- export const RUNE = INT;
58
+ export const RUNE = INT32;
59
59
  export const FLOAT32 = { kind: "basic", name: "float32" };
60
60
  export const FLOAT64 = { kind: "basic", name: "float64" };
61
61
  export const STRING = { kind: "basic", name: "string" };
@@ -149,9 +149,9 @@ export const isString = makeBasicPredicate("string");
149
149
  export const isBool = makeBasicPredicate("bool");
150
150
 
151
151
  // ── TypedArray mappings ──────────────────────────────────────
152
+ // []float64 deliberately stays a plain Array for JSON / JS-library interop.
152
153
  export const TYPED_ARRAY_CONSTRUCTORS = {
153
154
  float32: "Float32Array",
154
- float64: "Float64Array",
155
155
  uint8: "Uint8Array",
156
156
  byte: "Uint8Array",
157
157
  int8: "Int8Array",
@@ -159,6 +159,7 @@ export const TYPED_ARRAY_CONSTRUCTORS = {
159
159
  int16: "Int16Array",
160
160
  uint32: "Uint32Array",
161
161
  int32: "Int32Array",
162
+ rune: "Int32Array",
162
163
  };
163
164
 
164
165
  export function typedArrayConstructorForElem(elemType) {
package/src/vendor.js CHANGED
@@ -227,9 +227,12 @@ export async function loadNodePolyfillsPlugin(projectRoot, customPlugin) {
227
227
  if (!info) return null;
228
228
  try {
229
229
  const mod = await import(pathToFileURL(info.path).href);
230
- const fn =
231
- mod.nodePolyfills || mod.default?.nodePolyfills || mod.default || mod;
232
- return typeof fn === "function" ? fn() : mod;
230
+ const fn = [
231
+ mod.nodePolyfills,
232
+ mod.default?.nodePolyfills,
233
+ mod.default,
234
+ ].find((f) => typeof f === "function");
235
+ return fn ? fn() : null;
233
236
  } catch {
234
237
  return null;
235
238
  }
@@ -339,10 +342,12 @@ export async function bundleVendor(projectDir = ".", options = {}) {
339
342
  options.nodePolyfillsPlugin ??
340
343
  bundlerInfo.nodePolyfillsPlugin ??
341
344
  (options.nodePolyfills === false ? null : undefined);
342
- const polyfillPlugin = await loadNodePolyfillsPlugin(
343
- projectRoot,
344
- customPlugin,
345
- );
345
+ // The polyfill plugin is a Rolldown plugin; esbuild cannot use it.
346
+ const supportsPlugins =
347
+ typeof bundlerInfo.bundle === "function" || bundlerInfo.name === "rolldown";
348
+ const polyfillPlugin = supportsPlugins
349
+ ? await loadNodePolyfillsPlugin(projectRoot, customPlugin)
350
+ : null;
346
351
 
347
352
  if (typeof bundlerInfo.bundle === "function") {
348
353
  try {