// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
fn build_wgsl_ir_writer_final_name_plan(
view : WgslIrWriterModule,
shader_module : Module,
) -> WgslIrFinalNamePlan {
let table = WgslIrFinalNamePlan::empty()
let namer = WgslIrWriterNamer::WgslIrWriterNamer()
for slot in view.type_slots() {
view.allocate_type_name(table, namer, slot)
}
for slot in view.entry_point_slots() {
view.allocate_entry_point_signature_names(table, namer, namer, slot)
view.reserve_entry_point_var_local_names(table, namer, slot)
}
for slot in view.function_slots() {
view.allocate_function_signature_names(table, namer, namer, slot)
view.reserve_function_var_local_names(table, namer, slot)
}
for slot in view.global_variable_slots() {
table.names.set(
wgsl_ir_emit_name_key("global", slot.source_index),
namer.call_or(slot.item.name, "global"),
)
}
for slot in view.constant_slots() {
table.names.set(
wgsl_ir_emit_name_key("const", slot.source_index),
namer.call_or(slot.item.name, "const"),
)
}
for slot in view.override_slots() {
table.names.set(
wgsl_ir_emit_name_key("override", slot.source_index),
namer.call_or(slot.item.name, "override"),
)
}
for slot in view.function_slots() {
view.allocate_function_body_names(table, namer, slot, shader_module)
}
for slot in view.entry_point_slots() {
view.allocate_entry_point_body_names(table, namer, slot, shader_module)
}
table
}
///|
fn WgslIrWriterModule::allocate_type_name(
self : WgslIrWriterModule,
table : WgslIrFinalNamePlan,
namer : WgslIrWriterNamer,
slot : WgslIrWriterTypeSlot,
) -> Unit {
ignore(self)
let ty = slot.item
let raw = match ty.name {
Some(name) => name
None => "type"
}
table.names.set(
wgsl_ir_emit_name_key("type", slot.source_index),
namer.call(raw),
)
match ty.inner {
Struct(members, _) | PredeclaredStruct(members, _) => {
let member_namer = WgslIrWriterNamer::WgslIrWriterNamer()
for member_index in 0.. name
None => "member"
}
let raw = if self.type_name_is_imported_generated_symbol(ty.name) {
raw
} else {
self.root_struct_member_import_spelling_name(raw)
}
table.names.set(
wgsl_ir_emit_name_key2("member", slot.source_index, member_index),
member_namer.member_call(raw),
)
}
}
_ => ()
}
}
///|
fn WgslIrWriterModule::type_name_is_imported_generated_symbol(
self : WgslIrWriterModule,
name : String?,
) -> Bool {
match name {
Some(value) =>
match self.compatibility.generated_import(value) {
Some(provenance) => provenance.kind == ImportedSourceSymbol
None => false
}
None => false
}
}
///|
fn WgslIrWriterModule::root_struct_member_import_spelling_name(
self : WgslIrWriterModule,
source_name : String,
) -> String {
if !self.root_struct_member_import_spelling {
return source_name
}
let mut target : String? = None
for entry in self.compatibility.generated_import_provenance.iter() {
let (_, provenance) = entry
if provenance.kind != ImportedSourceSymbol ||
!provenance.root_local_spelling ||
provenance.source_symbol_name != source_name {
continue
}
match target {
Some(existing) if existing != provenance.generated_symbol_name =>
return source_name
Some(_) => ()
None => target = Some(provenance.generated_symbol_name)
}
}
match target {
Some(value) => value
None => source_name
}
}
///|
fn WgslIrWriterModule::allocate_entry_point_signature_names(
self : WgslIrWriterModule,
table : WgslIrFinalNamePlan,
module_namer : WgslIrWriterNamer,
local_namer : WgslIrWriterNamer,
slot : WgslIrWriterEntryPointSlot,
) -> Unit {
ignore(self)
let ep = slot.item
table.names.set(
wgsl_ir_emit_name_key("ep", slot.source_index),
module_namer.call(ep.name),
)
for arg_index in 0.. Some(self.compatibility.root_local_spelling(name))
None => None
}
table.names.set(
wgsl_ir_emit_name_key2("ep_arg", slot.source_index, arg_index),
local_namer.call_or(raw_name, "param"),
)
}
}
///|
fn WgslIrWriterModule::allocate_function_signature_names(
self : WgslIrWriterModule,
table : WgslIrFinalNamePlan,
module_namer : WgslIrWriterNamer,
local_namer : WgslIrWriterNamer,
slot : WgslIrWriterFunctionSlot,
) -> Unit {
ignore(self)
let function = slot.item
let name = match function.name {
Some(name) if self.function_name_is_generated_entry_wrapper(name) =>
module_namer.call_preserving_trailing_digit(name)
_ => module_namer.call_or(function.name, "function")
}
table.names.set(wgsl_ir_emit_name_key("fn", slot.source_index), name)
let visible_rel_path = self.compatibility.generated_function_rel_path(
function.name,
)
for arg_index in 0..
Some(self.compatibility.local_spelling(value, visible_rel_path))
None => None
}
table.names.set(
wgsl_ir_emit_name_key2("fn_arg", slot.source_index, arg_index),
local_namer.call_or(raw_name, "param"),
)
}
}
///|
fn WgslIrWriterModule::function_name_is_generated_entry_wrapper(
self : WgslIrWriterModule,
name : String,
) -> Bool {
guard name == "main_1" else { return false }
for slot in self.entry_point_slots() {
if slot.item.name == "main" {
return true
}
}
false
}
///|
fn WgslIrWriterModule::allocate_entry_point_body_names(
self : WgslIrWriterModule,
table : WgslIrFinalNamePlan,
namer : WgslIrWriterNamer,
slot : WgslIrWriterEntryPointSlot,
shader_module : Module,
) -> Unit {
ignore(self)
let ep = slot.item
table.allocate_function_body_names_from_arena(
shader_module,
EntryPointFunction(slot.source_index),
ep.function,
slot.function_plan,
namer,
self.compatibility,
Root,
)
}
///|
fn WgslIrWriterModule::reserve_entry_point_var_local_names(
self : WgslIrWriterModule,
table : WgslIrFinalNamePlan,
namer : WgslIrWriterNamer,
slot : WgslIrWriterEntryPointSlot,
) -> Unit {
ignore(self)
table.reserve_function_var_local_names_from_arena(
EntryPointFunction(slot.source_index),
slot.item.function,
slot.function_plan,
namer,
self.compatibility,
Root,
)
}
///|
fn WgslIrWriterModule::allocate_function_body_names(
self : WgslIrWriterModule,
table : WgslIrFinalNamePlan,
namer : WgslIrWriterNamer,
slot : WgslIrWriterFunctionSlot,
shader_module : Module,
) -> Unit {
ignore(self)
let function = slot.item
table.allocate_function_body_names_from_arena(
shader_module,
UserFunction(slot.source_index),
function,
slot.function_plan,
namer,
self.compatibility,
Visible(self.compatibility.generated_function_rel_path(function.name)),
)
}
///|
fn WgslIrWriterModule::reserve_function_var_local_names(
self : WgslIrWriterModule,
table : WgslIrFinalNamePlan,
namer : WgslIrWriterNamer,
slot : WgslIrWriterFunctionSlot,
) -> Unit {
ignore(self)
table.reserve_function_var_local_names_from_arena(
UserFunction(slot.source_index),
slot.item,
slot.function_plan,
namer,
self.compatibility,
Visible(self.compatibility.generated_function_rel_path(slot.item.name)),
)
}