///|
fn collect_wgsl_live_binding_plan(
facts : WgslComposeSemanticFacts,
bindings : WgslComposeBindingSet,
) -> WgslLiveBindingPlan {
WgslReachabilityPlan(facts, bindings).live_binding_plan()
}
///|
fn collect_wgsl_effective_reference_bindings(
session : WgslComposeSession,
bindings : WgslComposeBindingSet,
facts : WgslComposeSemanticFacts,
) -> WgslComposeBindingSet {
let effective = WgslComposeBindingSet()
for binding in bindings.bindings {
if facts.contains_reference_path(binding.reference_path.text()) {
effective.push(binding)
}
}
for binding in session.global_alias_bindings.bindings {
if facts.contains_reference_path(binding.reference_path.text()) {
effective.push(binding)
}
}
for entry in session.symbols.emitted_final_names.alias_entries() {
let identity = entry.identity()
let symbol = identity.symbol()
let reference_text = "\{identity.alias_name()}::\{symbol.original_name()}"
if !facts.contains_reference_path(reference_text) {
continue
}
match
WgslComposeBinding::for_alias_symbol(
symbol.rel_path(),
identity.alias_name(),
symbol.original_name(),
entry.final_name(),
QualifiedAliasBinding,
) {
Some(binding) => effective.push(binding)
None => ()
}
}
effective
}
///|
fn collect_wgsl_local_import_final_name_rewrite_plan(
session : WgslComposeSession,
) -> WgslReferenceRewritePlan {
let plan = WgslReferenceRewritePlan()
for binding in session.symbols.local_import_final_names {
match WgslReferencePath::from_text(binding.source_name) {
Some(reference_path) =>
plan.add_symbol_reference_binding(
WgslComposeSymbolIdentity(binding.rel_path, binding.source_name),
reference_path,
binding.final_name,
)
None => ()
}
}
plan
}
///|
fn finalize_wgsl_composed_source(
merged : String,
bindings : WgslComposeBindingSet,
active_defs : WgslActiveComposeDefs,
session : WgslComposeSession,
apply_virtual_overrides : Bool,
validate_output : Bool,
) -> String raise ComposerError {
let mut out = apply_wgsl_ifdefs_strict_for_compose(merged, active_defs)
out = apply_wgsl_template_consts(out, active_defs.value_defines)
out = rewrite_wgsl_declarations_with_binding_plan(
out,
collect_wgsl_local_import_final_name_rewrite_plan(session),
) catch {
error => raise composer_error_from_wgsl_parse_error(error)
}
let out_facts = collect_wgsl_compose_semantic_facts(session, out)
let effective_bindings = collect_wgsl_effective_reference_bindings(
session, bindings, out_facts,
)
let live_bindings = collect_wgsl_live_binding_plan(
out_facts, effective_bindings,
)
match live_bindings.first_conflict() {
Some(message) => raise AmbiguousImportBinding(message)
None => ()
}
let rewrite_plan = live_bindings.reference_rewrite_plan(session)
let mut source_changed_before_reference_rewrite = false
if apply_virtual_overrides {
if rewrite_plan.has_virtual_override_bindings() {
out = apply_wgsl_virtual_overrides_with_binding_plan(out, rewrite_plan)
source_changed_before_reference_rewrite = true
}
} else if rewrite_plan.has_virtual_override_bindings() {
out = rewrite_wgsl_override_targets_with_binding_plan(out, rewrite_plan)
source_changed_before_reference_rewrite = true
}
if source_changed_before_reference_rewrite {
out = rewrite_wgsl_references_with_binding_plan(out, rewrite_plan) catch {
error => raise composer_error_from_wgsl_parse_error(error)
}
} else {
out = rewrite_wgsl_references_with_binding_plan(out, rewrite_plan) catch {
error => raise composer_error_from_wgsl_parse_error(error)
}
}
if !validate_output {
return out
}
out = deduplicate_identical_wgsl_declarations(out)
if !apply_virtual_overrides {
validate_wgsl_translation_unit_strict(out)
return out
}
validate_wgsl_translation_unit_strict(out)
out
}