A way to modify class (and general assembly) data at build time - c#

This thing I want to do might not even be worth doing but I thought it would be cool.
So what I want to do is to have some code that runs when my project is building (not only when compiling), and adds stuff to my classes based on things like attributes and general code analysis. What I want to do is have dynamically generated fields/properties that are usable through intellisense, but not visible in the actual source.
The reason for that being that I might potentially want to generate a lot of them, and outputting them to source would turn into a mess very quickly.
The potential possibilities of a system like that would be stuff like vector swizzling.
Is there maybe a library of some sort for that that I could just plug my generation code in? If not, what would be the best way to approach this, if there is any?

The most visible example of this is done by Microsoft for XAML files. During the build, a C# source file is created for each XAML file and placed in the obj/Debug or obj/Release folder. In addition to that, the MSBuild .targets file where the relevant tasks are defined is specially configured to tell Visual Studio that the generated files are required for proper IntelliSense support, which means you don't actually have to explicitly build the project in order for IntelliSense to allow items declared in XAML to be used in C# code elsewhere in the project.
This is exactly the method I use for generating code for ANTLR grammar files during a build. You can see a complete example with a build task assembly and custom .targets file here:
https://github.com/antlr/antlrcs/tree/master/AntlrBuildTask
You should be aware that some 3rd party extensions for Visual Studio completely replace the IntelliSense support with their own implementation of code completion. Some of these extensions are known to not support the MSBuild IntelliSense extensibility features required for this to work with custom code generators. If you run into problems with IntelliSense and have any extensions installed, you may find that removing the extensions completely resolves the problems.

You should compile code by the class CSharpCodeProvider/ICodeCompiler/CompilerParameters when application run.

Related

How do I change the extension of a C# DLL when compiling with Visual Studio?

I am working with a C# based "Scripting" API. To have the application recognize my script i need to have the extension of the DLL be (libname.esapi.dll). I could accomplish this by changing the AssemblyName Property of the project, but I was hoping for a more elegant solution that would keep my fully specified names a little shorter for reflection operations in the future.
Is there a proper post build commandline to do this?
libname.esapi.dll
That is not a extension change. That is a file named libname.esapi with the extension .dll. Windows/the file System was given the abiltiy to support multiple points per filename in the last Milennium. Only the stuff after the last dot is the extension.
Added to the "feature" that it will hide extensions of some file types (like .exe), this has caused no end of accidental virus installations.

How to deploy "extension method" within a VSIX extension?

Due to the wording (many meanings of "extension" and "method"), I am utterly unable to find any information about my question on the interwebs. So I am asking here:
Is it possible to deploy "extension methods" with a VSIX extension?
Clarification:
By "extension method" I mean something like
public static string SomextExtension(this string s, string p) {
retrun s + p;
}
By VSIX extension I refer to a custom extension, that gets installed via a
SomeCoolExtension.vsix
The goal is:
A user installs the VSIX, gets a few features (mainly custom code generators in my case) and additionally has access to "Hello".SomeExtension(" World"); within their source code.
I am slowly thinking this just isn't possible as I have tried everything I could come up with and as stated in the beginning, it is virtually impossible to search for it on googls.
If it really is impossible, I would at least love to understand why.
So a simple "no" might be a valid answer, but if you could elaborate, that would put my coding soul to rest :-)
Specs: I am using VS2017 and the new "Visual Studio AsyncPackage", but if you know an answer for older version, I sould be happy to try them.
You can use both approaches:
An extension (.vsix) provides the greatest flexibility, because it can provide commands (buttons on menus, context menus and toolbars) that, on demand by the user, can 1) Insert code in the active document 2) Add files with code or other assets 3) Add references to Dlls that the extension can deploy in the source folder of the project, etc. Also, it can do all that not only on demand, but automatically watching events and examining if some conditions are met, for example, a solution is created, or it is loaded, a project is added, it already contains a code file or not, it already has a reference or not, etc. Needless to say, all this flexibility comes from some complexity.
A NuGet package can add DLLs to the references or code files to a project, it can execute a PowerShell script when the NuGet package is added to a project that can modify the project, it can modify the build process adding new MSBuild targets/tasks (being the Microsoft.VSSDK.BuildTools NuGet package to create a VSIX extension the prime example). It is a one-time operation during installation on a project. After that, no events, no commands, etc. but for most scenarios is much simpler.

c# syntax checking

I create a project, and add a file. I can build an exe and so on, works fine.
Question is: what if I have multiple files in my project and I want to check the syntax of my code in one single file, and don't want to build an exe or dll?
When programming c, I press ctrl+F7 in the Visual Studio IDE and that compiles my code. I understand that there are no object files in c#. Microsoft c# reference states: "There are no object (.obj) files created as a result of invoking the C# compiler; output files are created directly.".
Is there a csc.exe switch to tell me 'ok your code looks fine', or 'the expression at line xx doesn't make sense'?
Note: please do not give the link to Command-line Building With csc.exe. All the sample command lines are for creating an exe or dll, from one or multiple files. Or on how to exclude a file from building. I don't want that.
The compiler is the syntax checker. It will tell you if your C# code is valid or not when it compiles it. Any errors or warnings will be available at the end of the attempted compilation. If there are none, then it's valid code.
You can individually compile any arbitrary piece of C# code any time you like. However, if that code depends on other code then in order for it to be valid that other code will need to be included in the compilation as well. Code which uses otherwise undefined symbols (such as classes defined in other code files) isn't valid. Those symbols need to be defined.
In the comments above you indicate a concern that such compilation of an entire project might take a long time. This would be addressed by organizing your code into smaller components. If you have one enormous C# project that takes a long time to compile, then what you have is a mess. Break it apart into smaller components. Each of those components can be in their own projects which can be compiled separately. Different projects will depend on each other, and dependent projects will be included in that compilation. But that dependency graph also shouldn't be too large and unwieldy. If it is, you still have a mess but just on a different scale. Keep the dependency graph shallow and maintainable between your projects.
Sort of answering my own question. When I posted this I wasn't aware that splitting definition and implementation in c#, as you did in c or c++, was not possible. https://social.msdn.microsoft.com/Forums/en-US/64800602-4ff2-4747-8c42-a4e1980d4124/c-no-header-files-all-code-is-written-inline-why?forum=csharplanguage states that Interfaces do this, but not in a way I asked in the original post. Looks like in a multi file project, only the IDE gives me this piece of information (syntax checking), other than building the whole project.
It appears that ctrl+F7 on a single file (Visual Studio), or -c or -fsyntax-only switches (on gcc) are not possible with c#.

Antlr4 C# targets and output path of generated files

I have a C# solution with an Antlr3 grammar file, and I'm trying to upgrade to Anltr4. It turns out the grammar was the easy part (it became better, and one third the size!). Generating the parser turned out to be the tricky part.
In the old solution I merely ran AntlrWorks to update the lexer and parser .cs files when the grammar file changed. The lexer and parser were included directly in the same project as the grammar so the framework around the parser could make use of them directly.
With the Antlr4 targets for C# I noticed that (at least by default) the output path of the generated Parser C# classes is in the intermediate directory, e.g. obj\Debug. This means I can't use the parser directly in the same project. Am I supposed to change the output path if I want the generated source usable in my sln? Don't I want it in my sln?
I tried making a separate project for the parser generation, that is, a project containing only the grammar file. When this project is built using the Antlr4 targets, the resulting assembly can be referenced from projects needing the parser classes. However, if this project is included in the solution I still don't get any intellisense in visual studio since it bases its intellisense on source files for loaded projects, so it is still not quite usable. The only way I could get it working properly was to build then unload the parser project, and have other projects reference it as an assembly file rather than a project.
EDIT:
After looking on the antlr-interest list I found this thread indicating that the problem with intellisense may be Resharpers fault. If this is the case, then my question is rather how to keep using both Antlr4 and Resharper in my solution?
https://groups.google.com/forum/#!topic/antlr-discussion/QSuJXphaBDg
I found an extension for Resharper: ReSharper.ExternalCode.
Tip for Antlr: add obj\Debug in Resharper -> Code Inspection -> External Code and reload solution.
It's works for me.
There is an easy way to get the best of both Antlr 4 and Visual Studio. You are on the right track in having a separate grammar project and implementation project, but you are missing a couple steps.
Follow these steps to get the Intellisense working
In Visual Studio, go to Tools -> Extensions and Updates and search the Online section for "ANTLR Language Support" by Sam Harwell.
This does a few things:
Adds Templates for the combined grammars.
Adds Syntax Highlighting
Adds an MSBuild target for the grammar to generate the parser.
In your solution, set up your project structure like this:
Solution
Grammar Project
ANTLR 4 Combined Grammar
Implementation Project
Folder for Links to Generated files
Listener Implementation Class
Write and Compile your grammar.
In your folder for the Links to Generated Files, Right-Click the folder and click Add -> Existing Item
Browse to Grammar Project\obj\Debug and select all the generated parser files.
This next step is important. On the Add button there is a little drop-down arrow. Click the drop-down arrow and click "Add As Link".
This will add the generated files to the implementation project using a symbolic link instead of a direct copy.
This gives the added benefit of not having to remove and re-add the parser files if you have to change your grammar later.
Intellisense should work now for your generated parser classes, and you don't
even have to disable ReSharper.
You are encountering a known bug with ReSharper. The ANTLR 3 and ANTLR 4 C# build integration is reliable, and uses long-established patterns that Microsoft uses with other languages and code generation tasks. Your options are:
Stop using ReSharper
Get the ReSharper authors to address the lack of support for this feature, or
Modify the ANTLR 4 target to work around the limitation in ReSharper, which will introduce other problems into the build which may or may not be acceptable for your use.
Option 1 is certainly the least expensive, and most likely to provide reliable long-term support for your projects.

Visual Studio 2010 Intellisense

When using Visual Studio 2010, I open an aspx and cs file to edit. (I have not created a project. I am simply opening one aspx file and one cs file from my web directory to edit.) The intellisense will not detect System.Web or a large variety of others. In fact, only basic resources seem available. Is there a way to correct this?
As you are not in a project, you lack much of the context that would permit full intellisense support. VS has no idea what assemblies are included, and does not have imports from the web.config.
Remember that Intellisense tries to only present you with code completions that actually apply in the current build configuration. Without assemblies referenced, it can't guess that you have anything at all in, say, System.Web.
the Intellisense pretty much based on the content of the "using" clauses you have in the beginning of your file. It runs based on what you have already typed against a list o possible functions contained on the "used" assemblies.
For example, if you want intelisense to have access to the Convert function you need to use the System assembly. Without it, intelisense wont know the function exists

Categories

Resources