Modify existing source files

Nov 21, 2010 at 10:10 PM

I'm really excited about Genuilder! I'm trying to write extensions that modify an C# class. For example, making all properties virtual.

Using your example code, I'm able to access the source code, get the AST and change it as required. However, the only options I can see to apply these changes are either:

  1. Save the modified AST to a new file and exclude the original CodeItem. This compiles but stops intellisense working in the original file.
  2. Save the changes back to the original code item, which is really not what I want to do!

Is there another way? Perhaps a different part of the build process can be intercepted to provide the modified code?

Thanks.

Coordinator
Nov 22, 2010 at 11:57 PM
Edited Nov 22, 2010 at 11:58 PM

Glad you like it ! :)

I don't have an easy solution right now, however maybe I have an idea... you can try to surround the original source with pre processor instruction

something like 

#if !GENUILDER

bla...

bla...

bla...

#endif

And include a source file during compilation with #define GENUILDER.

Anyway I'll be glad to help you, if you can just send me the code, this way I can easily find a way to fix that use case for the next release 

Nov 24, 2010 at 11:32 AM

Thank you for the suggestion, but I'd rather not have to start putting conditional compilation around my code.

I would like to write code like this:

[HasVirtualProperties]
public class Customer {
    public string Name {get;set;}
    public string Address {get;set;}
}

And then have a Genuilder plugin that looks for that attribute and changes the modifier on each property to be "public virtual".

Is it possible to pass an altered ITaskItem of the source file to MSBuild without actually changing the file, or having to generate a new file? Could the change be applied only in memory? Or would that break VS's intellisense? I have very weak knowledge of MSBuild, so please let me know if this is just crazy talk! :)

Coordinator
Nov 24, 2010 at 1:01 PM

Your usecase is something Genuilder must support, if it seems hard to do, I have to do something about it.

No you can't give a ITaskItem only in memory, unfortunately !

The problem seems that intellisense breaks when you exclude your item. Is it a problem for you to give me your code ? this way I can find a solution more easily.

Nov 24, 2010 at 1:52 PM

I only have a really scrappy prototype project that implements the plugin at the moment. I can email this to you.

Having played with the code some more it seems that intellisense only stops working some of the time. Perhaps I'm having some problem with not creating a dependency between the source and target files...

Coordinator
Nov 25, 2010 at 1:03 AM

Andrew, technically speaking I can't have intellisense on files which are not compiled.

For the reason listed in "Design-Time IntelliSense" :

http://msdn.microsoft.com/en-us/library/ms171468.aspx

 

However I have a workaround for you. The first one would be to generate the "source" class in another namespace than the one of the generated class.

There are two downsides :

  1. The breakpoints you put in your source class will not be hit since you will use the generated class instead.
  2. You can easily make a mistake in your code by using the wrong namespace

Point 2 can easily be solved if you put all your "source" classes in a separate assembly as internal, and make the generated ones public.

Hope it will be enough for you... I'm a little disappointed about this limitation.