use crate::core::hash::{self, CommentStyle};
pub(super) fn strip_trailing_whitespace(content: &str) -> String {
let mut result: String = content
.lines()
.map(|line| line.trim_end())
.collect::<Vec<_>>()
.join("\n");
if !result.ends_with('\n') {
result.push('\n');
}
result
}
pub(super) fn csharp_file_header() -> String {
let mut out = hash::header(CommentStyle::DoubleSlash);
out.push_str("#nullable enable\n\n");
out
}
pub(super) fn gen_directory_build_props() -> String {
"<!-- auto-generated by alef (generate_bindings) -->\n\
<Project>\n \
<PropertyGroup>\n \
<Nullable>enable</Nullable>\n \
<LangVersion>latest</LangVersion>\n \
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>\n \
</PropertyGroup>\n\
</Project>\n"
.to_string()
}
const VISITOR_SUPPORT_FILES: [&str; 2] = ["IVisitor.cs", "VisitorCallbacks.cs"];
pub(super) fn superseded_visitor_filenames() -> Vec<String> {
VISITOR_SUPPORT_FILES.iter().map(|name| (*name).to_string()).collect()
}
pub(super) fn stale_visitor_filenames(config: &crate::core::config::ResolvedCrateConfig) -> Vec<String> {
let mut stale_files = superseded_visitor_filenames();
stale_files.extend(config.trait_bridges.iter().filter_map(|bridge| {
bridge
.context_type
.as_deref()
.map(|name| format!("{}.cs", crate::codegen::naming::csharp_type_name(name)))
}));
stale_files.extend(config.trait_bridges.iter().filter_map(|bridge| {
bridge
.result_type
.as_deref()
.map(|name| format!("{}.cs", crate::codegen::naming::csharp_type_name(name)))
}));
stale_files
}
pub(super) fn report_unemitted_visitor_files(
base_path: &std::path::Path,
filenames: &[String],
) -> Vec<std::path::PathBuf> {
let present: Vec<std::path::PathBuf> = filenames
.iter()
.map(|filename| base_path.join(filename))
.filter(|path| path.is_file())
.collect();
if present.is_empty() {
return present;
}
tracing::warn!(
"gen_bindings(csharp): {} visitor support file(s) under {} were not emitted by this run. These are NOT \
deleted: this generator cannot tell a file an older alef release wrote from one a human wrote at the same \
path, and an absent `[ffi]` config section is not a decision to disable visitor callbacks. Review each and \
remove by hand if genuinely stale:",
present.len(),
base_path.display()
);
for path in &present {
tracing::warn!(" unemitted visitor support file: {}", path.display());
}
present
}