Coffeescript Static Analysis/Static Typechecking - Roadblocks

AAK*_*AAK 19 javascript programming-languages static-analysis coffeescript

我认为Coffeescript是一种很棒的语言!我正在寻找一些将静态分析添加到Coffeescript的项目/问题/功能.然而,经过一些搜索,我发现Coffeescript 常见问题解答和此页面表明静态分析可能不可行.

我想知道如果在Coffeescript中实现静态分析/静态类型检查存在根本问题,那么编译器中是否存在这种类型的东西?

此外,对于非平凡的检查,这是不可能的,但可能仅适用于直接分析?当我说直截了当时,我的意思是检查一些微不足道的东西,比如,用户是否使用相同的名称(在类中)或顶层(或者在相关的.coffee文件集合中的顶层)定义了两次函数.

如果有人能指出一些示例,说明为什么实施静态分析/类型检查不简单/可能/值得花时间,我将不胜感激?

非常感谢你!

the*_*rns 13

这个答案有点大脑转储,因为我对此也很感兴趣.希望能帮助到你.

我使用Google Closure Compiler静态分析CoffeeScript生成的代码.它有一个非常好的静态分析仪,我不确定是否有充分的理由在这里重新发明轮子.简单的方法是手工编写注释:

###*
   * @param {number} x
   * @param {number} y
   * @return {number}
###
adder = (x, y) -> x + y
Run Code Online (Sandbox Code Playgroud)

它有点冗长,但另一方面,你借用了闭包编译器的静态分析功能,它非常强大并能够检查很多.我实际上以更简洁的方式编写类型注释,然后有一个脚本来重写咖啡文件.我的代码最终看起来像这样:

#! {number} x {number} y @return {number}
adder = (x, y) -> x + y
Run Code Online (Sandbox Code Playgroud)

我相信你可以看到重写器很简单.

在我继续之前快速说明.如果您通过闭包编译器运行代码,请务必使用-b(裸)编译代码.闭包编译器相当不错,但它不够智能,无法进行数据流分析.默认情况下,CoffeeScript会将您的代码包装在一个匿名函数中,这将使编译器绊倒.

沿同一路径的另一个选项(这将破坏与CoffeeScript的兼容性,但会更酷)将使Coffee编译器编译如下:

adder = (number x, number y): number -> x + y
Run Code Online (Sandbox Code Playgroud)

像这样进入JS:

/***
  * @param {number} x
  * @param {number} y
  * @return {number
  */
var adder = function(x, y) {
  return x + y;
};
Run Code Online (Sandbox Code Playgroud)

然后可以在编译时将其送入闭包编译器 - 如果没有错误,编译器就可以删除所有注释.

事实上,这家伙似乎正在这样做.可悲的是,他的工作似乎处于一种不完整的状态.

在所有这些情况下,我们将艰苦的工作 - 静态类型检查 - 推迟到闭包编译器.如果您不想这样做,我会理解,但要说服我从头开始构建一个全新的静态分析工具是值得的.:)

一年后编辑:这些天我只使用打字稿.:)

  • 用于可选stativ打字的合成糖将是一个杀手:) (4认同)

Kri*_*ski 8

我不是CoffeeScript的专家,所以这可能是完全错误的答案,但它基本上归结为:CoffeeScript是一种非常富有表现力的语言,大多数语义都是动态确定的(可能是奇怪的边缘情况).这与标准ML等语言形成鲜明对比,后者具有更严格定义的语义.通常,对高阶语言进行静态分析被认为非常困难.即,对真正的高阶程序(Haskell,ML,尤其是 jval因为eval之类的东西)的静态分析很难,因为控制流程更加灵活.实际上,高阶语言的静态分析解决方案实际上只是在过去二十年左右的时间内进行了探索.(值得注意的是,请参阅Matt Might关于CFA教程样式描述的文章.)

基本上,原因是这样的:

  • 要进行分析,你必须处理通过围绕高阶函数进行流控制而产生的富有表现力的语义问题.
  • 要进行打字,通常这些语言具有更丰富的可用类型.例如,在非常典型的情况下,如果您尝试将静态类型分配给Ruby中的变量(如C,Java,ML等等),则会出现错误,但是因为程序的某些路径从不执行,一切都很好.除此之外,像Ruby这样的语言添加了大量的隐式类型转换,这些转换实际上用于执行酷编程.我熟悉的这个领域的着名工作(Ruby的静态类型的动态分析)来自我与之合作的一些人,但肯定还有其他例子.
  • 基本上,语言以更加动态的方式使用,具有更具表现力的语义,并且静态推理更加困难,并且倾向于不精确.接近这个(这几天)的基本前沿开始看起来是混合的:你可以静态地分析程序的一部分,而且还要求程序员给出一些测试用例来做一些精细的分析.

我希望这有点回答你的问题,再次,抱歉,我无法直接解决你的问题的直接问题,因为它适用于CoffeeScript,但是现在正在分析像JavaScript之类的东西上有很多工作要做.我会注意到Javascript的一些实际问题来自于它奇怪的语​​义,原型继承很难推理,特别是 eval()!通常,对这些语言的程序分析会产生某些限制(例如,完全抛弃eval!),以使分析更加可行!