Files
hakorune/tools/hako_check/run_tests.sh
nyash-codex 6255877e48 Phase 21.4: HC012 Dead Static Box + HC013 Duplicate Method実装完了
## 実装内容

### HC012: Dead Static Box
- 未参照static boxを検出
- IR boxes配列活用、calls情報から参照チェック
- テスト: HC012_dead_static_box/{ok,ng}.hako + expected.json

### HC013: Duplicate Method
- 同名・同arityメソッド重複検出
- Box内でメソッド署名の一意性チェック
- テスト: HC013_duplicate_method/{ok,ng}.hako + expected.json

### 🔥 Critical Bug Fix: parser_core.hako arity計算修正
- **問題**: arityが「カンマの数」を返していた(add(a,b) → 1)
- **修正**: `if any == 1 { arity = arity + 1 }` に変更
- **影響**: 全メソッドのarity計算が正しくなった(HC015等に波及)

### Infrastructure改善
- analysis_consumer.hako: _ensure_array()ヘルパー導入
  - MapBox.get().push()問題の根本解決
  - uses/methods/calls/boxes全てで安全なpush実現
- run_tests.sh: NYASH_JSON_ONLY=1で出力純度確保
- cli.hako: HC012/HC013統合、デバッグ出力追加

## テスト結果
 HC011_dead_methods: OK
 HC012_dead_static_box: OK
 HC013_duplicate_method: OK
 HC016_unused_alias: OK
[TEST/SUMMARY] all green

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 02:59:54 +09:00

108 lines
3.7 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
BIN="${NYASH_BIN:-$ROOT/target/release/hakorune}"
if [ ! -x "$BIN" ]; then
echo "[TEST] hakorune not built: $BIN" >&2
echo "Run: cargo build --release" >&2
exit 2
fi
TARGET_DIR="$ROOT/tools/hako_check/tests"
fail=0
run_case() {
local dir="$1"
local expected="$dir/expected.json"
local input_ok="$dir/ok.hako"
local input_ng="$dir/ng.hako"
if [ ! -f "$expected" ]; then echo "[TEST] skip (no expected): $dir"; return; fi
if [ ! -f "$input_ok" ] && [ ! -f "$input_ng" ]; then echo "[TEST] skip (no inputs): $dir"; return; fi
local tmp_out="/tmp/hako_test_$$.json"
# Build a tiny wrapper program to call HakoAnalyzerBox.run with constructed argv
local path_ok text_ok
local path_ng text_ng
if [ -f "$input_ok" ]; then
path_ok="$input_ok"
text_ok="$(sed 's/\r$//' "$input_ok")"
else
:
fi
if [ -f "$input_ng" ]; then
path_ng="$input_ng"
text_ng="$(sed 's/\r$//' "$input_ng")"
else
:
fi
# Build argv array for analyzer CLI (preserve newlines in text)
ARGS=( --debug --format json-lsp )
if [ -f "$input_ok" ]; then ARGS+=( --source-file "$path_ok" "$text_ok" ); fi
if [ -f "$input_ng" ]; then ARGS+=( --source-file "$path_ng" "$text_ng" ); fi
# Directly invoke analyzer CLI with args via '--', avoid wrapper/FS
NYASH_DISABLE_NY_COMPILER=1 HAKO_DISABLE_NY_COMPILER=1 \
NYASH_PARSER_STAGE3=1 HAKO_PARSER_STAGE3=1 NYASH_PARSER_SEAM_TOLERANT=1 HAKO_PARSER_SEAM_TOLERANT=1 \
NYASH_ENABLE_USING=1 HAKO_ENABLE_USING=1 NYASH_USING_AST=1 \
NYASH_JSON_ONLY=1 \
"$BIN" --backend vm tools/hako_check/cli.hako -- "${ARGS[@]}" >"$tmp_out" 2>&1 || true
# Extract diagnostics JSON (one-line or pretty block)
tmp_json="/tmp/hako_test_json_$$.json"
json_line=$(grep -m1 '^\{"diagnostics"' "$tmp_out" || true)
if [ -n "$json_line" ] && echo "$json_line" | grep -q '\]}' ; then
echo "$json_line" > "$tmp_json"
else
json_block=$(awk '/^\{"diagnostics"/{f=1} f{print} /\]\}/{exit}' "$tmp_out" )
if [ -z "$json_block" ]; then
echo "[TEST/ERROR] no diagnostics JSON found; possible VM error. log head:" >&2
sed -n '1,120p' "$tmp_out" >&2 || true
json_block='{"diagnostics":[]}'
fi
printf "%s\n" "$json_block" > "$tmp_json"
fi
# Normalize absolute paths to basenames for stable comparison
tmp_norm="/tmp/hako_test_norm_$$.json"
cp "$tmp_json" "$tmp_norm"
if [ -f "$input_ok" ]; then
base_ok="$(basename "$input_ok")"; abs_ok="$input_ok"
sed -i "s#\"file\":\"$abs_ok\"#\"file\":\"$base_ok\"#g" "$tmp_norm"
sed -i "s#${abs_ok//\//\/}#${base_ok//\//\/}#g" "$tmp_norm"
fi
if [ -f "$input_ng" ]; then
base_ng="$(basename "$input_ng")"; abs_ng="$input_ng"
sed -i "s#\"file\":\"$abs_ng\"#\"file\":\"$base_ng\"#g" "$tmp_norm"
sed -i "s#${abs_ng//\//\/}#${base_ng//\//\/}#g" "$tmp_norm"
fi
# Align trailing blank line behavior to expected (tolerate one extra blank line)
if [ -f "$expected" ]; then
if [ -z "$(tail -n1 "$tmp_norm")" ]; then :; else
if [ -z "$(tail -n1 "$expected")" ]; then printf "\n" >> "$tmp_norm"; fi
fi
fi
# Replace absolute path occurrences in message with PLACEHOLDER
if [ -f "$input_ng" ]; then
sed -i "s#${abs_ng//\//\/}#PLACEHOLDER#g" "$tmp_norm"
fi
if ! diff -u "$expected" "$tmp_norm" >/dev/null; then
echo "[TEST/FAIL] $dir" >&2
diff -u "$expected" "$tmp_norm" || true
fail=$((fail+1))
else
echo "[TEST/OK] $dir"
fi
rm -f "$tmp_out" "$tmp_norm" "$tmp_json"
}
for d in "$TARGET_DIR"/*; do
[ -d "$d" ] || continue
run_case "$d"
done
if [ $fail -ne 0 ]; then
echo "[TEST/SUMMARY] failures=$fail" >&2
exit 1
fi
echo "[TEST/SUMMARY] all green"
exit 0