我可以写一个resharper插件来重构生成c#代码的自定义DSL吗?

本文关键字:代码 自定义 DSL 重构 插件 resharper 一个 我可以 | 更新日期: 2023-09-27 18:03:00

比如说我有一个yaml文件

immutable_class: Foo
  A: int
  B: string

,根据想象的MSBUILD规则将生成

partial class Foo {
    public int A { set ; private get; }
    public string B { set; private get; }
    private Foo(){}
    public static Foo Default = new Foo(); 
    public Foo SetA(int value){
        var r = (Foo) this.Clone();
        r.A = value;    
        return r;
    }  
    public Foo SetB(string value){
        var r = (Foo) this.Clone();
        r.B = value; 
        return r;   
    }                  
}

现在在源代码的某个地方我将有

Foo foo = Foo.Default;
foo = foo
    .SetA(1)
    .SetB("Hello");
var tmp = foo.B;

我现在告诉resharper我希望重构rename B,插件会识别出这个属性的来源是生成类的DSL,并相应地重构该DSL。假设我有工具,一旦我被正确的信息触发,我就可以自己实际重构DSL。

Resharper API是否足够开放来做这种事情?

我可以写一个resharper插件来重构生成c#代码的自定义DSL吗?

ReSharper API或多或少会允许你这样做,但是实现起来并不是那么简单。

您需要实现对yaml文件的文件支持。一旦有了抽象语法树,就可以在c#文件中的B节点和yaml文件中的B节点之间创建引用。当重命名时,ReSharper将能够跟随引用,并将引用文本从"B"重命名为任何。

(能够编辑生成的类和生成它的数据,增加了额外的复杂性。例如,如果您重命名Foo.B,那将更新yaml文件中的B,但是如何更新Foo.SetB方法?我认为您可以通过实现从yaml BFoo.SetB方法的引用来做到这一点,并且在重命名B时,它将重命名SetB。但是,如果您重命名Foo.SetB呢?我不知道该怎么处理。您还需要找到一种方法来知道yaml文件旨在生成c#文件)

在ReSharper中提供文件支持不是一件容易的事,但它是对文件内容进行所有操作(导航、使用、重构、编辑等)的基础。在devguide中没有适当的文档说明,但是有一些例子:

  • ForTea -为.tt文件提供语言支持,使用手工制作的解析器
  • NTriples—使用SDK专有解析器格式支持RDF三元文件的语言支持
  • AngularJs插件-语言支持嵌入在HTML文件中的AngularJs表达式。修改现有的JS语言解析器,以支持Angular所需的子集。