# w3cos-compiler 技术文档
**版本**: 0.1.0
**位置**: `crates/w3cos-compiler/`
---
## 一、概述
**w3cos-compiler** 是 W3C OS 的核心编译器,负责将 TypeScript 源代码转换为 Rust 代码,最终通过 rustc/LLVM 编译为原生二进制文件。
```
TypeScript (.ts/.tsx) → w3cos-compiler → Rust 源码 (.rs) → rustc/LLVM → 原生二进制
```
### 设计目标
- **AOT 编译**: 无运行时、无解释器、无 V8
- **零开销抽象**: TS 代码直接映射为原生机器码
- **双模式支持**: UI 应用 + 通用 TS 逻辑
---
## 二、模块结构
```
w3cos-compiler/
├── src/
│ ├── lib.rs # 入口:compile_to_rust() / compile()
│ ├── parser.rs # 解析 TS/JSON 为内部 AST
│ ├── codegen.rs # 从 AST 生成 Rust 代码
│ ├── ts_transpiler.rs # 通用 TypeScript → Rust 转译 (基于 SWC)
│ └── ts_types.rs # TypeScript 类型推断系统
├── Cargo.toml
└── tests/
```
### 核心依赖
| 依赖 | 用途 |
|------|------|
| `swc_ecma_parser` | TypeScript 词法/语法分析 |
| `swc_ecma_ast` | TypeScript AST 表示 |
| `swc_common` | 源码映射、错误报告 |
| `anyhow` | 错误处理 |
---
## 三、两种编译模式
编译器自动检测输入类型并选择相应模式:
### 模式 A: UI DSL (组件树)
**检测条件**:
- JSON 格式输入
- 导入 `@w3cos/std`
- 使用 `<Column>`, `<Text>`, `<Button>` 等 TSX 组件
**输出**: 链接 `w3cos-runtime` 的 GUI 应用
```tsx
// 输入:app.tsx
import { Column, Text, Button } from "@w3cos/std"
export default Column({
style: { gap: 20, padding: 48, background: "#0f0f1a" },
children: [
Text("W3C OS", { style: { fontSize: 42, color: "#e94560" } }),
Button("Get Started", { style: { background: "#e94560" } })
]
})
```
```rust
// 输出:main.rs
use w3cos_std::{Component, Style};
use w3cos_std::style::*;
use w3cos_std::color::Color;
fn main() {
w3cos_runtime::run_app(build_ui).expect("W3C OS app crashed");
}
fn build_ui() -> Component {
Component::column(
Style {
gap: 20_f32,
padding: Edges::all(48_f32),
background: Color::from_hex("#0f0f1a"),
..Style::default()
},
vec![
Component::text("W3C OS", Style {
font_size: 42_f32,
color: Color::from_hex("#e94560"),
..Style::default()
}),
Component::button("Get Started", Style {
background: Color::from_hex("#e94560"),
..Style::default()
}),
]
)
}
```
### 模式 B: 通用 TypeScript
**检测条件**:
- 包含 `function`, `const`, `let`, `interface` 等
- 无 `@w3cos/std` 导入
- 纯逻辑代码
**输出**: 独立 CLI 二进制
```typescript
// 输入:app.ts
interface User {
name: string;
age: number;
}
function greet(name: string): string {
return "Hello, " + name + "!";
}
function fibonacci(n: number): number {
if (n <= 1) { return n; }
let a: number = 0;
let b: number = 1;
for (let i = 2; i < n; i++) {
let temp = b;
b = a + b;
a = temp;
}
return b;
}
console.log(greet("W3C OS"));
```
```rust
// 输出:main.rs
use std::collections::HashMap;
#[derive(Debug, Clone)]
struct User {
pub name: String,
pub age: i64,
}
fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
fn fibonacci(n: i64) -> i64 {
if n <= 1 { return n; }
let mut a: i64 = 0;
let mut b: i64 = 1;
for i in 2..n {
let temp = b;
b = a + b;
a = temp;
}
b
}
fn main() {
let message = greet("W3C OS");
println!("{}", message);
}
```
---
## 四、核心 API
### `compile_to_rust()`
将 TypeScript 源码转换为 Rust 代码字符串(无文件 I/O)。
```rust
pub fn compile_to_rust(ts_source: &str) -> Result<String> {
if is_ui_dsl(ts_source) {
let tree = parser::parse(ts_source)?;
codegen::generate(&tree)
} else {
ts_transpiler::transpile(ts_source)
}
}
```
### `compile()`
将 TypeScript 源文件编译为独立的 Rust 项目。
```rust
pub fn compile(ts_source: &str, output_dir: &std::path::Path) -> Result<()> {
let is_ui = is_ui_dsl(ts_source);
let rust_code = compile_to_rust(ts_source)?;
std::fs::create_dir_all(output_dir.join("src"))?;
if is_ui {
let cargo_toml = codegen::generate_cargo_toml(output_dir)?;
std::fs::write(output_dir.join("Cargo.toml"), cargo_toml)?;
} else {
let cargo_toml = generate_standalone_cargo_toml()?;
std::fs::write(output_dir.join("Cargo.toml"), cargo_toml)?;
}
std::fs::write(output_dir.join("src/main.rs"), rust_code)?;
Ok(())
}
```
### `is_ui_dsl()`
启发式检测输入是否为 UI DSL。
```rust
fn is_ui_dsl(source: &str) -> bool {
let trimmed = source.trim();
// JSON 格式
if trimmed.starts_with('{') || trimmed.starts_with('[') {
return true;
}
// 检查 W3C OS UI 模式
let has_ui_import = trimmed.contains("@w3cos/std");
let has_component_call = ["Column(", "Row(", "Text(", "Button("]
.iter()
.any(|pat| trimmed.contains(pat));
let has_tsx_component = ["<Column", "<Row", "<Text", "<Button"]
.iter()
.any(|pat| trimmed.contains(pat));
if has_ui_import && (has_component_call || has_tsx_component) {
return true;
}
// 检查主体是否为组件表达式
let body = extract_body(trimmed);
body.starts_with("Column(") || body.starts_with("<Column")
&& !body.contains("function ")
&& !body.contains("const ")
}
```
---
## 五、TypeScript 支持范围
### ✅ 已支持特性
| 类别 | 特性 |
|------|------|
| **语法** | 函数、变量、常量、箭头函数 |
| **类型** | `string`, `number`, `boolean`, 数组,接口,类型别名 |
| **控制流** | `if/else`, `for`, `for...in`, `for...of`, `while` |
| **表达式** | 二元运算、一元运算、赋值、更新 (`++`, `--`) |
| **数据结构** | 数组字面量、对象字面量 |
| **内置函数** | `console.log()` → `println!()` |
| **数组方法** | `.push()`, `.pop()`, `.length` |
| **字符串** | 模板字面量、字符串拼接 |
| **TSX** | 组件语法、属性、子元素 |
### ❌ 不支持的特性
| 特性 | 原因 |
|------|------|
| `eval()` | 非 AOT 兼容 |
| `innerHTML` | XSS 风险,非 AOT 兼容 |
| `document.write()` | 非 AOT 兼容 |
| 动态 `import()` | 需要运行时支持 |
| `class` (部分) | 复杂继承未完全支持 |
| 泛型 | 类型擦除后等价 Rust |
---
## 六、类型推断系统
编译器使用静态类型推断将 TypeScript 类型映射为 Rust 类型:
| TypeScript | Rust |
|------------|------|
| `string` | `String` |
| `number` | `i64` / `f64` |
| `boolean` | `bool` |
| `number[]` | `Vec<i64>` |
| `string[]` | `Vec<String>` |
| `T[]` | `Vec<T>` |
| `{ name: string }` | `struct { name: String }` |
| `T \| null` | `Option<T>` |
| `any` | `serde_json::Value` |
| `Map<K, V>` | `HashMap<K, V>` |
### 推断示例
```typescript
// TypeScript
let count: number = 42; // → let count: i64 = 42;
let name: string = "W3C"; // → let name: String = "W3C".to_string();
let items: number[] = [1, 2, 3]; // → let items: Vec<i64> = vec![1, 2, 3];
interface User {
name: string;
age: number;
email?: string;
}
// → struct User { pub name: String, pub age: i64, pub email: Option<String> }
```
---
## 七、代码生成策略
### UI DSL 代码生成
```rust
fn gen_node(node: &Node, depth: usize, signal_names: &[&str]) -> String {
let indent = " ".repeat(depth + 1);
let style_code = gen_style(&node.style, depth + 1);
match &node.kind {
NodeKind::Text(content) => {
let text = node.text.as_deref().unwrap_or(content.as_str());
format!("{indent}Component::text({text:?}, {style_code})")
}
NodeKind::Button(label) => {
let lbl = node.label.as_deref().unwrap_or(label.as_str());
if let Some(ref action_str) = node.on_click {
let action = gen_event_action(action_str, signal_names);
format!("{indent}Component::button_with_click({lbl:?}, {style_code}, {action})")
} else {
format!("{indent}Component::button({lbl:?}, {style_code})")
}
}
NodeKind::Column => {
let children_code = if node.children.is_empty() {
"vec![]".to_string()
} else {
let items: Vec<String> = node.children
.iter()
.map(|c| gen_node(c, depth + 2, signal_names))
.collect();
format!("vec![\n{},\n{indent}]", items.join(",\n"))
};
format!("{indent}Component::column({style_code}, {children_code})")
}
// ...
}
}
```
### 通用 TS 代码生成
```rust
fn transpile_for(&mut self, for_stmt: &ForStmt) -> Result<()> {
// 检测:for (let i = 0; i < N; i++) → for i in 0..N
if let Some(range) = detect_range_for(for_stmt) {
self.push_indent();
self.push(&format!("for {} in ", range.var));
self.transpile_expr(&range.start)?;
self.push("..");
self.transpile_expr(&range.end)?;
self.push(" {\n");
self.indent += 1;
self.transpile_stmt_body(&for_stmt.body)?;
self.indent -= 1;
self.line("}");
return Ok(());
}
// 通用 for → while 循环
// ...
}
```
---
## 八、使用示例
### CLI 使用
```bash
# 编译 UI 应用
w3cos build examples/showcase/app.tsx -o showcase --release
# 编译通用 TS 程序
w3cos build examples/general-ts/app.ts -o myapp --release
# 运行
./showcase
./myapp
```
### 库 API 使用
```rust
use w3cos_compiler::compile_to_rust;
let ts_source = r#"
Column({
style: { gap: 8, padding: 16 },
children: [
Text("Title", { style: { font_size: 24 } }),
Button("Submit", { style: { background: "#e94560" } })
]
})
"#;
let rust_code = compile_to_rust(ts_source).unwrap();
println!("{}", rust_code);
```
---
## 九、测试覆盖
### 单元测试
```rust
#[test]
fn compile_general_ts_showcase() {
let input = r#"
interface User {
name: string;
age: number;
email?: string;
}
function greet(name: string): string {
return "Hello, " + name + "!";
}
function fibonacci(n: number): number {
if (n <= 1) { return n; }
let a: number = 0;
let b: number = 1;
for (let i = 2; i < n; i++) {
let temp = b;
b = a + b;
a = temp;
}
return b;
}
console.log(greet("W3C OS"));
"#;
let rust = compile_to_rust(input).unwrap();
assert!(rust.contains("struct User"));
assert!(rust.contains("fn greet("));
assert!(rust.contains("fn fibonacci("));
assert!(rust.contains("fn main()"));
assert!(rust.contains("for i in"));
assert!(rust.contains("println!"));
}
```
---
## 十、性能指标
| 指标 | 数值 |
|------|------|
| 编译速度 (UI DSL) | ~50-100ms |
| 编译速度 (通用 TS) | ~200-500ms (含 SWC 解析) |
| 输出二进制大小 | 2.4 MB (release) |
| 启动时间 | < 100ms |
---
## 十一、未来规划
| 版本 | 特性 |
|------|------|
| v0.2 | 完整 React Hooks 支持 |
| v0.3 | CSS `@keyframes` 动画 |
| v0.4 | 增量编译 (watch 模式) |
| v0.5 | 热重载开发服务器 |
---
## 十二、相关文件
- [`crates/w3cos-compiler/src/lib.rs`](../crates/w3cos-compiler/src/lib.rs) - 入口
- [`crates/w3cos-compiler/src/parser.rs`](../crates/w3cos-compiler/src/parser.rs) - 解析器
- [`crates/w3cos-compiler/src/codegen.rs`](../crates/w3cos-compiler/src/codegen.rs) - 代码生成
- [`crates/w3cos-compiler/src/ts_transpiler.rs`](../crates/w3cos-compiler/src/ts_transpiler.rs) - TS 转译器
- [`ARCHITECTURE.md`](../ARCHITECTURE.md) - 整体架构