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:
nyash-codex
2025-11-21 06:25:17 +09:00
parent baf028a94f
commit f9d100ce01
366 changed files with 14322 additions and 5236 deletions

View File

@ -1,5 +1,5 @@
//! Using Resolution Box - 綺麗綺麗なusing文解決専門家📦
//!
//!
//! 巨大な `collect_using_and_strip` 関数を箱に分解して、
//! 責務を明確にしてテストしやすくするにゃ!
@ -8,7 +8,7 @@ use std::collections::HashMap;
use std::path::{Path, PathBuf};
/// 📦 UsingResolutionBox - using文解決の専門家
///
///
/// using文の解析、パス解決、重複チェックを一手に引き受ける箱にゃ
pub struct UsingResolutionBox<'a> {
runner: &'a NyashRunner,
@ -52,9 +52,9 @@ impl<'a> UsingResolutionBox<'a> {
|| crate::config::env::env_bool("NYASH_RESOLVE_TRACE"),
allow_file_using: crate::config::env::allow_using_file(),
};
let ctx_dir = Path::new(filename).parent().map(|p| p.to_path_buf());
// ファイルがパッケージ内にあるかチェック
let filename_canon = std::fs::canonicalize(filename).ok();
let mut inside_pkg = false;
@ -89,11 +89,11 @@ impl<'a> UsingResolutionBox<'a> {
}
crate::cli_v!("[using] stripped line: {}", line);
let rest0 = t.strip_prefix("using ").unwrap().trim();
let rest0 = rest0.split('#').next().unwrap_or(rest0).trim();
let rest0 = rest0.strip_suffix(';').unwrap_or(rest0).trim();
let (target, alias) = if let Some(pos) = rest0.find(" as ") {
(
rest0[..pos].trim().to_string(),
@ -105,16 +105,21 @@ impl<'a> UsingResolutionBox<'a> {
let target_unquoted = target.trim_matches('"').to_string();
let using_ctx = self.runner.init_using_context();
// 既知のエイリアスかモジュールかチェック
let is_known_alias_or_module = using_ctx.aliases.contains_key(&target_unquoted)
|| using_ctx.pending_modules.iter().any(|(k, _)| k == &target_unquoted)
|| using_ctx
.pending_modules
.iter()
.any(|(k, _)| k == &target_unquoted)
|| using_ctx.packages.contains_key(&target_unquoted);
let is_path = if is_known_alias_or_module {
false
} else {
crate::runner::modes::common_util::resolve::path_util::is_using_target_path_unquoted(&target_unquoted)
crate::runner::modes::common_util::resolve::path_util::is_using_target_path_unquoted(
&target_unquoted,
)
};
Some(UsingTarget {
@ -145,7 +150,7 @@ impl<'a> UsingResolutionBox<'a> {
let path = target.target.trim_matches('"').to_string();
let mut p = PathBuf::from(&path);
// 相対パス解決
if p.is_relative() {
if let Some(dir) = &self.ctx_dir {
@ -154,7 +159,7 @@ impl<'a> UsingResolutionBox<'a> {
p = cand;
}
}
// NYASH_ROOTも試す
if p.is_relative() {
if let Ok(root) = std::env::var("NYASH_ROOT") {
@ -172,9 +177,13 @@ impl<'a> UsingResolutionBox<'a> {
}
/// 🛡️ 重複チェックするにゃ!
pub fn check_duplicates(&mut self, target: &UsingTarget, resolved_path: &str) -> Result<(), String> {
let canon_path = std::fs::canonicalize(resolved_path)
.unwrap_or_else(|_| PathBuf::from(resolved_path));
pub fn check_duplicates(
&mut self,
target: &UsingTarget,
resolved_path: &str,
) -> Result<(), String> {
let canon_path =
std::fs::canonicalize(resolved_path).unwrap_or_else(|_| PathBuf::from(resolved_path));
let canon_str = canon_path.to_string_lossy();
// パスの重複チェック
@ -204,10 +213,14 @@ impl<'a> UsingResolutionBox<'a> {
// 記録
let alias_label = target.alias.as_ref().unwrap_or(&target.target).clone();
self.seen_paths.insert(canon_str.to_string(), (alias_label.clone(), target.line_no));
self.seen_paths
.insert(canon_str.to_string(), (alias_label.clone(), target.line_no));
if let Some(ref alias_name) = target.alias {
self.seen_aliases.insert(alias_name.clone(), (resolved_path.to_string(), target.line_no));
self.seen_aliases.insert(
alias_name.clone(),
(resolved_path.to_string(), target.line_no),
);
}
Ok(())