構樹層 tree.ts
Это содержимое пока не доступно на вашем языке.
把扁平的
path -> ResolvedToken構造成巢狀樹,供各 target 按命名空間層級輸出。
為什麼需要樹
Section titled “為什麼需要樹”令牌在 JSON 裡是巢狀的(color.primary.default),但載入與解析階段都是扁平的 Map<path, ResolvedToken>(方便查重、ref 解析、暗色合併)。到了生成階段,Kotlin 的 object Color { object Primary { ... } }、Swift 的 enum Color { enum Primary { ... } }、C 的分節註解都需要巢狀結構——所以先構樹。
interface TokenTreeGroup { name: string tokens: { name: string; token: ResolvedToken }[] // 分組下的直接令牌(按原名保留) children: TokenTreeGroup[] // 子分組}轉換範例:
color.primary.default => { name: 'color', children: [ { name: 'primary', children: [ { name: 'default', tokens: [{ name: 'default', token }] } ] } ] }buildTokenTree(tokens: ResolvedToken[]): TokenTreeGroup[]
Section titled “buildTokenTree(tokens: ResolvedToken[]): TokenTreeGroup[]”入口。建一個虛擬根,對每個令牌呼叫 insert(root, segments, token, 0),最後傳回 root.children(虛擬根本身不出現)。
insert(group, segments, token, depth): void
Section titled “insert(group, segments, token, depth): void”內部遞迴函式:
const name = segments[depth]if (depth === segments.length - 1) { group.tokens.push({ name, token }) // 末段:入 tokens return}let child = group.children.find((c) => c.name === name)if (!child) { child = { name, tokens: [], children: [] } group.children.push(child) // 不存在則建子分組}insert(child, segments, token, depth + 1)同名子分組只建一次,後續同前綴的令牌複用。
pascalCase(name: string): string
Section titled “pascalCase(name: string): string”組名轉 PascalCase,用於 Kotlin object / Swift enum / ArkTS class 的分組命名:
return name.charAt(0).toUpperCase() + name.slice(1)各端怎麼用樹
Section titled “各端怎麼用樹”| 端 | 用法 |
|---|---|
| Android | emitTree 遞迴輸出 object PascalCase { ... },成員 val name = literal |
| iOS | emitTree 遞迴輸出 public enum PascalCase,成員 public static let name = ... |
| 鴻蒙 | emitTree 遞迴輸出 class PascalCase(巢狀類別不帶 export),成員 static readonly name: T = ... |
| C | 扁平 #define 風格,樹只用來生成分節註解 /* --- group.path --- */ |
詳見 五個目標平台。
Copyright © 2024-2026 FengMo WenXue