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

比方说,我有一个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我希望重构重命名B,插件会认识到这个属性的来源是生成类的DSL并相应地重构DSL.一旦我用正确的信息触发,我假设我有自己重构DSL的工具.

Resharper API是否足够开放以执行此类操作?

最佳答案 ReSharper API允许您或多或少地执行此操作,但实现起来并不是一件容易的事.

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

(通过编辑生成的类及其生成的数据,可以增加额外的复杂性.例如,如果重命名Foo.B,那将更新yaml文件中的B,但是如何更新Foo.SetB方法?我认为你可以通过实现从yaml B到Foo.SetB方法的引用来实现这一点,当重命名B时它将重命名SetB.但是,如果你重命名Foo.SetB怎么办?我不知道如何处理你还需要找到一种方法来知道yaml文件是用来生成C#文件的.

在ReSharper中提供文件支持并不是一件容易的事,但它是所有文件内容操作(导航,用法,重构,编辑等)的基础.它没有在devguide中正确记录,但有一些例子:

> ForTea – 使用手工制作的解析器为.tt文件提供语言支持
> NTriples – 使用SDK的专有解析器格式对RDF三重文件的语言支持
> AngularJs plugin – HTML文件中AngularJS表达式中嵌入的语言支持.修改现有的JS语言解析器以支持Angular所需的子集.

点赞