-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
目前js/ts没有关于宏的语法,所以这里并不是提出什么新语法,而只是提供一种取巧的方式来解决大部分问题。
我们可以定义多种宏语法,来对当前的语法进行修饰,从而逐个解决问题
函数宏
最基础的当然是函数宏,函数宏的语法是最简单的,它只需要接收一系列的“参数”(这些参数本质上是表达式)。所以在实际的运行中,我们只需要做简单的函数替换即可:
log(a ? 1 : 2)
// => 替换成
console.log(a ? 1 : 2)
// => 或者替换成
noop(a ? 1 : 2)所以我们只需要知道某一个函数是宏函数,然后在语法树中对其进行标记,之后的在使用到它的时候触发语法置换即可。
那么根据置换规则,开发者需要先提供一个正常js/ts环境下能使用的代码:
//#funmacro:default KEY
const log = console.log
//#endfunmarco这里#funmacro:default代表着默认值,它是纯粹的js/ts语法,不会触发宏替换
而后,我们定义置换代码:
//#funmacro:case KEY, "DEV", ["log1", "log"]
const log_1 = (...fields) => {
return globalThis.test.logger.log(...fields)
}
//#endfunmarco
//#funmacro:case KEY, "PROD", ["log2", "log"]
const log_2 = (a,...fields) => {
return console.log(`!!${a}`, ...fields)
}
//#endfunmarco这里#funmacro:case的参数是用来尝试匹配定义的宏代码:
- PROFILE_KEY: string
- PROFILE_VALUE: string/regexp
- ...RENAME_FUNS
如果匹配成功,那么: - 原本
#funmacro:default的代码会被移除 - 之后的同PROFILE_KEY的
#funmacro:case的代码不会再触发匹配,会被直接移除代码 - RENAME_FUNS会将该宏范围内的代码进行名字匹配并重构,可以定义多个
宏的嵌套
宏可以进行嵌套,但是基于缩进风格,缩进符号为/:
//#funmacro:case "RUNTIME", /Web|WebWorker/
import 'web-log-shim';
///#funmacro:case "RUNTIME", "Web", ["log_web", "log"]
const log_web = (...fields)=>console.log(...fields)
///#endfunmarco
///#funmacro:case "RUNTIME", "WebWorker", ["log_web_worker", "log"]
const log_web_worker = (...fields)=>console.log(...fields)
///#endfunmarco
//#endfunmarco核心技术重点难点
- 这一整套技术,核心的就是要在掌握“重构rename”技术,用函数重命名(这里简单的正则替换是做不了的)。
- 要注意的是,这里并不负责提供“函数内联”的功能,该功能应该由其它的组件来实现。
- 此外还有一个难点,就是对于语言服务器,它是否能正常工作?这个还需要调研
waterbang
Metadata
Metadata
Assignees
Labels
No labels