Bicameral Engine
GPU-resident engine for a magic-research open-world game
Loading...
Searching...
No Matches
luau_type_check.h
Go to the documentation of this file.
1// luau_type_check.h — パッケージの Luau を、読み込む(走らせる)前に型検査する(T-0140、13 §2・ADR-0046)。
2//
3// データの流れ: 型の定義(data/types/bicameral.d.luau)→ LuauTypeChecker::Create
4// → LoadPackages が各パッケージを読む前に CheckManifest(package.luau)・CheckPackage(全部のファイル + entry の戻り値)
5// → TypeDiagnostic(どのファイルの何行目・何列目・何が違うか)。誤りがあるパッケージは読まない(理由に診断が入る)。
6// 検査は Luau.Analysis(vcpkg の luau port に入っている)の新しい型ソルバーで、全部のファイルを strict で見る
7// (ファイルの先頭の --!nonstrict などはそのファイルだけに効く)。殻で見えないグローバル(os・debug など)は検査でも見えない。
8// 決定性: 検査のたびにモジュールの状態を捨て、診断はファイル → 行 → 列 → 文の順に並べて重複を除く。同じ入力なら同じ診断の列になる。
9// ここは CPU だけ(原則 2)。
10#pragma once
11
12#include <cstdint>
13#include <expected>
14#include <memory>
15#include <string>
16#include <string_view>
17#include <vector>
18
19#include "core/aliases.h"
20
21namespace bicameral::script {
22
23 struct
24 PackageSource; // luau_package.h(luau_package.h がこのヘッダの TypeDiagnostic を使うので、ここでは include しない)
25
26 // 型の定義に必ずある型の名前(package.luau の戻り値・entry の戻り値)
27 constexpr std::string_view MANIFEST_TYPE_NAME = "PackageManifest";
28 constexpr std::string_view ENTRY_TYPE_NAME = "PackageEntry";
29
30 // 1 つの誤り。並べる順番 = ファイル → 行 → 列 → 種類 → 文
32 std::string file; // "パッケージ/パッケージの中の相対パス"(例 "combustion_test/species.luau")
33 uint32_t line = 0; // 1 始まり
34 uint32_t column = 0; // 1 始まり
35 std::string kind; // 何が違うか(日本語。「型が合わない」「知らない名前」など)
36 std::string message; // Luau の説明(英語のまま。型の名前と食い違いの場所が入る)
37
38 auto operator<=>(const TypeDiagnostic&) const = default;
39 };
40
41 // "combustion_test/species.luau:12:9: 型が合わない: Type 'string' could not be converted into 'number'"
42 [[nodiscard]] std::string FormatDiagnostic(const TypeDiagnostic& diagnostic);
43
44 // 診断の列を 1 行に(最初の maxShown 個と、残りの数)。パッケージを読まない理由に使う
45 [[nodiscard]] std::string SummarizeDiagnostics(const std::vector<TypeDiagnostic>& diagnostics, size_t maxShown = 3);
46
48 public:
49 // definitions は Luau の定義ファイルのソース(MANIFEST_TYPE_NAME・ENTRY_TYPE_NAME を export type で持つ)。
50 // 定義ファイル自体の誤り・型が無いときは error
51 [[nodiscard]] static std::expected<std::unique_ptr<LuauTypeChecker>, std::string> Create(
52 std::string_view definitions);
53
57
58 // package.luau だけ(戻り値が PackageManifest か)。マニフェストを走らせる前に使う
59 [[nodiscard]] std::vector<TypeDiagnostic> CheckManifest(const PackageSource& package);
60
61 // パッケージの全部の *.luau と、entry("init" の形)の戻り値が PackageEntry か。entry を走らせる前に使う
62 [[nodiscard]] std::vector<TypeDiagnostic> CheckPackage(const PackageSource& package, std::string_view entry);
63
64 private:
65 struct Impl;
66
67 explicit LuauTypeChecker(std::unique_ptr<Impl> impl);
68
69 std::unique_ptr<Impl> m_impl;
70 };
71
72 // 既定の型の定義のファイル: <exe のフォルダ>/data/types/bicameral.d.luau(ビルドがリポジトリの data/ を写す)
73 [[nodiscard]] fs::path DefaultTypeDefinitionsPath();
74
75 // 型の定義のファイルを読んで LuauTypeChecker を作る
76 [[nodiscard]] std::expected<std::unique_ptr<LuauTypeChecker>, std::string> CreateTypeCheckerFromFile(
77 const fs::path& definitionsFile);
78
79} // namespace bicameral::script
LuauTypeChecker(const LuauTypeChecker &)=delete
static std::expected< std::unique_ptr< LuauTypeChecker >, std::string > Create(std::string_view definitions)
LuauTypeChecker & operator=(const LuauTypeChecker &)=delete
std::vector< TypeDiagnostic > CheckPackage(const PackageSource &package, std::string_view entry)
std::vector< TypeDiagnostic > CheckManifest(const PackageSource &package)
std::string SummarizeDiagnostics(const std::vector< TypeDiagnostic > &diagnostics, size_t maxShown)
std::string FormatDiagnostic(const TypeDiagnostic &diagnostic)
fs::path DefaultTypeDefinitionsPath()
std::expected< std::unique_ptr< LuauTypeChecker >, std::string > CreateTypeCheckerFromFile(const fs::path &definitionsFile)
constexpr std::string_view ENTRY_TYPE_NAME
constexpr std::string_view MANIFEST_TYPE_NAME
auto operator<=>(const TypeDiagnostic &) const =default