1
1
import type * as smol from 'tinyest' ;
2
2
import * as d from '../data' ;
3
+ import type { AnyData } from '../data/dataTypes' ;
3
4
import { abstractInt } from '../data/numeric.js' ;
4
5
import * as wgsl from '../data/wgslTypes.js' ;
5
6
import {
6
7
type ResolutionCtx ,
7
8
type Resource ,
8
9
UnknownData ,
9
- type Wgsl ,
10
+ isMarkedInternal ,
10
11
isWgsl ,
11
12
} from '../types.js' ;
12
13
import {
@@ -46,8 +47,8 @@ type Operator =
46
47
| smol . UnaryOperator ;
47
48
48
49
function operatorToType <
49
- TL extends wgsl . AnyWgslData | UnknownData ,
50
- TR extends wgsl . AnyWgslData | UnknownData ,
50
+ TL extends AnyData | UnknownData ,
51
+ TR extends AnyData | UnknownData ,
51
52
> ( lhs : TL , op : Operator , rhs ?: TR ) : TL | TR | wgsl . Bool {
52
53
if ( ! rhs ) {
53
54
if ( op === '!' || op === '~' ) {
@@ -190,7 +191,9 @@ export function generateExpression(
190
191
if ( typeof target . value === 'string' ) {
191
192
return {
192
193
value : `${ target . value } .${ property } ` ,
193
- dataType : getTypeForPropAccess ( target . dataType as Wgsl , property ) ,
194
+ dataType : d . isData ( target . dataType )
195
+ ? getTypeForPropAccess ( target . dataType , property )
196
+ : UnknownData ,
194
197
} ;
195
198
}
196
199
@@ -214,10 +217,24 @@ export function generateExpression(
214
217
// biome-ignore lint/suspicious/noExplicitAny: <sorry TypeScript>
215
218
const propValue = ( target . value as any ) [ property ] ;
216
219
220
+ if ( target . dataType . type !== 'unknown' ) {
221
+ if ( wgsl . isMat ( target . dataType ) && property === 'columns' ) {
222
+ return {
223
+ value : target . value ,
224
+ dataType : target . dataType ,
225
+ } ;
226
+ }
227
+
228
+ return {
229
+ value : propValue ,
230
+ dataType : getTypeForPropAccess ( target . dataType , property ) ,
231
+ } ;
232
+ }
233
+
217
234
if ( isWgsl ( target . value ) ) {
218
235
return {
219
236
value : propValue ,
220
- dataType : getTypeForPropAccess ( target . value as d . AnyWgslData , property ) ,
237
+ dataType : getTypeForPropAccess ( target . value , property ) ,
221
238
} ;
222
239
}
223
240
@@ -245,7 +262,9 @@ export function generateExpression(
245
262
246
263
return {
247
264
value : `${ targetStr } [${ propertyStr } ]` ,
248
- dataType : getTypeForIndexAccess ( targetExpr . dataType as d . AnyWgslData ) ,
265
+ dataType : d . isData ( targetExpr . dataType )
266
+ ? getTypeForIndexAccess ( targetExpr . dataType )
267
+ : UnknownData ,
249
268
} ;
250
269
}
251
270
@@ -291,10 +310,21 @@ export function generateExpression(
291
310
} ;
292
311
}
293
312
313
+ if ( ! isMarkedInternal ( idValue ) ) {
314
+ throw new Error (
315
+ `Function ${ String ( idValue ) } has not been created using TypeGPU APIs. Did you mean to wrap the function with tgpu.fn(args, return)(...) ?` ,
316
+ ) ;
317
+ }
318
+
294
319
// Assuming that `id` is callable
295
- return ( idValue as unknown as ( ...args : unknown [ ] ) => unknown ) (
320
+ const fnRes = ( idValue as unknown as ( ...args : unknown [ ] ) => unknown ) (
296
321
...resolvedResources ,
297
322
) as Resource ;
323
+
324
+ return {
325
+ value : resolveRes ( ctx , fnRes ) ,
326
+ dataType : fnRes . dataType ,
327
+ } ;
298
328
}
299
329
300
330
if ( 'o' in expression ) {
@@ -369,7 +399,7 @@ export function generateExpression(
369
399
370
400
return {
371
401
value : `${ arrayType } ( ${ arrayValues . join ( ', ' ) } )` ,
372
- dataType : d . arrayOf ( type as d . AnyWgslData , values . length ) ,
402
+ dataType : d . arrayOf ( type , values . length ) as d . AnyWgslData ,
373
403
} ;
374
404
}
375
405
@@ -449,6 +479,10 @@ ${alternate}`;
449
479
throw new Error ( 'Cannot create variable without an initial value.' ) ;
450
480
}
451
481
482
+ if ( d . isLooseData ( eq . dataType ) ) {
483
+ throw new Error ( 'Cannot create variable with loose data type.' ) ;
484
+ }
485
+
452
486
registerBlockVariable ( ctx , rawId , eq . dataType ) ;
453
487
const id = resolveRes ( ctx , generateIdentifier ( ctx , rawId ) ) ;
454
488
0 commit comments