diff --git a/tools/hako_check/cli.hako b/tools/hako_check/cli.hako index 1f0165a6..9b9d5672 100644 --- a/tools/hako_check/cli.hako +++ b/tools/hako_check/cli.hako @@ -252,13 +252,59 @@ static box HakoAnalyzerBox { // ---- QuickFix (text scope, MVP: HC003 using quoted) ---- _fix_text_quick(text) { if text == null { return null } - // Only HC003: using 非引用→引用化 + // QuickFix (text scope): + // - HC002 include → using + // - HC003 using 非引用 → 引用化 + // - HC016 未使用 alias の削除(using ... as Alias) + // - HC014 missing entrypoint の空スタブ提案 local lines = me._split_lines(text) local changed = 0 local out = new ArrayBox() + // 事前: alias 宣言の収集(行番号と別名) + local alias_lines = new ArrayBox() // of Map {idx, alias} local i = 0 while i < lines.size() { local ln = lines.get(i) + // HC002: include → using(相対→modulesの推測はしない;文字列そのまま移行) + { + local ltrim = me._ltrim(ln) + if ltrim.indexOf("include \"") == 0 { + // preserve indentation and trailing content (;等) + local head_len = ln.indexOf("include \"") + if head_len < 0 { head_len = 0 } + local head = ln.substring(0, head_len) + local rest = ln.substring(head_len) + // rest begins with include " + local after = rest.substring(8) // length("include ") = 8 + local newline = head + "using " + after + if newline != ln { changed = 1; out.push(newline) } else { out.push(ln) } + i = i + 1 + continue + } + } + + // HC016 用: using ... as Alias の抽出 + { + local ltrim2 = me._ltrim(ln) + if ltrim2.indexOf("using ") == 0 && ltrim2.indexOf(" as ") > 0 { + // パターン: using "X" as Alias もしくは using X as Alias + local aspos = ltrim2.indexOf(" as ") + local tail = ltrim2.substring(aspos + 4) + // Alias の終端は空白/セミコロン/行末 + local j = 0; local alias = "" + while j < tail.length() { + local ch = tail.substring(j,j+1) + if ch == " " || ch == "\t" || ch == ";" { break } + alias = alias + ch + j = j + 1 + } + if alias != "" { + local ent = new MapBox(); ent.set("idx", i); ent.set("alias", alias); alias_lines.push(ent) + } + } + } + + // HC003: using 非引用 → 引用化 local ltrim = me._ltrim(ln) if ltrim.indexOf("using ") == 0 && ltrim.indexOf('using "') != 0 { // rewrite: using X ... -> using "X" ...(X は最初の空白/セミコロン/"as" まで) @@ -289,11 +335,67 @@ static box HakoAnalyzerBox { } i = i + 1 } + // HC016: 未使用 alias の削除(安全に、完全一致のみ削除) + if alias_lines.size() > 0 { + // 再結合した out を基にテキストを作り、使用有無チェック + local cur_text = ""; local k=0; while k= 0 { + local ent = alias_lines.get(ai) + local idx = ent.get("idx") + local alias = ent.get("alias") + if me._alias_unused(cur_text, alias) == 1 { + // remove that line from out if matches using ... as alias + // ただし out の該当行が using でない場合はスキップ + if idx >= 0 && idx < out.size() { + local l = me._ltrim(out.get(idx)) + if l.indexOf("using ") == 0 && l.indexOf(" as ") > 0 && l.indexOf(" " + alias) > 0 { + // delete + out.set(idx, null) + changed = 1 + } + } + } + ai = ai - 1 + } + // null を除去 + local out2 = new ArrayBox(); local z=0; while z= 0 { return 0 } + i = i + 1 + } + return 1 + } + _has_entrypoint(text) { + if text == null { return 1 } + // Rough check: presence of 'method main(' is considered as entrypoint + if text.indexOf("method main(") >= 0 { return 1 } + return 0 + } _print_unified_diff(path, before, after) { if before == null || after == null || before == after { return 0 } // Minimal unified diff for whole file replacement(MVP)