如何打破SweetJS卫生局部variables?

我正在尝试在我的项目中使用SweetJS。 为了更好地理解和学习SweetJS,我想我会从一个简单的“class”macros开始(我知道有一些存在,只是在这里玩…)。 我似乎无法让SweetJS停止与我的本地variables“自我”和“superCall”混乱。 任何想法我做错了什么? 我想var self=this保持var self=this而不是被损坏。

 macro class { case { _ $name extends $parent { constructor $cargs { $cbody ... } $($mname $margs { $mbody ... } ) ... } } => { return #{ function $name $cargs { var self=this,superCall=$parent.prototype; $cbody ... } $name.prototype = Object.create($parent.prototype); ($name.prototype.$mname = function $margs {var self=this,superCall=$parent.prototype; $mbody ... } ) ...; } } case { _ $name { $body ...} } => { return #{ class $name extends test2 { $body ... } }; } } macro super { case { $macroName.$name( $($args (,) ...) ) } => { letstx $s = [makeIdent("self", #{ $macroName })]; letstx $sC = [makeIdent("superCall", #{ $macroName })]; return #{ $sC.$name.call($s) }; } case { $macroName( $args ... ) } => { letstx $s = [makeIdent("self", #{ $macroName })]; letstx $sC = [makeIdent("superCall", #{ $macroName })]; return #{ superCall.constructor.call($s); }; } } class test extends cow { constructor(arg1, arg2) { console.log('Hello world!'); } method1(arg1, arg2) { super.method1(); } } 

这扩展到:

 function test(arg1, arg2) { var self$2 = this, superCall$2 = cow.prototype; console.log('Hello world!'); } test.prototype = Object.create(cow.prototype); test.prototype.method1 = function (arg1, arg2) { var self$2 = this, superCall$2 = cow.prototype; superCall.method1.call(self); }; 

正如你所看到的, var self=this已经变成var self$2 = this 。 我怎样才能防止这个? 我试图使用makeIdent ,但我认为我做错了什么。 有任何想法吗? 谢谢!

为了打破卫生,你需要提供超出你所在macros的范围的词法上下文。在这种情况下,通过使用$name绑定,你实际上引用了你的macros而不是内部的范围。 这使得在这种情况下可能破坏卫生。

结果,以下似乎工作:

 macro class { case { _ $name extends $parent { constructor $cargs { $cbody ... } $($mname $margs { $mbody ... } ) ... } } => { letstx $self = [makeIdent("self", #{ $name })]; return #{ function $name $cargs { var $self=this,superCall=$parent.prototype; $cbody ... } $name.prototype = Object.create($parent.prototype); ($name.prototype.$mname = function $margs {var $self=this,superCall=$parent.prototype; $mbody ... } ) ...; } } case { _ $name { $body ...} } => { return #{ class $name extends test2 { $body ... } }; } } 

请注意,我创build了一个名为$self的标识符,并将该类的名称用作我的语法对象。

在这里了解更多有关打破卫生的信息