@@ -156,21 +156,19 @@ export function minify(
156156 return null
157157 }
158158
159- const prefixes : ( string | null ) [ ] = [ ]
160-
161- function getPrefix ( ) : string | null {
162- if ( prefixes . length > 0 && prefixes . at ( - 1 ) ) {
163- return prefixes . join ( '.' )
164- }
165-
166- return null
167- }
159+ const typeScopes = new Map < string , Scope > ( )
160+ const types : ( string | null ) [ ] = [ ]
168161
169162 function getScopedName ( name : string ) : string | null {
170163 if ( mangleMap . has ( name ) ) {
171164 return mangleMap . get ( name ) !
172165 }
173166
167+ if ( types [ 0 ] != null && typeScopes . has ( types [ 0 ] ) ) {
168+ const renamed = typeScopes . get ( types [ 0 ] ) ! . values . get ( name )
169+ if ( renamed ) return renamed
170+ }
171+
174172 for ( let i = scopes . length - 1 ; i >= 0 ; i -- ) {
175173 const renamed = scopes [ i ] . values . get ( name )
176174 if ( renamed ) return renamed
@@ -200,7 +198,10 @@ export function minify(
200198 }
201199
202200 scopes . at ( - 1 ) ! . values . set ( name , renamed )
203- if ( isExternal ) mangleMap . set ( name , renamed )
201+ if ( isExternal ) {
202+ if ( types [ 0 ] != null ) mangleMap . set ( types [ 0 ] + '.' + name , renamed )
203+ else mangleMap . set ( name , renamed )
204+ }
204205
205206 return renamed
206207 }
@@ -264,76 +265,85 @@ export function minify(
264265 popScope ( )
265266 } ,
266267 } ,
267- StructDeclaration ( node ) {
268- const isExternal = externalTypes . has ( node . id . name )
269- if ( ! isExternal || mangleExternals ) {
270- mangleName ( node . id . name , isExternal )
271-
272- // pushScope()
273- for ( const member of node . members ) {
274- if ( member . type !== 'VariableDeclaration' ) continue
275- for ( const decl of member . declarations ) {
276- mangleName ( node . id . name + '.' + decl . id . name , isExternal )
277- }
268+ StructDeclaration : {
269+ enter ( node ) {
270+ const isExternal = externalTypes . has ( node . id . name )
271+ if ( ! isExternal || mangleExternals ) {
272+ mangleName ( node . id . name , isExternal )
278273 }
279- // popScope()
280- }
274+
275+ pushScope ( )
276+ typeScopes . set ( node . id . name , scopes . at ( - 1 ) ! )
277+ types . push ( node . id . name )
278+ } ,
279+ exit ( ) {
280+ types . length -= 1
281+ popScope ( )
282+ } ,
281283 } ,
282- StructuredBufferDeclaration ( node ) {
283- if ( node . typeSpecifier . type !== 'Identifier' ) return
284+ StructuredBufferDeclaration : {
285+ enter ( node ) {
286+ if ( node . typeSpecifier . type !== 'Identifier' ) return
284287
285- // When an instance name is not defined, the type specifier can be used as an external reference
286- if ( node . id || mangleExternals ) {
287- mangleName ( node . typeSpecifier . name , false )
288- }
288+ // When an instance name is not defined, the type specifier can be used as an external reference
289+ if ( node . id || mangleExternals ) {
290+ mangleName ( node . typeSpecifier . name , false )
291+ }
289292
290- if ( ! node . id ) return
293+ if ( ! node . id ) return
291294
292- const isExternal = externalTypes . has ( node . typeSpecifier . name )
293- if ( ! isExternal || mangleExternals ) {
294- mangleName ( node . id . name , isExternal )
295+ const isExternal = externalTypes . has ( node . typeSpecifier . name )
296+ if ( ! isExternal || mangleExternals ) {
297+ mangleName ( node . id . name , isExternal )
298+ }
295299
296300 const scope = scopes . at ( - 1 ) !
297301 if ( node . typeSpecifier . type === 'Identifier' ) {
298302 scope . references . set ( node . id . name , node . typeSpecifier . name )
303+ types . push ( node . typeSpecifier . name )
299304 } else if ( ( node . typeSpecifier as ArraySpecifier ) . type === 'ArraySpecifier' ) {
300305 scope . references . set ( node . id . name , ( node . typeSpecifier as ArraySpecifier ) . typeSpecifier . name )
306+ types . push ( ( node . typeSpecifier as ArraySpecifier ) . typeSpecifier . name )
301307 }
302308
303- // pushScope()
304- for ( const member of node . members ) {
305- if ( member . type !== 'VariableDeclaration' ) continue
306- for ( const decl of member . declarations ) {
307- mangleName ( node . typeSpecifier . name + '.' + decl . id . name , isExternal )
308- }
309+ pushScope ( )
310+ typeScopes . set ( node . id . name , scopes . at ( - 1 ) ! )
311+ } ,
312+ exit ( node ) {
313+ if ( node . id ) {
314+ types . length -= 1
315+ popScope ( )
309316 }
310- // popScope()
311- }
317+ } ,
312318 } ,
313- VariableDeclarator ( node , ancestors ) {
319+ VariableDeclaration ( node , ancestors ) {
314320 // TODO: ensure uniform decl lists work
315- const containerNode = ancestors . at ( - 2 ) // Container -> VariableDecl
316- const isExternal =
317- node . qualifiers . some ( isStorage ) ||
318- containerNode ?. type === 'StructDeclaration' ||
319- ( containerNode ?. type === 'StructuredBufferDeclaration' && containerNode . qualifiers . some ( isStorage ) )
320-
321- if ( ! isExternal || mangleExternals ) {
322- let name : string = ''
323- if ( node . id . type === 'Identifier' ) {
324- name = node . id . name
325- mangleName ( name , isExternal )
326- } else if ( node . id . type === 'ArraySpecifier' ) {
327- name = ( node . id as unknown as ArraySpecifier ) . typeSpecifier . name
328- }
321+ const parent = ancestors . at ( - 1 ) // Container -> VariableDecl
322+ const isParentExternal =
323+ parent ?. type === 'StructDeclaration' ||
324+ ( parent ?. type === 'StructuredBufferDeclaration' && parent . qualifiers . some ( isStorage ) )
325+
326+ for ( const decl of node . declarations ) {
327+ // Skip preprocessor
328+ if ( decl . type !== 'VariableDeclarator' ) continue
329+
330+ const isExternal = isParentExternal || decl . qualifiers . some ( isStorage )
331+ if ( ! isExternal || mangleExternals ) {
332+ let name : string = ''
333+ if ( decl . id . type === 'Identifier' ) {
334+ name = decl . id . name
335+ } else if ( decl . id . type === 'ArraySpecifier' ) {
336+ name = ( decl . id as unknown as ArraySpecifier ) . typeSpecifier . name
337+ }
329338
330- mangleName ( name , isExternal )
339+ mangleName ( name , isExternal )
331340
332- const scope = scopes . at ( - 1 ) !
333- if ( node . typeSpecifier . type === 'Identifier' ) {
334- scope . references . set ( name , node . typeSpecifier . name )
335- } else if ( node . typeSpecifier . type === 'ArraySpecifier' ) {
336- scope . references . set ( name , node . typeSpecifier . typeSpecifier . name )
341+ const scope = scopes . at ( - 1 ) !
342+ if ( decl . typeSpecifier . type === 'Identifier' ) {
343+ scope . references . set ( name , decl . typeSpecifier . name )
344+ } else if ( decl . typeSpecifier . type === 'ArraySpecifier' ) {
345+ scope . references . set ( name , decl . typeSpecifier . typeSpecifier . name )
346+ }
337347 }
338348 }
339349 } ,
@@ -352,7 +362,7 @@ export function minify(
352362 } ,
353363 MemberExpression : {
354364 enter ( node ) {
355- let type : string | null = null
365+ let type : string | null = ''
356366
357367 if ( node . object . type === 'CallExpression' && node . object . callee . type === 'Identifier' ) {
358368 // TODO: length() should be mangled whereas array.length() should not
@@ -368,16 +378,14 @@ export function minify(
368378 if ( renamed !== null ) node . object . name = renamed
369379 }
370380
371- prefixes . push ( type )
381+ types . push ( type )
372382 } ,
373383 exit ( ) {
374- prefixes . length -= 1
384+ types . length -= 1
375385 } ,
376386 } ,
377387 Identifier ( node ) {
378- // TODO: can this wrongly scope objects inside of member expr?
379- const prefix = getPrefix ( )
380- const renamed = getScopedName ( prefix ? prefix + '.' + node . name : node . name )
388+ const renamed = getScopedName ( node . name )
381389 if ( renamed !== null ) node . name = renamed
382390 } ,
383391 } )
0 commit comments