4

Say for example I have a yaml file

immutable_class: Foo
  A: int
  B: string

which according to an imagined MSBUILD rule will generate

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;   
    }                  
}

now somewhere in my source code I will have

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

var tmp = foo.B;

I now tell resharper I wish to refactor rename B and the plugin will recognise that the source of this property is the DSL that generates the class and refactor that DSL accordingly. Assume that I have the tools to actually refactor the DSL myself once I have been triggered with the correct information.

Is the Resharper API open enough to do this kind of thing?

bradgonesurfing
  • 30,949
  • 17
  • 114
  • 217

1 Answers1

2

The ReSharper API would allow you to do this, more or less, but it's not exactly trivial to implement.

You would need to implement file support for yaml files. Once you have an abstract syntax tree, you could create a reference between the B node in the C# file and the B node in the yaml file. When renaming, ReSharper will be able to follow the references, and rename the reference text from "B" to whatever.

(Additional complexity is added by being able to edit both the generated class and the data it's generated from. E.g. if you rename Foo.B, that would update the B in the yaml file, but then how does that update the Foo.SetB method? I think you could do this by implementing a reference from the yaml B to the Foo.SetB method, and when renaming B it would rename SetB. However, what if you rename Foo.SetB? I'm not sure how to handle that. You'd also need to find a way to know that the yaml file is intended to generate the C# file)

Providing file support in ReSharper is not an easy task, but it's the foundation for all operations on the contents of files (navigation, usages, refactoring, editing, etc). It's not properly documented in the devguide, but there are examples out there:

  • ForTea - provides language support for .tt files, with a hand crafted parser
  • NTriples - language support for RDF triple files, using the SDK's proprietary parser format
  • AngularJs plugin - language support embedded inside AngularJS expressions in HTML files. Modifies the existing JS language parser to support the subset required by Angular.
citizenmatt
  • 18,085
  • 5
  • 55
  • 60
  • A couple of points. _1_ Generated code will never be edited. A partial class will be generated just like XAML so the user can customize that way. _2_ Don't need a full YAML parser just a representation of the DSL being implemented – bradgonesurfing May 12 '14 at 11:02
  • You would still need to create an abstract syntax tree of the dsl control file (yaml or not) to allow references between nodes in the trees. – citizenmatt May 12 '14 at 13:37
  • Yes of course but that AST would be much simpler than a full YAML AST. The YAML file would just be the lexer stage. I would parse it build an AST and then generate the C# code which is required. The resharper hooks would be able to modify the AST and then write back the corresponding YAML. That's the idea anyway. – bradgonesurfing May 12 '14 at 13:42