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:
nyash-codex
2025-11-08 00:46:34 +09:00
parent 647e15d12e
commit 58a6471883
39 changed files with 1435 additions and 283 deletions

View File

@ -174,48 +174,11 @@ impl super::MirBuilder {
/// Build a single statement node.
///
/// Note:
/// - Stage-3 While/ForRange lowering is delegated to existing Loop/expr lowering
/// or handled in a dedicated pass; this function does not emit ad-hoc control
/// flow for them to avoid divergence from SSOT/loop_common.
/// - While/ForRange は将来 Loop lowering へ委譲する拡張ポイントとして扱い、
/// 現状は他の専用ビルダ/既存パスと同様に build_expression に委譲する。
pub(super) fn build_statement(&mut self, node: ASTNode) -> Result<ValueId, String> {
match node.clone() {
ASTNode::While { condition, body, .. } => {
// Desugar Stage-3 while into legacy loop(condition) { body }
let loop_node = ASTNode::Loop { condition, body, span: crate::ast::Span::unknown() };
self.build_expression(loop_node)
}
ASTNode::ForRange { var_name, start, end, body, .. } => {
use crate::ast::{Span, LiteralValue, BinaryOperator};
// local var initialization
let init = ASTNode::Local {
variables: vec![var_name.clone()],
initial_values: vec![Some(start)],
span: Span::unknown(),
};
// condition: var_name < end
let cond = ASTNode::BinaryOp {
left: Box::new(ASTNode::Variable { name: var_name.clone(), span: Span::unknown() }),
operator: BinaryOperator::Less,
right: end,
span: Span::unknown(),
};
// step: var_name = var_name + 1
let step = ASTNode::Assignment {
target: Box::new(ASTNode::Variable { name: var_name.clone(), span: Span::unknown() }),
value: Box::new(ASTNode::BinaryOp {
left: Box::new(ASTNode::Variable { name: var_name.clone(), span: Span::unknown() }),
operator: BinaryOperator::Add,
right: Box::new(ASTNode::Literal { value: LiteralValue::Integer(1), span: Span::unknown() }),
span: Span::unknown(),
}),
span: Span::unknown(),
};
let mut loop_body = body.clone();
loop_body.push(step);
let loop_node = ASTNode::Loop { condition: Box::new(cond), body: loop_body, span: Span::unknown() };
let program = ASTNode::Program { statements: vec![init, loop_node], span: Span::unknown() };
self.build_expression(program)
}
match node {
// 将来ここに While / ForRange / Match / Using など statement 専用分岐を追加する。
other => self.build_expression(other),
}
}