自动将多个variables定义重构为单个声明

有没有可以用“每个variables一个声明”自动replace多个variables定义的工具或方法?

例如,给出

var one = 1, two = 2, three = 3; 

我想自动重构这个:

 var one = 1; var two = 2; var three = 3; 

这与执行ESLint one-var规则相同 ,但是对现有的“错误”实现进行自动重构。 ESLint规则不包括在可用的“自动修复”列表中。

您可以使用程序转换系统(PTS)来执行此操作。 这些工具将源代码parsing为内部表单(通常为抽象语法树),并允许您应用源代码转换来修改这些表单(树)。 完成所有更改后,可以从修改后的AST中重新生成源代码。

有些PTS仅通过一种特定的语言(通常是单一的方言)进行连线。 更一般的接受用作参数的编程语言的描述,因此可用于多种语言的任务。

转换通常是以forms书写的,

  if you see *this*, replace it by *that* when *condition* 

在哪里是用源语言expression的模式,而条件是控制是否应用特定变换的额外谓词。 [考虑“如果你看到x / x,当x不等于0时,用1代替它”作为条件的一个激励例子]。 这通常意味着您可以在不知道AST的精确细节的情况下编写这些转换…并且可以写完这些转换之后再读取这些转换。

例如,我们的DMS软件重新构build工具包 ( JavaScript前端)可以执行OP的操作。 JavaScript前端包含JavaScript的精确语法,确保源代码正确parsing为AST; 它还包含一个AST文本prettyprinter用于重新生成文本作为最终结果。

我们假设ECMASCript语句的语法规则已被标记为关联

 [associative] StatementList = StatementList Statement; 

这意味着你可以在这个列表的中间插入一个语句,而不用改变它的(关联)列表类属性。

以下是(未经testing但非常接近正确的)DMS要完成这项工作的规则:

 domain ECMAScript~MicrosoftNetscape; -- establish language/dialect of interest rule break_up_complex_var1(vdl: VariableDeclarationList, i: Identifier): StatementList -> StatementList = "var \vdl, \i;" -> "var \vdl; var \i;" rule break_up_complex_var2(vdl: VariableDeclarationList, i: Identifier, e: Expression): StatementList -> StatementList = "var \vdl, \i=\e;" -> "var \vdl; var \i=\e;" ruleset break_up_complex_var = { break_up_complex_var1, break_up_complex_var2 }; 

DMS重写规则具有名称(例如, break_up_complex_var1… var2 ),并且在用元语词 “….”编写的模式上操作,这些模式用于区分目标语言(例如,ECMAScript)语法与DMS的语法重写规则。 在元引用中,反斜线项是一个模式匹配variables ,它表示规则头中描述的语言子句,例如“\ i”是指标识符。 每个规则都有一个模式( this )和replace( that ),每个都用metaquotes写成。 有趣的– >运营商的手段被取代 。 模式匹配variables由左手边匹配; 如果在那里提到模式variables,那么绑定值被隐含地replace为正确的模式。 这些特定的规则不需要条件。 关于DMS重写规则forms的更多细节可以在这里find 。

我们提供了两条规则:一条处理未初始化的variables声明的情况,一条处理初始化声明的情况。 在这两种情况下,我们都指定我们要在var语句中select最后一个声明的内容,并为最后一个声明创build一个单独的var语句。 规则集告诉DMS将这两个规则视为一个集合; 很容易让DMS在任何地方都应用这个规则集(在这个答案中没有显示)。 在应用这些规则之后,DMS会印刷修改后的AST。 瞧。

这是一个相当简单的DMS应用程序,但它是完全可靠的。 图案精确; 除了他们描述的东西外,他们无法匹配任何东西。 DMS所要求的replace是语法良好的; 这并不能保证正确性,但是正确性的必要条件,在定义规则时也会遇到很多愚蠢的错误。 在这种情况下,规则在语义上是正确的,这应该是明显的检查(例如,你可以读别人写的规则)。

鉴于初始化expression式(“上下文释放”)可以任意复杂,并包含嵌套(){}和[],你不能实现这与文本黑客攻击,甚至文字黑客与正则expression式。 临时秘书处是正确的做法。

通常我们用DMS做更复杂的事情,但这是一个很好的简单例子。 (我不确定这个任务是否会激发实际使用DMS来实现OP的特定效果)。 更有趣的任务包括使用数十个转换(通常还有一些额外的代码分析,这里没有讨论),所有这些都是为了实现复杂的大规模重构任务。 应该清楚的是,这些更复杂的任务也不能通过正则expression式来实现。

Interesting Posts