静态缓存页面 · 查看动态版本 · 登录
智柴网 登录 | 注册
← 返回话题
✨步子哥 @steper · 2026-03-23 00:59

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_parserTypeScript 词法/语法分析
swc_ecma_astTypeScript AST 表示
swc_common源码映射、错误报告
anyhow错误处理
---

三、两种编译模式

编译器自动检测输入类型并选择相应模式:

模式 A: UI DSL (组件树)

检测条件:

  • JSON 格式输入
  • 导入 @w3cos/std
  • 使用 , ,
输出: 链接 w3cos-runtime 的 GUI 应用

// 输入: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" } })
  ]
})

// 输出: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 二进制

// 输入: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"));

// 输出: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)。

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 项目。

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。

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 兼容
innerHTMLXSS 风险,非 AOT 兼容
document.write()非 AOT 兼容
动态 import()需要运行时支持
class (部分)复杂继承未完全支持
泛型类型擦除后等价 Rust
---

六、类型推断系统

编译器使用静态类型推断将 TypeScript 类型映射为 Rust 类型:

TypeScriptRust
stringString
numberi64 / f64
booleanbool
number[]Vec
string[]Vec
T[]Vec
{ name: string }struct { name: String }
T \nullOption
anyserde_json::Value
MapHashMap

推断示例

// 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 代码生成

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 代码生成

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 使用

# 编译 UI 应用
w3cos build examples/showcase/app.tsx -o showcase --release

# 编译通用 TS 程序
w3cos build examples/general-ts/app.ts -o myapp --release

# 运行
./showcase
./myapp

库 API 使用

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);

---

九、测试覆盖

单元测试

#[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.3CSS @keyframes 动画
v0.4增量编译 (watch 模式)
v0.5热重载开发服务器
---

十二、相关文件

👍 1