【问题标题】:How do I search some files for cases when a certain function is called with its optional arguments?当使用可选参数调用某个函数时,如何在某些文件中搜索这些情况?
【发布时间】:2012-01-17 10:20:43
【问题描述】:

我想搜索一个文件目录,找出所有调用常用dojo.map 函数及其可选的第四个参数的情况。

我想找到类似的东西

map(an_array, a_function_by_name, x, fourth_arg);

或者也可以使用内联函数:

map(an_array, function(item, i, arr){
    //anything
}, x, fourth_arg);

我不想找到没有第四个可选参数的案例。这个函数在代码库中很常见,我必须翻遍数百个误报才能找到案例我真的很想要

//this function also can be called with just 2 or 3 parameters
//(the second parameter can still be inline or not)

map(an_array, a_function);
map(an_array, a_function, x);

我最初考虑使用 grep 处理 map([^,]*,[^,]*,[^,]*,[^,]*) 之类的东西,但我认为这还不够,因为第二个参数是一个函数,这意味着它不仅可以跨越多行,还可以在内部包含任意 Javascript 代码。


当使用所有四个参数调用函数时,找到所有情况的最有效方法是什么?我在 Linux 机器上,不介意为此安装一个小工具恰好是最简单的解决方案。

【问题讨论】:

  • 如果您在调用中确实有各种各样的变体,那么除了使用 JavaScript 解析器实际解析文件之外,没有办法做到这一点。因为它当然是 JavaScript,即使是 那个 也会很困难,因为确定你在语法上识别的函数调用是你真正担心的函数调用本身就很困难。
  • @Pointy:我知道这不是微不足道的,这就是为什么我在这里问它:) 但我不确定你是否需要一个完整的 Javascript 解析器,因为我已经知道代码格式正确 - 匹配打开并且右大括号和括号可能足以限制函数和参数
  • 也许吧;这取决于您的代码。所需要的只是一个带有不匹配的“(”或“{”字符的带引号的字符串,例如,为了搞砸一些简单的事情。而正则表达式对于处理括号嵌套不是很好。
  • 正则表达式无法做到这一点。一旦你有可能使用嵌套的标记对(如 '{' n '}' 或 '(' 和 ')'),正则表达式就不可能了。
  • @FK82:我对这里的任何解决方案都非常满意。如果你愿意,你可以使用骗子 Perl 正则表达式

标签: javascript regex search grep


【解决方案1】:

对不起,如果我在这里弄错了,我自己不太擅长使用 RegExes。也没有测试过,只是说说我的想法。 ;)

但是,您是否考虑过让 RegEx 像下面这样“不贪婪”?

map(.*?,(.*?|function\([^)]\{.*?\}),.*?,.*?)

您可能需要为此检查正确的语法...但是 AFAIK,使正则表达式“不贪婪”应该导致它尽可能多地获取匹配的重复字符。这当然也意味着,例如参数 1 或 3 可能包含一个额外的逗号,如果参数计数上升到 5 或更多,这在这种情况下是不太可能的。

也许这是解决嵌套问题的方法?也许我颠倒了它,它实际上被称为“贪婪”..?自从我使用 RegExes 以来已经有一段时间了。

非常感谢任何专家对此的帮助,这样我也可以自己学习一些东西! ;D

【讨论】:

  • 问题是正则表达式不保证{} 匹配。这意味着该模式可能会错误地匹配函数内部的}
【解决方案2】:

不知道这是否可行;未经测试,只是在下班前从我的臀部射击! :-)

您能否(暂时)从函数签名中删除第四个参数,然后在整个目录中使用 Javascript 编译器来查看什么中断?

【讨论】:

  • 遗憾的是,这没有用。 1) Javascript 允许您将任意数量的参数传递给函数,因此删除一个不一定会使事情中断 2) 该参数是可选的 3) 我不知道使用所有 4 个参数的调用在哪里。这就是问题的重点......
【解决方案3】:

您可以更改 dojo.map 函数并添加一些行来检索 arguments.caller 这将是调用 map 的函数。如果您还使用arguments[] 验证内部映射函数有多少参数,您可以在arguments[0] && arguments[0] 时使用console.log(arguments.caller)

希望对你有帮助。

【讨论】:

  • 虽然这样做的好处是即使是不太明显的调用也能找到,比如使用 call、apply 或别名,但只有在函数被调用时才能使用它,这对我来说是一个很大的负面影响。由于这是具有许多特定于浏览器的分支路径的库代码,因此静态解决方案可能会更好。
【解决方案4】:

这是一种高级方法:

  1. 将 JavaScript 解析为 AST。如果您使用 Antlrthere is a JavaScript grammar 之类的工具,您可以使用它来生成树。
  2. 遍历 AST,找到使用标识符 map 的函数调用,并检查传递给调用的参数数量。

这当然有其局限性:

  1. 它不会告诉您是否调用了 Dojo map 函数,只是使用了名为 map 的函数引用。
  2. 它不会找到通过“动态绑定”调用map 的情况。换句话说,虽然这是对map 的调用,但它不会被找到:window['map'](foo, bar, baz, bah);

尽管有这些限制,这可能足以满足您的需求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    • 2014-07-10
    相关资源
    最近更新 更多