如何在resharper插件中动态重写AST?

Ert*_*maa 10 c# resharper resharper-plugins

请求:

我希望能够编写一个分析器,它可以为某个表达式提供代理值并触发重新解析文档.

动机:

我们的代码中充斥着ABTests,它们可以处于已部署或处于活动状态且具有控制和变体组.确定测试的状态是通过数据库查找完成的.对于使用控制组部署的测试,以下表单的任何语句都将计算为false:

if(ExperimentService.IsInVariant(ABTest.Test1))
{
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试提供工具,以便在开发时通过在这种情况下将其变灰来更容易处理.事实上,这是相当有限的,并不健壮,因为我基本上必须自己玩解析器.

如果实际代码是什么

if(!ExperimentService.IsInVariant(ABTest.Test1))
Run Code Online (Sandbox Code Playgroud)

要么

if(ExperimentService.IsInVariant(ABTest.Test1) || true)
Run Code Online (Sandbox Code Playgroud)

要么

var val = ..... && (ExperimentService.IsInVariant(ABTest.Test1);
if(val){
  // val is always going to be false if we deployed control.
}
Run Code Online (Sandbox Code Playgroud)

我可以看到的一种可能的方法是允许我们编写一次触发的分析器并在实际的IDE解析发生之前重写树(或者,好吧,只是再次解析它).这些应该只发射一次并允许我们用另一个表达式替换某个表达式.这将允许我交换所有这些实验调用的真假文字.

因此,这些部分可以从所有其他IDE功能中受益,例如代码灰化无法访问的代码,还有更复杂的代码,例如永远不会有不同值的变量

显然这仅仅是一个例子,我不确定它是多么可行.对于正确的功能或已经存在的东西的任何建议都非常受欢迎.

cit*_*att 1

我认为没有一种方法是不妥协的。

\n\n

ReSharper 不支持在分析之前重写 AST - 这只会重写文件中的文本。

\n\n

您可以编写一个分析器,通过对块的内容应用“死代码”突出显示来使代码变灰if,但正如您所说,您需要解析代码并分析控制流才能使其正确,我认为这将非常困难(ReSharper 确实提供了一个控制流图,因此您可以遍历它,但这取决于您A.找到 的返回值IsInVariantB.通过任何条件跟踪该值,&&或者||语句,直到找到合适的if块)。

\n\n

或者,您可以使用属性标记IsInVariant方法ContractAnnotation,例如:

\n\n
[ContractAnnotation("=> false")]\npublic bool IsInVariant(string identifier)\n{\n  // whatever...\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这将告诉 ReSharper 的分析,该方法始终返回false(也可以说它将根据特定输入返回true/// not null false) 。null因为它总是返回,ReSharper 会将语句中的代码或分支false变灰(如果您这样做)。ifelseif (!IsInVariant(\xe2\x80\xa6))

\n\n

这里的缺点是 ReSharper 还会在语句中添加警告,if告诉您表达式始终返回false。因此,这是一种妥协,但您可以将该警告的严重性更改为“提示”,这样就不会那么具有侵入性。

\n