|
Posted
over 11 years
ago
by
Rpinski
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
... [More]
place your files.
Project Structure
NR6Pack solution consists of several projects:
ICSharpCode.NRefactory6.CSharp and ICSharpCode.NRefactory6.CSharp.RefactoringThese 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.TestsUnit test project of NRefactory, which is used to assure NR6Pack's quality, as well.
NR6PackMain assembly of NR6Pack.
NR6Pack.DemonstrationSmall project demonstrating how some actions/analyzers work in code editor.
NR6Pack.DocGeneratorUtility 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.VsixProject 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:
[Less]
|
|
Posted
over 11 years
ago
by
Rpinski
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
... [More]
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.RefactoringThese 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.TestsUnit test project of NRefactory, which is used to assure NR6Pack's quality, as well.
NR6PackMain assembly of NR6Pack.
NR6Pack.DemonstrationSmall project demonstrating how some actions/analyzers work in code editor.
NR6Pack.DocGeneratorUtility 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.VsixProject 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:
[Less]
|
|
Posted
over 11 years
ago
by
Rpinski
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
... [More]
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.RefactoringThese 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.TestsUnit test project of NRefactory, which is used to assure NR6Pack's quality, as well.
NR6PackMain assembly of NR6Pack.
NR6Pack.DemonstrationSmall project demonstrating how some actions/analyzers work in code editor.
NR6Pack.DocGeneratorUtility 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.VsixProject 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:
[Less]
|
|
Posted
over 11 years
ago
by
Rpinski
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
... [More]
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.RefactoringThese 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.TestsUnit test project of NRefactory, which is used to assure NR6Pack's quality, as well.
NR6PackMain assembly of NR6Pack.
NR6Pack.DemonstrationSmall project demonstrating how some actions/analyzers work in code editor.
NR6Pack.DocGeneratorUtility 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.VsixProject 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:
[Less]
|
|
Posted
over 11 years
ago
by
Rpinski
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
... [More]
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.RefactoringThese 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.TestsUnit test project of NRefactory, which is used to assure NR6Pack's quality, as well.
NR6PackMain assembly of NR6Pack.
NR6Pack.DemonstrationSmall project demonstrating how some actions/analyzers work in code editor.
NR6Pack.DocGeneratorUtility 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.VsixProject 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:
[Less]
|
|
Posted
over 11 years
ago
by
ChristophWille
Last year's event in late August was a social event for the core team members. This year, we are back with an open-to-all developer event around SharpDevelop, ILSpy, NRefactory, NR6Pack, AvalonEdit and more from our ecosystem. Here are the main "W's"
... [More]
When: Friday May 29th through Sunday May 31st
Where: TZ Inneres Salzkammergut, Bad Ischl
What: See the intro paragraph, but let's expand a bit - there is no conference program ("talks" on a schedule). The main reason for this event was and still is to get together to discuss architectural ideas (way easier and productive in person), do spikes together on certain issues (pair programming if you'd like to call it that), iron out the strategy of the products and in general get to know each other better. This year of course we'll have plenty to discuss with Build and Ignite happening about a month before our event (your guess why we scheduled it that way...).
Who: Attending core team members include Siegi, Andreas, Mike, Daniel and Peter.
If you are interested in dropping by, let us know either via the dev mailing list, or get in touch with me directly (email address is on my GitHub profile). I can provide you with travel information (from public transport to accomodation if necessary). Oh, and bring a laptop. [Less]
|
|
Posted
over 11 years
ago
by
ChristophWille
Last year's event in late August was a social event for the core team members. This year, we are back with an open-to-all developer event around SharpDevelop, ILSpy, NRefactory, NR6Pack, AvalonEdit and more from our ecosystem. Here are the main "W's"
... [More]
When: Friday May 29th through Sunday May 31st
Where: TZ Inneres Salzkammergut, Bad Ischl
What: See the intro paragraph, but let's expand a bit - there is no conference program ("talks" on a schedule). The main reason for this event was and still is to get together to discuss architectural ideas (way easier and productive in person), do spikes together on certain issues (pair programming if you'd like to call it that), iron out the strategy of the products and in general get to know each other better. This year of course we'll have plenty to discuss with Build and Ignite happening about a month before our event (your guess why we scheduled it that way...).
Who: Attending core team members include Siegi, Andreas, Mike, Daniel and Peter.
If you are interested in dropping by, let us know either via the dev mailing list, or get in touch with me directly (email address is on my GitHub profile). I can provide you with travel information (from public transport to accomodation if necessary). Oh, and bring a laptop. [Less]
|
|
Posted
over 11 years
ago
by
ChristophWille
Last year's event in late August was a social event for the core team members. This year, we are back with an open-to-all developer event around SharpDevelop, ILSpy, NRefactory, NR6Pack, AvalonEdit and more from our ecosystem. Here are the main "W's"
... [More]
When: Friday May 29th through Sunday May 31st
Where: TZ Inneres Salzkammergut, Bad Ischl
What: See the intro paragraph, but let's expand a bit - there is no conference program ("talks" on a schedule). The main reason for this event was and still is to get together to discuss architectural ideas (way easier and productive in person), do spikes together on certain issues (pair programming if you'd like to call it that), iron out the strategy of the products and in general get to know each other better. This year of course we'll have plenty to discuss with Build and Ignite happening about a month before our event (your guess why we scheduled it that way...).
Who: Attending core team members include Siegi, Andreas, Mike, Daniel and Peter.
If you are interested in dropping by, let us know either via the dev mailing list, or get in touch with me directly (email address is on my GitHub profile). I can provide you with travel information (from public transport to accomodation if necessary). Oh, and bring a laptop. [Less]
|
|
Posted
over 11 years
ago
by
ChristophWille
We have hit a major internal milestone for NR6Pack, namely completing the infrastructure setup for the project. Now we have a dedicated Web site at nr6pack.net, a forum on our community server and the build server set up for automated unit tests of
... [More]
NRefactory.
In the course of completing 0.5, Siegfried went through the codebase for a first-pass code review of the summer-of-code contributions [*] and more (he and Andreas will continue doing so in January). We want to ratchet up the scenario coverage to give you confidence in using the library, and future contributors a place to go to for "inspiration" on how to unit test their code.
Having said that, here are the news aside from our quality goals: one new refactoring, three new analyzers (we still have a few unported / untested ones in the repository that currently don't ship).
What next? Continued focus on quality, more documentation.
[*] These were part of the Mono project's GSoC. That is why we (the SharpDevelop team) didn't feel responsible back then. [Less]
|
|
Posted
over 11 years
ago
by
ChristophWille
We have hit a major internal milestone for NR6Pack, namely completing the infrastructure setup for the project. Now we have a dedicated Web site at nr6pack.net, a forum on our community server and the build server set up for automated unit tests of
... [More]
NRefactory.
In the course of completing 0.5, Siegfried went through the codebase for a first-pass code review of the summer-of-code contributions [*] and more (he and Andreas will continue doing so in January). We want to ratchet up the scenario coverage to give you confidence in using the library, and future contributors a place to go to for "inspiration" on how to unit test their code.
Having said that, here are the news aside from our quality goals: one new refactoring, three new analyzers (we still have a few unported / untested ones in the repository that currently don't ship).
What next? Continued focus on quality, more documentation.
[*] These were part of the Mono project's GSoC. That is why we (the SharpDevelop team) didn't feel responsible back then. [Less]
|