Posted
over 13 years
ago
by
DanielGrunwald
After a long pause, we have finally released the first Beta of ILSpy 2.0.
Download:
ILSpy 2.0.0.1564 Beta Binaries.zip
ILSpy 2.0.0.1564 Beta Source Code.zip
New features compared with version 1.0:
Assembly Lists
Support for decompiling
... [More]
Expression trees
Support for lifted operatores on nullables
Integrated Debugger
Decompile to Visual Basic
Search for multiple strings separated by space (searching for "Assembly manager" in ILSpy.exe would find AssemblyListManager)
Clicking on a local variable will highlight all other occurrences of that variable
Ctrl+F can be used to search within the decompiled code view
[Less]
|
Posted
over 13 years
ago
by
siegi44
In SharpDevelop 4.2 Beta we added a new feature which was partially developed by Tomas Linhart during GSoC 2010. Because it was never finished it took us some time to complete it after GSoC. One of the biggest changes after GSoC was the rewrite of
... [More]
the core engine. The engine now uses the new NRefactory 5 Type System in combination with Mono.Cecil.
It is nearly done now, only little changes to the UI will be made until the final release of SharpDevelop 4.2.
To launch the addin, simply select Analysis > Analyze Code Quality from the main menu. First you have to select a set of assemblies from the file system. After the analyzer completes the matrix above will be shown. The colours are quite simple:
Green: left uses top
Blue: left is used by top
Turquoise: left uses and is used by top
The numbers in the cells tell you how many dependencies there are from left to top or vice versa.
For example this code:
string M(string a) { return a.ToLower(); }
It has three usages of the type System.String and one usage of the method System.String.ToLower.
But in our matrix we show only one dependency on System.String, otherwise the numbers would be too noisy. This shows that there is one class from mscorlib involved in the method M.
This is only a preview and I hope it is useful to you. If you have any suggestions or find bugs, please feel free to post a comment below or on the forums.
[Less]
|
Posted
over 13 years
ago
by
MattWard
SharpDevelop 4.2 now includes support for JavaScript code
folding and code regions.
When you open a JavaScript (.js) file into the text editor any
functions that are defined can be folded.
The text editor also supports code regions.
... [More]
//#region Canvas Test
tests['canvas'] = function() {
var elem = document.createElement( 'canvas' );
return !!(elem.getContext && elem.getContext('2d'));
};
//#endregion
These regions can be folded as shown below.
[Less]
|
Posted
over 13 years
ago
by
MattWard
One of the new features in
SharpDevelop 4.2 is better support for ASP.NET MVC 3
applications. Previous versions contained project templates for
ASP.NET MVC but not much more. With SharpDevelop 4.2 the following
features
... [More]
have been added:
Razor project and file templates for C# and Visual Basic
Razor syntax highlighting
Add Controller dialog using T4 templates
Add View dialog using T4 templates
HTML folding
Now let us take at these new features.
Prerequisites
Before using SharpDevelop you should install ASP.NET MVC 3 and
IIS, either IIS Express or full IIS. You can get MVC 3 and IIS
Express from
Microsoft's Web Platform installer or download them
directly from the following pages:
ASP.NET
MVC 3
IIS
Express
After installing IIS Express make sure that you run
IISExpress.exe once so it can generate its configuration files for
your user profile. If you do not then SharpDevelop will fail to
configure IIS Express.
Creating an ASP.NET MVC Application
Now we shall create a new C# ASP.NET MVC application that uses
the Razor view engine. First run SharpDevelop and then from the
File menu select New Solution to open the New Project
dialog.
On the left in Categories select ASP.NET MVC under
C#. On the right you will see three project templates.
Empty MVC Application - creates an MVC application with a
minimal set of files.
MVC Application - creates an MVC application that uses the
Web Forms view engine (.aspx).
Razor MVC Application - creates an MVC application that uses
the Razor view engine.
Select the Razor MVC Application project template. Enter a name
for the project and select a location where the project will be
created. Click Create to create the MVC project.
If you open the Projects window by selecting
Projects from the View menu you will see that the
project template created a Home Controller, two Razor view
pages - Index and Contact, as well as installing the
jQuery and Modernizer NuGet packages.
Syntax Highlighting and Folding
If you open the a Razor file (.cshtml) you will see that there
is html folding and Razor syntax highlighting.
The Razor syntax highlighting is still under development and
does not work in all cases since it is not using Microsoft's
Razor parser and uses a basic syntax definition file. In the
screenshot above, for example, the Razor @ symbol is not correctly
highlighted in the script and link tags.
Running an ASP.NET MVC Application
In order to be able to run your application first you will need
to configure the project to use IIS Express or IIS. From the
Project menu select Project Options. Select the
Debug tab. At the bottom of this tab you will see options
for IIS Express and IIS.
For this walkthrough we will use IIS Express. Select IIS Express
and enter a port number. Then click the Create
Applicaton/Virtual Directory button. A message will then be
displayed telling you that the application/virtual directory was
created successfully. Now we can run the application.
To run the application select Run from the Debug
menu. IIS Express will then be launched and your application will
be loaded into your default web browser.
You can set breakpoints in your application and debug your code
in the standard way. For example, set a breakpoint in the
HomeController's Contact method and then click Contacts in
your browser and you will see SharpDevelop stop at the
breakpoint.
To stop debugging select Stop process from the
Debug menu. You will then see a prompt asking you to detach
or terminate the process being debugged, in this case IIS Express.
Detaching will leave IIS Express running.
File Templates
SharpDevelop includes a set of file templates for ASP.NET MVC
applications. You can create a new file using these templates by
selecting the project or a folder in the Projects window,
right clicking and select Add New Item.
Select the appropriate template, give the file a name and click
Create to add a new file to your project.
Add Controller Dialog
You can add a new controller to your project using a file
template as described in the previous section or you can use the
Add Controller dialog.
Select the Controllers folder in the Projects
window, right click and select Add Controller to show the
Add Controller dialog.
In the dialog you specify the controller's name and select
one of the templates that will be used to generate the controller
class. These templates are defined by a single T4 template that you
can edit if you want to customise it. The T4 template exists in the
following subfolder where SharpDevelop was installed:
AddIns\BackendBindings\AspNet.Mvc\ItemTemplates
Click the Add button to create a new controller from the
T4 template.
Add View Dialog
A new view can be created by using a file template or by using
the Add View dialog. Select one of the Views folders,
right click and select Add New View to show the Add View
dialog.
In the dialog you can specify the following items:
View Name - specifies the name of the view
View Engine - selects either web forms (ASPX) or Razor
view engine. The options displayed in the dialog will change
based on this selection.
Strongly Typed - allows you to generate a view based
on a type in your project.
Model - a list of types in your project. You may have
to compile your project for a class to be displayed in this drop
down.
Template - specifies which of the T4 templates will be
used when generating the view. Templates available are - Empty,
Create, Delete, Details, Edit, List.
Use Layout (Razor) - specifies whether the view will
use a layout.
Layout (Razor) - specifies the path to the layout
page. The browse button allows you to select a layout page from
those in your project.
User Master Page (ASPX) - specifies whether the view
will use a master page.
Master Page (ASPX) - specifies the path to the master
page. The browse button allows you to select a master page from
those in your project.
Main Content ID (ASPX) - specifies the main content
ID.
Partial View - used to generate a partial view.
Views generated from this dialog use T4 templates which exist in
the following folder if you need to customise them:
AddIns\BackendBindings\AspNet.Mvc\ItemTemplates
That concludes the walkthrough of the new ASP.NET MVC 3 support
in SharpDevelop. Further information on ASP.NET MVC 3 can be found
at the Getting Started with
ASP.NET MVC page. [Less]
|
Posted
over 13 years
ago
by
MattWard
Thanks to Yusuke
Kamiyamane's Fugue Icons, and icons created and remixed by
Michael Seeger, SharpDevelop 4.2 has a new look. A selection of
before and after screenshots are shown below:
SharpDevelop 4.1 Toolbar
SharpDevelop 4.2 Toolbar
SharpDevelop 4.1SharpDevelop 4.2
|
Posted
over 13 years
ago
by
siegi44
While hunting a bug related to Windows Forms, we decided to move the output pad to WPF. It now uses AvalonEdit instead of a textbox and we added support for file hyperlinks (C#, VB and NUnit); additionally you can now search through debug output by pressing Ctrl+F while the output pad is focused.
|
Posted
over 13 years
ago
by
ChristophWille
If you test a method like the following:
static void TestWithUnusedVariables()
{
var x = new Demo()
{
SomeProperty = "Hello World"
};
... [More]
var y = new List<Demo>
{
new Demo() {
SomeProperty = "nada"
},
new Demo()
{
SomeProperty = "nix"
}
};
}
And decompile with ILSpy you might be thinking that object / collection intializers are not being detected:
private static void TestWithUnusedVariables()
{
Demo demo = new Demo();
demo.SomeProperty = "Hello World";
List<Demo> list = new List<Demo>();
list.Add(new Demo
{
SomeProperty = "nada"
});
list.Add(new Demo
{
SomeProperty = "nix"
});
}
Well, you are right. The reason being that the compilers sees that my user variables are not being used, thus optimizing the code by only keeping the compiler-generated ones, thus making it impossible for us to correctly detect the initializer.
However, if you use the variables
static void TestWithUsedVariables()
{
var x = new Demo()
{
SomeProperty = "Hello World"
};
var y = new List<Demo>
{
new Demo() {
SomeProperty = "nada"
},
new Demo()
{
SomeProperty = "nix"
}
};
x.SomeProperty = "noch was";
var z = y.Count();
}
ILSpy will correctly come up with proper decompiled code:
private static void TestWithUsedVariables()
{
Demo x = new Demo
{
SomeProperty = "Hello World"
};
List<Demo> y = new List<Demo>
{
new Demo
{
SomeProperty = "nada"
},
new Demo
{
SomeProperty = "nix"
}
};
x.SomeProperty = "noch was";
int z = y.Count<Demo>();
}
In the sense of a "variable being used" the decompilation also works for variables only used to pass back a value:
static Demo TestWithReturnValue()
{
return new Demo()
{
SomeProperty = "Hello World"
};
}
ILSpy output:
private static Demo TestWithReturnValue()
{
return new Demo
{
SomeProperty = "Hello World"
};
}
Bottom line: object and collection initializers are being properly decompiled if we can ascertain that it actually is one. [Less]
|
Posted
over 13 years
ago
by
siegi44
In recent builds of SharpDevelop 4.2 and AvalonEdit I implemented the "Virtual Space" feature. This feature allows you to place the caret after the end of the line. It was necessary to properly implement rectangle selection.
You can enable it in the
... [More]
TextEditor by setting EnableVirtualSpace = true or in the SharpDevelop options. When a rectangle selection is active virtual space is enabled implicitly.
For a detailed overview/explanation see the following:
I hope you find this useful. If you find any bugs or have a suggestion, please leave a comment! [Less]
|
Posted
over 13 years
ago
by
MattWard
Here is a preview of a new feature that is planned for
SharpDevelop - integrated support for Machine.Specifications.
Machine.Specifications, or MSpec for short, is a
Behaviour Driven Development framework for .NET created by
... [More]
Aaron Jensen which takes its inspiration from
SpecUnit.NET
and RSpec.
Support for MSpec has been added thanks to
Tomasz Tretkowski.
So let us take a look at how the MSpec integration works in
SharpDevelop.
MSpec Integration
The first thing you will need to do is add a reference to MSpec
in the project that will contain your specifications. The easiest
way to do this is to use NuGet. Select your project, right click
and select Manage Packages.
Search for the Machine.Specifications package and then
click the Add button to add the NuGet package to your
project.
This will add a Machine.Specifications assembly reference to
your project.
Now let us create our first specification. We are going to
create a specification which is based on an
example provided with the MSpec source code. The specification
is for transferring an amount of money between two bank accounts
and is shown below.
using System;
using Machine.Specifications;
namespace Banking.Tests
{
[Subject(typeof(Account), "Funds transfer")]
public class when_transferring_between_two_accounts
{
static Account fromAccount;
static Account toAccount;
Establish context = () => {
fromAccount = new Account { Balance = 1m };
toAccount = new Account { Balance = 1m };
};
Because of = () =>
fromAccount.Transfer(1m, toAccount);
It should_debit_the_from_account_by_the_amount_transferred = () =>
fromAccount.Balance.ShouldEqual(0m);
It should_credit_the_to_account_by_the_amount_transferred = () =>
toAccount.Balance.ShouldEqual(2m);
}
}
MSpec uses Establish/Because/It which is
equivalent to Given/When/Then that is used
with SpecFlow. Establish is used to setup the initial state.
Because is used to define the event/action that you are
testing. It is used to test the final state and see if it
matches what is expected.
The Account class that is used by this specification is shown
below.
using System;
namespace Banking
{
public class Account
{
public decimal Balance { get; set; }
public void Transfer(decimal amount, Account toAccount)
{
}
}
}
Specifications are displayed in the Unit Tests window.
This window can be opened by selecting Unit Tests from the
View | Tools menu. The specification we have defined
will be displayed in the Unit Test window as shown below.
The Unit Tests window will update as the specification is
written in the same way it does when you are writing NUnit
tests.
To run MSpec you can right click a specification and select
Run tests or you can click the toolbar buttons at the top of
the Unit Tests window.
Failures will be highlighted in Red in the Unit Tests window.
The output from MSpec is displayed in the Output
window.
Failures are also added to the Errors window. Clicking on
an error will take you directly to the source code for the failing
test.
Now we have to fix the failures by implementing the
Account's Transfer method. The updated Transfer method is
shown below:
public void Transfer(decimal amount, Account toAccount)
{
Balance -= amount;
toAccount.Balance += amount;
}
After making this change and running MSpec again everything
passes, as shown below.
That completes the quick introduction to using MSpec with
SharpDevelop. Now let us take a look at MSpec Behaviours.
MSpec Behaviours
MSpec Behaviours are a way to group together a set of tests that
you want to re-use with different contexts. To do this you create a
separate class, add a Behaviors attribute to it, and move your
tests into that class. This behaviour class is then referenced by
using the Behaves_like syntax. An example taken from the
MSpec examples is shown below.
using System;
using Machine.Specifications;
namespace Banking.Tests
{
[Subject("Date time parsing")]
public class when_a_date_is_parsed_with_the_regular_expression_parser
: DateTimeParsingSpecs
{
Establish context = () =>
Parser = new RegexParser();
Because of = () =>
ParsedDate = Parser.Parse("2009/01/21");
Behaves_like<DateTimeParsingBehavior> a_date_time_parser;
}
[Subject("Date time parsing")]
public class when_a_date_is_parsed_by_the_infrastructure
: DateTimeParsingSpecs
{
Establish context = () =>
Parser = new InfrastructureParser();
Because of = () =>
ParsedDate = Parser.Parse("2009/01/21");
Behaves_like<DateTimeParsingBehavior> a_date_time_parser;
}
public abstract class DateTimeParsingSpecs
{
protected static DateTime ParsedDate;
protected static IParser Parser;
}
[Behaviors]
public class DateTimeParsingBehavior
{
protected static DateTime ParsedDate;
It should_parse_the_expected_date = () =>
ParsedDate.ShouldEqual(new DateTime(2009, 1, 21));
}
}
Here the behaviour of the parser returning a particular date has
been extracted and re-used across two different contexts.
SharpDevelop is aware of MSpec behaviours and will display the
underlying tests. The date time parser specifications above will be
displayed in the Unit Tests window as shown below.
For further details on MSpec behaviours take a look at the
Behaviours in MSpec post by James Gregory.
Further MSpec Information
Here is a selection of links to further information on MSpec
that you may find useful.
MSpec on Github
Introducing MSpec - Aaron Jensen's post that first
introduced MSpec.
Getting Started with MSpec
Learning
BDD - If you prefer to learn by watching a video check out Rob
Conery's BDD screencast where he discusses BDD and also covers
MSpec.
Make BDD
your BFF - Rob Conery walks through BDD with MSpec.
Teaching a String Calculator How to Behave
Behaviours in MSpec
[Less]
|
Posted
over 13 years
ago
by
siegi44
The Search and Replace engine used in SharpDevelop had a bad architecture. The concept of IDocumentIterator (for a number of documents) and ITextIterator (for a single document) leads to problems when doing manual "Find next" over multiple documents.
... [More]
It leads code duplication and there are lots of hacks to circumvent all sorts of bugs.
In the most recent alpha builds of SharpDevelop 4.2 the core parts of the Search and Replace engine were rewritten. While rewriting the code I wanted to get rid of code duplication, bugs, special cases and improve performance of the search engine. In a first step I removed all the existing engine code.
Choosing a search algorithm
There are lots of debates on .NET string search algorithm on the net. Some propose to use IndexOf, because it seems faster than Regex, others suggest to implement your own FastIndexOf. I choose to implement search using the Regex classes in the BCL for several reasons:
It is easier to maintain because it is less code. Additionally the Regex classes are well tested in contrast to a custom IndexOf.
There are multiple search modes: Normal, Wildcards and Regex. For regex, of course, we had to use the Regex classes. Wildcards are easier to translate to regex and plain text search is fast enough (if not faster in some cases), when using compiled regex.
Features like "Ignore case" and "Match whole words" are implemented with Regex easily. "Match whole words" is simply \bsearchTerm\b.
Using regex has helped to get rid of code duplication, bugs and special cases. I hope you agree with me and see the benefits of simplicity in contrast to micro and rare-case optimization.
SearchPanel: Single file search - Integrated into the AvalonEdit text editor
In AvalonEdit 4.2 Ctrl+F functionality has been directly built into the editor. The normal Search and Replace dialog has been moved to Ctrl+Shift+F. Incremental and Quick find were removed, because the SearchPanel is a very powerful replacement.
As you can see it offers some basic search options. You can use F3 to jump to the next match and Shift+F3 to move to the previous match.The SearchPanel will soon be integrated into ILSpy to allow full-text search in currently decompiled code.
Improving performance and usability of Find all in multiple files
One of the weaknesses of Find all in SharpDevelop was its speed on the one hand and on the other hand, it was locking up SharpDevelop so the user had to wait for Find all to complete.
During the redesign of the search engine, we also focused on making it thread-safe. This requires to create a list of files to search through before doing the actual search. This causes some neglectable delay and overhead. The only case in which this would turn out really bad, is a recursive directory search starting from C:\ using *.* as file mask. But this is certainly not a common scenario when working with an IDE.
The good news is, you can continue working while waiting for the search to complete. Please keep in mind that all changes you make to documents while Find all is active are not guaranteed to be recognized, depending on when the background thread processes the file.
Another good news for all those of you with multi-core CPUs: SharpDevelop 4.2 will process multiple files in parallel and display all results in real-time. So you can work with the first results while the remaining files are processed. This is implemented using the IObservable<T> and IObserver<T> interfaces.
These are the key features of the new search engine. I hope you like it. If you have any suggestions, please leave a comment. [Less]
|