use std::path::Path;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use crate::{
macro_impl::{Config, Lazieness},
metadata::cargo_crate_name,
template::TemplateContext,
};
fn is_ide() -> bool {
std::env::current_exe()
.ok()
.as_deref()
.and_then(Path::file_name)
.map_or_else(|| "unknown".into(), |s| s.to_string_lossy().into_owned())
.contains("rust-analyzer")
|| std::env::var("RUST_ANALYZER_INTERNALS_DO_NOT_USE").unwrap_or_default() == "this is unstable"
}
fn format_ide_helper_mod(template_context: &TemplateContext) -> TokenStream {
let deps = template_context
.source_metadata
.dependencies
.iter()
.map(|dep| {
let name = cargo_crate_name(&dep.name);
let name = format_ident!("{}", name);
quote! {
extern crate #name;
}
})
.collect::<Vec<_>>();
let content = &template_context.generated_content;
let mod_name = format_ident!(
"__ide_tg_helper_{}",
cargo_crate_name(&template_context.package_name)
);
quote! {
mod #mod_name {
extern crate token_goblin_runtime;
use token_goblin_runtime::prelude::*;
macro_rules! quote {
($($tokens:tt)*) => {{
const _: () = ();
TokenStream::new()
}}
}
macro_rules! output {
($($tokens:tt)*) => {
{let _ = quote!($($tokens)*);}
}
}
#(#deps)*
#content
}
}
}
pub fn emit_ide_helper_mod(template_context: &TemplateContext, config: &Config) -> TokenStream {
if is_ide() && !config.no_ide_helper {
format_ide_helper_mod(template_context)
} else {
TokenStream::new()
}
}
pub fn is_lazy(config: &Config) -> bool {
config.lazy == Lazieness::Enforced || (config.lazy == Lazieness::Default && is_ide())
}