Phase 21.3 WIP: Hako Source Checker improvements - HC011/HC016/HC017 実装完了
主な変更: - ✅ HC011 (dead methods) 実装・テスト緑 - ✅ HC016 (unused alias) 実装・テスト緑 - ✅ HC017 (non-ascii quotes) 実装完了 - 🔧 tokenizer/parser_core 強化(AST優先ルート) - 🛡️ plugin_guard.rs 追加(stderr専用出力) - 📋 テストインフラ整備(run_tests.sh改善) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -12,3 +12,4 @@ pub mod resolve;
|
||||
pub mod exec;
|
||||
pub mod core_bridge;
|
||||
pub mod hako;
|
||||
pub mod plugin_guard;
|
||||
|
||||
89
src/runner/modes/common_util/plugin_guard.rs
Normal file
89
src/runner/modes/common_util/plugin_guard.rs
Normal file
@ -0,0 +1,89 @@
|
||||
/*!
|
||||
* Plugin guard utilities
|
||||
*
|
||||
* Centralized helper to check required plugin providers and emit
|
||||
* consistent diagnostics across runner modes.
|
||||
*/
|
||||
|
||||
/// Build the list of required provider type names.
|
||||
///
|
||||
/// Priority:
|
||||
/// - If env `NYASH_PLUGIN_OVERRIDE_TYPES` is set, use it (comma-separated).
|
||||
/// - Otherwise, return a conservative default set used in VM paths.
|
||||
pub fn gather_required_providers() -> Vec<String> {
|
||||
if let Ok(list) = std::env::var("NYASH_PLUGIN_OVERRIDE_TYPES") {
|
||||
let mut v: Vec<String> = list
|
||||
.split(',')
|
||||
.map(|s| s.trim().to_string())
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect();
|
||||
v.sort();
|
||||
v.dedup();
|
||||
return v;
|
||||
}
|
||||
// Default conservative set
|
||||
let mut v = vec![
|
||||
"FileBox".to_string(),
|
||||
"ConsoleBox".to_string(),
|
||||
"ArrayBox".to_string(),
|
||||
"MapBox".to_string(),
|
||||
"StringBox".to_string(),
|
||||
"IntegerBox".to_string(),
|
||||
];
|
||||
v
|
||||
}
|
||||
|
||||
/// Return missing providers by checking the unified registry.
|
||||
pub fn detect_missing_providers(required: &[String]) -> Vec<String> {
|
||||
let reg = nyash_rust::runtime::get_global_registry();
|
||||
let mut missing: Vec<String> = Vec::new();
|
||||
for t in required {
|
||||
if reg.get_provider(t).is_none() {
|
||||
missing.push(t.clone());
|
||||
}
|
||||
}
|
||||
missing
|
||||
}
|
||||
|
||||
/// Emit hints for specific provider types.
|
||||
fn emit_hints_for(missing: &[String]) {
|
||||
if missing.iter().any(|t| t == "FileBox") {
|
||||
eprintln!("[plugin/hint] FileBox plugin is required for file I/O (new FileBox/open/read).");
|
||||
eprintln!("[plugin/hint] Build and load plugin: see tools/plugin_v2_smoke.sh or configure nyash.toml [libraries.*.FileBox].");
|
||||
eprintln!("[plugin/hint] Ensure LD_LIBRARY_PATH (or platform equivalent) includes the plugin directory.");
|
||||
eprintln!("[plugin/hint] For analyzer runs, you can avoid FileBox via --source-file <path> <text>.");
|
||||
}
|
||||
}
|
||||
|
||||
/// Check provider availability and emit diagnostics.
|
||||
///
|
||||
/// - `strict`: exit(1) when any provider is missing.
|
||||
/// - `quiet_pipe`: respect quiet JSON pipelines; we still write diagnostics to stderr only.
|
||||
/// - `label`: context label (e.g., "vm", "vm-fallback") for messages.
|
||||
pub fn check_and_report(strict: bool, quiet_pipe: bool, label: &str) {
|
||||
let required = gather_required_providers();
|
||||
let missing = detect_missing_providers(&required);
|
||||
if missing.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
if strict {
|
||||
eprintln!(
|
||||
"❌ {} plugin-first strict: missing providers for: {:?}",
|
||||
label, missing
|
||||
);
|
||||
emit_hints_for(&missing);
|
||||
// Do not print anything to stdout in quiet mode; just exit with 1
|
||||
std::process::exit(1);
|
||||
} else {
|
||||
eprintln!(
|
||||
"[plugin/missing] {} providers not loaded: {:?}",
|
||||
label, missing
|
||||
);
|
||||
emit_hints_for(&missing);
|
||||
if quiet_pipe {
|
||||
// In quiet JSON mode, avoid noisy stdout; hints are on stderr already.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,13 @@ impl NyashRunner {
|
||||
// Initialize plugin host so method_id injection can resolve plugin calls
|
||||
crate::runner_plugin_init::init_bid_plugins();
|
||||
|
||||
// Friendly plugin guard (non‑strict): unify diagnostics across modes
|
||||
crate::runner::modes::common_util::plugin_guard::check_and_report(
|
||||
false,
|
||||
crate::config::env::env_bool("NYASH_JSON_ONLY"),
|
||||
"llvm",
|
||||
);
|
||||
|
||||
// Read the file
|
||||
let code = match fs::read_to_string(filename) {
|
||||
Ok(content) => content,
|
||||
|
||||
@ -67,30 +67,13 @@ impl NyashRunner {
|
||||
}
|
||||
std::env::set_var("NYASH_PLUGIN_OVERRIDE_TYPES", override_types.join(","));
|
||||
|
||||
// Strict mode: verify providers exist for override types
|
||||
if crate::config::env::env_bool("NYASH_VM_PLUGIN_STRICT") {
|
||||
let v2 = nyash_rust::runtime::get_global_registry();
|
||||
let mut missing: Vec<String> = Vec::new();
|
||||
for t in [
|
||||
"FileBox",
|
||||
"ConsoleBox",
|
||||
"ArrayBox",
|
||||
"MapBox",
|
||||
"StringBox",
|
||||
"IntegerBox",
|
||||
] {
|
||||
if v2.get_provider(t).is_none() {
|
||||
missing.push(t.to_string());
|
||||
}
|
||||
}
|
||||
if !missing.is_empty() {
|
||||
eprintln!(
|
||||
"❌ VM plugin-first strict: missing providers for: {:?}",
|
||||
missing
|
||||
);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
// Centralized plugin guard
|
||||
let strict = crate::config::env::env_bool("NYASH_VM_PLUGIN_STRICT");
|
||||
crate::runner::modes::common_util::plugin_guard::check_and_report(
|
||||
strict,
|
||||
quiet_pipe,
|
||||
"vm",
|
||||
);
|
||||
}
|
||||
|
||||
// Read the file
|
||||
|
||||
@ -295,6 +295,12 @@ impl NyashRunner {
|
||||
|
||||
// Execute via MIR interpreter
|
||||
let mut vm = MirInterpreter::new();
|
||||
// Centralized plugin guard (non-strict by default on fallback route)
|
||||
crate::runner::modes::common_util::plugin_guard::check_and_report(
|
||||
false,
|
||||
crate::config::env::env_bool("NYASH_JSON_ONLY"),
|
||||
"vm-fallback",
|
||||
);
|
||||
// Optional: verify MIR before execution (dev-only)
|
||||
if crate::config::env::env_bool("NYASH_VM_VERIFY_MIR") {
|
||||
let mut verifier = crate::mir::verification::MirVerifier::new();
|
||||
|
||||
Reference in New Issue
Block a user