SharpDevelop Community

Get your problems solved!
Welcome to SharpDevelop Community Sign in | Join | Help
in Search

Andreas Weizel

  • Beta Test of Refactoring Essentials using new Roslyn Features

    Recently we have applied some configuration changes to our diagnostic analyzers which now use 2 new features of Roslyn 1.2:

    Generated Code Detection

    From the beginning until release 4.0 Refactoring Essentials has used its own detection of generated code files in order to ignore them. Now Roslyn is able to accomplish that for us, which has some advantages:

    • Roslyn knows which code file can be suppressed for analysis before starting the analyzer. This is much earlier than doing it inside of analyzer run.
    • Roslyn detects more types of generated files than we did before.

    Further technical description

    Concurrent Execution

    Since 1.2 every analyzer can be configured to be executed concurrently. This means that Roslyn's analyzer driver is allowed to execute the same analyzer in multiple threads simultaneously to analyze more than one file at once. The intention is to improve performance of analyzer runs on big solutions.

    Further technical description

    For now we have activated concurrency for all of Refactoring Essentials' analyzers, assuming their thread-safety. Please, feel free to test our recent development builds and report us in case you see any unexpected behavior.

    Thank you for helping us to make Refactoring Essentials better!

  • Refactoring Essentials v2.0 Preview

    Currently we are working on a 2.0 release of Refactoring Essentials, that will include a considerable number of new refactorings and bugfixes/improvements - for C# and VB! Please see the complete list in our release notes.

    Because some of our devs will be on vacation next week, the official release will arrive only after September 14th, 2015. But if you are interested in experiencing the new features now, you can pick one of our development builds automatically pushed to VSIX Gallery. Don't get confused: The development builds still have a 1.2.x version number.

    Feel free to test (especially the new refactorings and analyzers) and let us know about any problems through GitHub!

    P.S.: Many thanks to all contributors and testers who helped us in the last months to make Refactoring Essentials better!

  • NRefactory & NR6Pack Finally Roslyn-ized

    In the last two months Mike Krüger has done some intensive refactoring of NRefactory 6 code and we also have restructured the project and the way how NRefactory and NR6Pack share their code:

    Analyzers & Refactorings are now plain Roslyn

    NRefactory 6 began as a thin wrapper API around some Roslyn base classes to emulate the API of NRefactory 5. The intention was to simplify porting of code actions and issues from the pre-Roslyn NRefactory 5. But since concepts of NR5 and Roslyn are not completely congruent, this led to some restrictions. An example: In Roslyn a code analyzer and a code fix may exist independently from each other. NR5 (and therefore NR6 wrapper) API didn't allow this separation. That way it wasn't possible to implement custom fixes for analyzers already shipped with Roslyn without reimplementing the analyzer.

    The wrapper API has been removed, there are no NR6-specific base classes or attributes anymore. There is no difference to analyzers or refactorings implemented plainly with Roslyn. This is the reason why we have dropped the NRefactory.Templates project (and Visual Studio extension) published in January: The ".NET Compiler Platform SDK Templates" provided by Microsoft are now sufficient.

    Changes in naming

    In NRefactory and NR6Pack "Analyzers" and "Refactorings" were previously called "Issues" and "Actions", a relict from NR5. All classes were renamed to fit Roslyn terminology. All ...CodeFixProvider classes were moved to their own .cs files.

    What's new and what's past?

    Some new analyzers were ported, like ThreadStaticAtInstanceFieldAnalyzer, FieldCanBeMadeReadOnlyAnalyzer, PublicConstructorInAbstractClassAnalyzer and several more. On the other side some analyzers/refactorings were removed because they are similar to what Roslyn already provides. For some compiler errors Roslyn delivers only the analyzers, while NR6(Pack) also implements appropriate code fixes. Therefore only the CodeFixProviders were kept, while the analyzers have been dropped.

    There are also some examples of refactorings which were combined into one, so their number might even have decreased without loosing features.

    NRefactory "vs." NR6Pack

    In previous releases NR6Pack project was more or less a reduced copy of NRefactory 6 project consisting of file links to analyzers and refactorings in ICSharpCode.NRefactory6.CSharp.Refactoring project. It was quite hard to keep both projects synchronized all the time. After recent restructuring all projects have clear responsibilities:

    • ICSharpCode.NRefactory6.Shared: Shared project containing utility classes used by NR6 and NR6Pack
    • NR6Pack: Now regularly contains all the analyzers and refactorings. No copies or links of these classes are needed anymore, the NR6Pack project will simply be used by MonoDevelop as well as by NR6Pack Visual Studio extension.
    • NR6Pack.Tests: This new project hosts all unit tests for analyzers and refactorings of NR6Pack.
    • ICSharpCode.NRefactory6.CSharp: Rest of NRefactory 6 remaining after excluding all utility APIs and analyzers/refactorings. This includes code completion and special refactoring features mainly needed by MonoDevelop.
    • ICSharpCode.NRefactory6.CSharp.Tests: Contains unit tests for features of ICSharpCode.NRefactory6.CSharp.

     

    All this work should simplify maintenance and extending of NR/NR6Pack a lot. And there are still some unported analyzers and refactorings you could help us with!

     


    UPDATE 2015-06-25:

    We have finished the next evolutional step with NR6Pack and separated all refactorings and analyzers to a new project: "Refactoring Essentials" were born! Read the full post.

  • Adopt a (Code) Issue

    Even if NR6Pack already brings more than 150 C# analyzers and refactorings from NRefactory to Visual Studio: There are still many more, which haven't been ported to Roslyn yet. Therefore we invite developers to "adopt" unported code issues and help us with extending NR6Pack with new cool features!

    What do you need to participate?

    1. Have a look at our list of unported code actions and issues. Especially interesting items are marked in bold. If possible, please prefer one of these.
    2. Check if somebody has already created a GitHub issue for porting your chosen item. If no GitHub issue exists, please add one (something like "Port of <XYZ>Issue to Roslyn") and assign it to yourself. If it already exists, but has no assignee, feel free to take it over.
    3. Start porting :-)
      Integration of analyzers has been described here. Unported code issues are already part of ICSharpCode.NRefactory6.CSharp.Refactoring project, but they still need to be linked into NR6Pack project additionally. Unported code issues always contain their old code (based on NRefactory 5) as comment. So porting means understanding that code and reimplementing it with Roslyn API. You can use other finished analyzers and refactorings as orientation.
    4. Don't forget to reactivate the appopriate unit test, too! Tests of inactive refactorings are currently marked as "Ignore". Unit tests are very helpful anyway for understanding how a refactoring should behave and for later testing of your work.
    5. Finally create a GitHub push request with your changes. We will review and merge it, if it's alright.

    We're looking forward to your collaboration! And if you have more questions, please ask them in our forum or on GitHub.

  • NRefactory Issue & Action Templates for Developers

    UPDATE 2015-04-29:The extension described here has been removed. For more details please see this post.

     

    As a little helpful supplement to my last post we have released the new extension "NRefactory Issue & Action Templates for Developers" on Visual Studio Gallery:

    It's purpose: Allowing developers to quickly start with their own code refactoring or analyzer for NRefactory or NR6Pack. The templates include all the basic glue code for you, so you just need to continue with your logic.

    After installing the extension (available for Visual Studio 2013 and 2015), you will see a new directory "NRefactory" in your C# templates, when opening the "Add New Item" dialog:

     

    The template uses the chosen class name as basis for your action/issue:

     

    Please note that these templates are only intended for analyzer implementation based on NRefactory 6!

  • Adding a New Analyzer to NR6Pack

    UPDATE 2015-06-25: Since NR6Pack was reborn as the separate project "Refactoring Essentials" (see here), this post is no longer applicable. We will provide a new post with up-to-date information soon!

    This post is for people interested in contributing to NR6Pack (and NRefactory) project. Let's assume you want to implement a new analyzer for NR6Pack. How would you integrate it? I'll explain the structure of NR6Pack solution and where you should place your files.

    Project Structure

    NR6Pack solution consists of several projects:

    • ICSharpCode.NRefactory6.CSharp and ICSharpCode.NRefactory6.CSharp.Refactoring
      These two are main parts of NRefactory library itself. They were added to solution to simplify work. There are no references from NR6Pack to NRefactory on project/assembly level.
    • ICSharpCode.NRefactory6.Tests
      Unit test project of NRefactory, which is used to assure NR6Pack's quality, as well.
    • NR6Pack
      Main assembly of NR6Pack.
    • NR6Pack.Demonstration
      Small project demonstrating how some actions/analyzers work in code editor.
    • NR6Pack.DocGenerator
      Utility generating HTML output files with all supported actions and analyzers by reading code files in NR6Pack project. This tool is launched as post-build event on every compilation.
    • NR6Pack.Vsix
      Project with manifest needed to generate a VSIX package of NR6Pack to be installed through Visual Studio Extension Gallery.

    First of all it's important to know that NR6Pack doesn't bring it's own analyzers. Instead, it links analyzer class files contained in NRefactory 6 project:

    Links:

     

    Original class files:

    That also means that if you integrate a new analyzer to NR6Pack, you actually add it to NRefactory!

     

    A Simple Analyzer

    I'll use the example of a very simple (and not very useful) analyzer, that suggests to prefix every class name with a "C" (like in "CString"). Let's call the analyzer "ClassNameWithoutPrefixIssue".

    Step 1: Write a Test

    Before starting implementation carefully think about what your analyzer should do and what it shouldn't. The best way to describe that is a unit test:

    ClassNameWithoutPrefixIssueTests.cs

    We use NUnit as our test framework. NRefactory offers an API for unit testing of analyzers and refactorings. Therefore every analyzer test class must be derived from InspectionActionTestBase (tests of plain refactorings use ContextActionTestBase instead). You can define the input code and the expected output code after applying the fix. Dollar signs ($) enclose the code part that your analyzer should recognize as a fixable issue. This is equal to the part that is often underlined in editor as warning or error.

    Test classes should be added to ICSharpCode.NRefactory6.Tests project. For analyzer tests please use sub-directory CSharp/CodeIssues:

    By the way: By "CodeIssues" NRefactory means diagnostic analyzers. "CodeActions" are NRefactory's synonym for code refactorings. These different names come from pre-Roslyn era and were used by SharpDevelop and MonoDevelop.

     

    Step 2: Implement the Analyzer

    Now it's time to create our ClassNameWithoutPrefixIssue:

    ClassNameWithoutPrefixIssue.cs

    I'm not going to dive into details of analyzer implementation here. But just a hint: If you already had a look at examples of analyzer creation with Roslyn, you will very likely have seen differing base classes. The reason is that NRefactory 6 has a wrapper layer around some Roslyn base classes. It originates from former NRefactory versions, that were based on their own C# parser instead of Roslyn.

    The new class should be added to ICSharpCode.NRefactory6.CSharp.Refactoring project first. You can choose the sub-directory CodeIssues/Custom:

    Now your analyzer is part of NRefactory library and can be tested using previously created unit tests.

     

    Step 3: Link Analyzer to NR6Pack

    As already said, NR6Pack just links code files from NRefactory. Therefore your final step will be to add a link to ClassNameWithoutPrefixIssue.cs in NR6Pack project. Just take the class file in Solution Explorer and drag it into CodeIssues/Custom directory of NR6Pack project while holding ALT key pressed:

    This creates a link to the file instead of copying it.

    Now you can experience your analyzer in action: Make sure that NR6Pack.Vsix is your start-up project. When pressing F5 (or the "Start" toolbar button) in Visual Studio a second Visual Studio instance is started, where NR6Pack with the new analyzer is automatically installed. You can open a project and test if it detects your code issue and allows to apply the implemented fix:

     

  • Installing and Using NR6Pack NuGet Package in Projects

    UPDATE 2015-06-25: NR6Pack has been reborn as the separate project "Refactoring Essentials". Therefore please don't use the old NR6Pack packages anymore, but install the new VS Extension or NuGet package instead!

    Now our refactoring and analyzers extension NR6Pack is available on NuGet! It's a good alternative for all who want to include NR6Pack analyzers to a project without requiring every developer in team to install the extension as add-on in Visual Studio (2015). And it's really easy to integrate, as I'll show you here.

    Let's start with a very simple console application project doing something very bad: It compares two float values using "==", a common mistake that might be hard to find later:

    The additional analyzers shipped with NR6Pack are able to find such common coding issues. Open the NuGet management page of your project, search for "nr6pack" and click on "Install":

    After a short download and installation you will see a new "NR6Pack" entry in your project's "Analyzers":

    You will also notice a change in your code editor: Comparison of the float variables is now underlined and a yellow bulb is shown with a tooltip describing the code issue:

    Through the yellow bulb you also have the option to directly fix the issue:

    The issue is also shown as warning when compiling the project in Visual Studio as well as from console (think of build servers!):

     

    Of course, I have shown just one example of coding issue detected by NR6Pack. There is a complete list available on project page.

  • Walking the hierarchy of members up and down

    Since SharpDevelop 4 you should already be familiar with the key shortcut F6 or the context menu entry "Find derived symbols" on members and types:

    When called on a type, it shows a popup with all types deriving from it (or for interfaces: implementing that interface) and allows to navigate to them. When called on a virtual or interface member, a popup with overriding or implementing members will appear:

     

    With the new SharpDevelop 5 RC the same is possible in the opposite direction: "Find base symbols" (previously "Find base classes") is now working on class members, too:

    Called on a virtual/override member it will show base members:

     

    The same is possible for interface members, that have been implemented by selected member:

     

    The new shortcut Ctrl+F6 can be used as well. This feature should make it much easier to navigate in your project.

  • SharpDevelop 5 and its new Resource Editor

    Since we have recently changed management of resources in SharpDevelop project, our good old WinForms-based ResourceEditor needed a review. So we chose rewriting its UI in WPF to implement a better architecture and solve some focusing issues:

     

    Basically our editor for *.resx files works in the same manner as before:

    • You can add new string resources or load image resources from external files through context menu.
    • Cut/Copy/Paste resource items, even between two open resource files.
    • Edit contents of a resource item by selecting it and using the view area below the list.
    • Edit comments for resource items (through context menu)

    But there is one new helpful feature: Now you are able to filter the list using the text field at the top:

     

    After pressing Enter key or clicking the "Update" button the filter text is applied to list. When pressing Escape key in the text field, current filter is reset.

    Now it should be much easier to work with big resource files.

  • Code formatting in SharpDevelop 5

    There's another cool thing we now present in SharpDevelop 5: A configurable code formatting engine.

    The first that you see for from this feature is the new "Reformat" command in editor's context menu:

    You can select a block of code and reformat it. If you don't select anything, whole file will be reformatted.

    So

    becomes

     

    Define your rules

    Of course, you may change the way how SD formats your code. The formatting options used generally for your SD installation can be set in options dialog through "Coding" -> "C#" -> "Formatting":

     All available settings are organized in expandable groups. At the top you see a preset selection. Presets are predefined profiles for some common coding styles.

    To overwrite your current formatting settings with a preset, just select one and click on "Reset to:".

     

    Define solution's rules

    One main advantage is the policy system, which allows to not only set global settings, but also define settings which are specific to a certain solution. There's a new entry in every solution file's properties:

    Clicking on the "..." button opens the solution's formatting settings dialog:

     

    Initially all settings are set to "(global)", which means they use the same values as defined in global settings. That way you can override some of the settings specifically for your solution.

    All solution-specific formatting settings are saved in a <SolutionName>.sln.sdsettings file, which can be added to version control like the solution itself.

     

    Define project's rules

    What you just have seen for solutions is also possible on project level: The project settings now have a "Code Formatting" tab:

    Initially all settings are set to "(solution)" here, so they inherit what has been defined in solution (which on the other hand can refer to global options). All project-specific formatting rules you set here will be saved along with the project (in a .csproj.sdsettings file) and submitted to version control.

    Posted Mar 27 2014, 10:11 PM by Rpinski with no comments
    Filed under:
  • What's new in Class Browser?

    In SharpDevelop 5 we have rewritten the Class Browser available through View -> Classes menu.

    After opening a solution you will see the hierarchy of all projects, namespaces, types and type members. Double-clicking a type or type member opens it in code editor view. A right click shows a context menu with some navigation and refactoring commands:

     

    Class Browser as ILSpy

    Besides the features well-known from SharpDevelop 4 the Class Browser is able to load and browse any external .NET assembly, similar to ILSpy. Therefore SharpDevelop maintains a workspace, which contains the solution (if one is loaded) and any external assembly manually added to it. The workspace is persisted, so all assemblies loaded in it will be available again after restarting SharpDevelop. This is also similar to ILSpy's behaviour.

    Use the Class Browser's toolbar to add an assembly from file system or from GAC:

      

    A double-click on a type or member will open it in code view with decompiled contents of the type:

    This is possible even if no solution is loaded.

     

    Browsing types and members on-the-fly

    From code editor you can open any symbol in Class Browser using the appropriate context menu command:

    If the assembly containing that symbol is not already in Class Browser's workspace, it's temporarily added and the symbol's node is selected in tree:

    ...

    Since the assembly is added only temporarily in this case, it will disapear again after restart. You can permanently store it in Class Browser's workspace using the assembly node's context menu:

     

  • Publishing an AddIn for SharpDevelop 5

    As I've already mentioned in my first post about new AddIn Manager, SharpDevelop team has introduced an online repository where you can publish your SharpDevelop 5 AddIns. It's visible to all SharpDevelop users, so they can download and install your AddIn directly through AddIn Manager. We utilize NuGet as well-proven platform for package distribution. The repository itself is hosted on MyGet.

    This blog post will show you how to package your AddIn and make it visible to other people.

    Creating an initial AddIn package

    Let's start with a small fictitious sample AddIn called "AddInManager2Test" adding an item to the main menu. More details about development of SharpDevelop AddIns can be found in our Wiki. Assume that the AddIn has been already created using the "SharpDevelop addin" solution template and contains some code:

    Begin with the .addin file describing your AddIn. Here it's important to set a unique identity:

    <AddIn name="AddInManager Test"
           author ="Andreas Weizel"
           description="Just a test AddIn to demonstrate how to publish it.">
       
        <Manifest>
            <Identity name="AWeizel.AddInManager2Test" />
        </Manifest>
       
        <Runtime>
            <Import assembly="AWeizel.AddInManager2Test.dll"/>
        </Runtime>
       
        <!-- Some sample menu item added to main menu -->
        <Path name = "/SharpDevelop/Workbench/MainMenu/Help">
            <MenuItem id="ShowAddInManager2"
                      label="Test Command"
                      class="
    AWeizel.AddInManager2Test.ShowCommand"/>
        </Path>
    </AddIn>

    Since our repository is based on NuGet, you will need an additional NuGet package description (also called "Nuspec"). It's another XML file which you can add directly to your solution. In this example I've called it AddInManager2Test.nuspec, corresponding to project name:

    <?xml version="1.0"?>
    <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
      <metadata>
        <id>AWeizel.AddInManager2Test</id>
        <version>1.0.0.0</version>
        <authors>Andreas Weizel</authors>
        <owners>Andreas Weizel</owners>
        <projectUrl>http://www.icsharpcode.net/OpenSource/SD/</projectUrl>
        <description>AddInManager2 Test AddIn</description>
        <tags>SharpDevelop AddIn Test Blog</tags>
      </metadata>
      <files>
        <file src="bin\Release\AddInManager2Test.addin" target="" />
        <file src="bin\Release\AWeizel.AddInManager2Test.dll" target="" />
      </files>
    </package>

    You can freely define most of the metadata values as you need them. Most important are <id> and <version>. The NuGet ID uniquely identifies the package in repository. I recommend to use the same value here as for the AddIn's identity defined earlier in .addin file. The version tag allows to distinguish between different releases of the AddIn.

    In the <files> section you define which files have to be added to your package release. You can refer to your build output directory and add at least the assembly file and the .addin file. The target attribute in <file> element sets a relative subdirectory path, where the file will be placed inside the package's directory structure (remember: NuGet packages are technically ZIP archives). SharpDevelop AddIn packages must contain all .dll and .addin files at root level, otherwise later installation will fail. That's why the target attribute has been left empty in the example above.

    To learn more about possible options in Nuspec, please have a look at the Nuspec Reference in NuGet Docs.

    Before creating and publishing the package from the .nuspec file, you now need:

    • a recent NuGet command line client, which you can download from NuGet server (simply download nuget.exe and add it to your PATH)
    • a MyGet account to get write-access to SharpDevelop package feed. Registration is free.

    After these steps open a command line in your project directory and create the package specifying the name of your .nuspec file:

    nuget pack AddInManager2Test.nuspec

    In my example this generates the package file AWeizel.AddInManager2Test.1.0.0.0.nupkg named after NuGet ID and version of the package. So it's time to push it to public repository:

    nuget push AWeizel.AddInManager2Test.1.0.0.0.nupkg <Your-API-Key> -s https://www.myget.org/F/sharpdevelop/

    Replace "<Your-API-Key>" with the key you see in your myget.org account settings under "Security":

    After successful publishing your new package should be available in AddIn Manager:

    From here it can be downloaded and finally installed:

     

    Publishing an update

    After publishing an AddIn for the first time you will likely want to release an update later. So make all changes you need to the code and increase the package version in your .nuspec file:

    <?xml version="1.0"?>
    <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
      <metadata>
        <id>AWeizel.AddInManager2Test</id>
        <version>1.0.1.0</version>
        <authors>Andreas Weizel</authors>
        <owners>Andreas Weizel</owners>
        <projectUrl>http://www.icsharpcode.net/OpenSource/SD/</projectUrl>
        <description>AddInManager2 Test AddIn</description>
        <tags>SharpDevelop AddIn Test Blog</tags>
      </metadata>
      <files>
        <file src="bin\Release\AddInManager2Test.addin" target="" />
        <file src="bin\Release\AWeizel.AddInManager2Test.dll" target="" />
      </files>
    </package>

    After executing

    nuget pack AddInManager2Test.nuspec

    again the command line utility will generate a new name for the package: AWeizel.AddInManager2Test.1.0.1.0.nupkg

    After pushing it to repository using

    nuget push AWeizel.AddInManager2Test.1.0.1.0.nupkg <Your-API-Key> -s https://www.myget.org/F/sharpdevelop/

    all users of your AddIn will see the update in AddIn Manager:

     

  • Introducing new AddIn Manager in SharpDevelop 5

    SharpDevelop allows to extend its features by installing AddIns. With SharpDevelop 5 we bring a new and modern AddIn Manager interface into the IDE:

    AddIn Manager's main window

    It can be found at the same place as the former one (Menu Tools / AddIn Manager) and supports installing, updating, disabling or removing SharpDevelop AddIns.

     

    Installation from online repository

    Completely new is the possibility to connect to an online NuGet-based repository to install or update your AddIns from. A central repository maintained by the SharpDevelop Team will be predefined. Custom repositories can be added through preferences. You can browse all repositories through the navigation bar on the left:

    Navigation bar

    Selecting one repository shows installable NuGet packages containing SharpDevelop AddIns:

    Available NuGet package

    After clicking the Install button the NuGet package is downloaded and marked for installation:

    NuGet package marked for installation

    A restart of SharpDevelop is needed to complete the installation. After that the AddIn will be shown in the "Installed" list:

    AddIn installed from a NuGet repository

     

    Installation from package file

    As in SharpDevelop 4 we still support installing an AddIn from an *.sdaddin package file:

     Installation from archive button

    Selecting an .sdaddin package

    After selecting the archive the procedure is the same as with NuGet-packaged AddIns: It will be marked for installation ...

    Archive package marked for installation

    ... and after restarting SharpDevelop it will appear among other AddIns:

     

    AddIn installed from an .sdaddin package

     

Powered by Community Server (Commercial Edition), by Telligent Systems
Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.