chore: Phase 25.1 完了 - LoopForm v2/Stage1 CLI/環境変数削減 + Phase 26-D からの変更
Phase 25.1 完了成果: - ✅ LoopForm v2 テスト・ドキュメント・コメント完備 - 4ケース(A/B/C/D)完全テストカバレッジ - 最小再現ケース作成(SSAバグ調査用) - SSOT文書作成(loopform_ssot.md) - 全ソースに [LoopForm] コメントタグ追加 - ✅ Stage-1 CLI デバッグ環境構築 - stage1_cli.hako 実装 - stage1_bridge.rs ブリッジ実装 - デバッグツール作成(stage1_debug.sh/stage1_minimal.sh) - アーキテクチャ改善提案文書 - ✅ 環境変数削減計画策定 - 25変数の完全調査・分類 - 6段階削減ロードマップ(25→5、80%削減) - 即時削除可能変数特定(NYASH_CONFIG/NYASH_DEBUG) Phase 26-D からの累積変更: - PHI実装改善(ExitPhiBuilder/HeaderPhiBuilder等) - MIRビルダーリファクタリング - 型伝播・最適化パス改善 - その他約300ファイルの累積変更 🎯 技術的成果: - SSAバグ根本原因特定(条件分岐内loop変数変更) - Region+next_iパターン適用完了(UsingCollectorBox等) - LoopFormパターン文書化・テスト化完了 - セルフホスティング基盤強化 Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: ChatGPT <noreply@openai.com> Co-Authored-By: Task Assistant <task@anthropic.com>
This commit is contained in:
@ -8,9 +8,9 @@
|
||||
*/
|
||||
|
||||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
use crate::using::spec::{UsingPackage, PackageKind};
|
||||
use crate::using::spec::{PackageKind, UsingPackage};
|
||||
use crate::using::ssot_bridge::{call_using_resolve_ssot, SsotCtx};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Using/module resolution context accumulated from config/env/nyash.toml
|
||||
pub(super) struct UsingContext {
|
||||
@ -149,13 +149,18 @@ pub(super) fn resolve_using_target(
|
||||
}
|
||||
// Phase 22.1: Thin SSOT hook (future wiring). No behavior change for now.
|
||||
if std::env::var("HAKO_USING_SSOT").ok().as_deref() == Some("1")
|
||||
&& std::env::var("HAKO_USING_SSOT_INVOKING")
|
||||
.ok()
|
||||
.as_deref()
|
||||
!= Some("1")
|
||||
&& std::env::var("HAKO_USING_SSOT_INVOKING").ok().as_deref() != Some("1")
|
||||
{
|
||||
if let Some(ssot_res) = try_resolve_using_target_ssot(
|
||||
tgt, is_path, modules, using_paths, aliases, packages, context_dir, strict, verbose,
|
||||
tgt,
|
||||
is_path,
|
||||
modules,
|
||||
using_paths,
|
||||
aliases,
|
||||
packages,
|
||||
context_dir,
|
||||
strict,
|
||||
verbose,
|
||||
) {
|
||||
return Ok(ssot_res);
|
||||
}
|
||||
@ -220,7 +225,9 @@ pub(super) fn resolve_using_target(
|
||||
let mut cur = tgt.to_string();
|
||||
let mut depth = 0usize;
|
||||
while let Some(next) = aliases.get(&cur).cloned() {
|
||||
if trace { crate::runner::trace::log(format!("[using/resolve] alias '{}' -> '{}'", cur, next)); }
|
||||
if trace {
|
||||
crate::runner::trace::log(format!("[using/resolve] alias '{}' -> '{}'", cur, next));
|
||||
}
|
||||
if !seen.insert(cur.clone()) {
|
||||
return Err(format!("alias cycle detected at '{}'", cur));
|
||||
}
|
||||
@ -230,10 +237,22 @@ pub(super) fn resolve_using_target(
|
||||
return Err(format!("alias resolution too deep starting at '{}'", tgt));
|
||||
}
|
||||
// Continue while next is also an alias; break when concrete
|
||||
if !aliases.contains_key(&cur) { break; }
|
||||
if !aliases.contains_key(&cur) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Recurse once into final target to materialize path/token
|
||||
let rec = resolve_using_target(&cur, false, modules, using_paths, aliases, packages, context_dir, strict, verbose)?;
|
||||
let rec = resolve_using_target(
|
||||
&cur,
|
||||
false,
|
||||
modules,
|
||||
using_paths,
|
||||
aliases,
|
||||
packages,
|
||||
context_dir,
|
||||
strict,
|
||||
verbose,
|
||||
)?;
|
||||
crate::runner::box_index::cache_put(&key, rec.clone());
|
||||
return Ok(rec);
|
||||
}
|
||||
@ -244,7 +263,10 @@ pub(super) fn resolve_using_target(
|
||||
// Return a marker token to avoid inlining attempts; loader will consume later stages
|
||||
let out = format!("dylib:{}", pkg.path);
|
||||
if trace {
|
||||
crate::runner::trace::log(format!("[using/resolve] dylib '{}' -> '{}'", tgt, out));
|
||||
crate::runner::trace::log(format!(
|
||||
"[using/resolve] dylib '{}' -> '{}'",
|
||||
tgt, out
|
||||
));
|
||||
}
|
||||
crate::runner::box_index::cache_put(&key, out.clone());
|
||||
return Ok(out);
|
||||
@ -253,25 +275,39 @@ pub(super) fn resolve_using_target(
|
||||
// Compute entry: main or <dir_last>.hako
|
||||
let base = std::path::Path::new(&pkg.path);
|
||||
let out = if let Some(m) = &pkg.main {
|
||||
if matches!(base.extension().and_then(|s| s.to_str()), Some("nyash") | Some("hako")) {
|
||||
if matches!(
|
||||
base.extension().and_then(|s| s.to_str()),
|
||||
Some("nyash") | Some("hako")
|
||||
) {
|
||||
// path is a file; ignore main and use as-is
|
||||
pkg.path.clone()
|
||||
} else {
|
||||
base.join(m).to_string_lossy().to_string()
|
||||
}
|
||||
} else {
|
||||
if matches!(base.extension().and_then(|s| s.to_str()), Some("nyash") | Some("hako")) {
|
||||
if matches!(
|
||||
base.extension().and_then(|s| s.to_str()),
|
||||
Some("nyash") | Some("hako")
|
||||
) {
|
||||
pkg.path.clone()
|
||||
} else {
|
||||
let leaf = base.file_name().and_then(|s| s.to_str()).unwrap_or(tgt);
|
||||
// prefer .hako when package path points to a directory without explicit main
|
||||
let hako = base.join(format!("{}.hako", leaf));
|
||||
if hako.exists() { hako.to_string_lossy().to_string() }
|
||||
else { base.join(format!("{}.hako", leaf)).to_string_lossy().to_string() }
|
||||
if hako.exists() {
|
||||
hako.to_string_lossy().to_string()
|
||||
} else {
|
||||
base.join(format!("{}.hako", leaf))
|
||||
.to_string_lossy()
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
};
|
||||
if trace {
|
||||
crate::runner::trace::log(format!("[using/resolve] package '{}' -> '{}'", tgt, out));
|
||||
crate::runner::trace::log(format!(
|
||||
"[using/resolve] package '{}' -> '{}'",
|
||||
tgt, out
|
||||
));
|
||||
}
|
||||
crate::runner::box_index::cache_put(&key, out.clone());
|
||||
return Ok(out);
|
||||
@ -321,8 +357,11 @@ pub(super) fn resolve_using_target(
|
||||
}
|
||||
Err(e) => {
|
||||
// Maintain previous behavior: return original name and log when unresolved
|
||||
if trace { crate::runner::trace::log(format!("[using] unresolved '{}' ({})", tgt, e)); }
|
||||
else { eprintln!("[using] not found: '{}'", tgt); }
|
||||
if trace {
|
||||
crate::runner::trace::log(format!("[using] unresolved '{}' ({})", tgt, e));
|
||||
} else {
|
||||
eprintln!("[using] not found: '{}'", tgt);
|
||||
}
|
||||
Ok(tgt.to_string())
|
||||
}
|
||||
}
|
||||
@ -349,7 +388,11 @@ fn try_resolve_using_target_ssot(
|
||||
map.insert(k.clone(), v.clone());
|
||||
}
|
||||
let cwd_str = context_dir.and_then(|p| p.to_str()).map(|s| s.to_string());
|
||||
let ctx = SsotCtx { modules: map, using_paths: using_paths.to_vec(), cwd: cwd_str };
|
||||
let ctx = SsotCtx {
|
||||
modules: map,
|
||||
using_paths: using_paths.to_vec(),
|
||||
cwd: cwd_str,
|
||||
};
|
||||
if let Some(hit) = call_using_resolve_ssot(tgt, &ctx) {
|
||||
if trace {
|
||||
crate::runner::trace::log(format!("[using/ssot] '{}' -> '{}'", tgt, hit));
|
||||
@ -412,9 +455,21 @@ fn try_resolve_using_target_ssot(
|
||||
let prev = std::env::var("HAKO_USING_SSOT_INVOKING").ok();
|
||||
std::env::set_var("HAKO_USING_SSOT_INVOKING", "1");
|
||||
let res = resolve_using_target(
|
||||
tgt, is_path, modules, using_paths, aliases, packages, context_dir, strict, verbose,
|
||||
tgt,
|
||||
is_path,
|
||||
modules,
|
||||
using_paths,
|
||||
aliases,
|
||||
packages,
|
||||
context_dir,
|
||||
strict,
|
||||
verbose,
|
||||
);
|
||||
if let Some(val) = prev { std::env::set_var("HAKO_USING_SSOT_INVOKING", val); } else { let _ = std::env::remove_var("HAKO_USING_SSOT_INVOKING"); }
|
||||
if let Some(val) = prev {
|
||||
std::env::set_var("HAKO_USING_SSOT_INVOKING", val);
|
||||
} else {
|
||||
let _ = std::env::remove_var("HAKO_USING_SSOT_INVOKING");
|
||||
}
|
||||
res.ok()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user