Browse Source

Merge branch 'newNR' of github.com:icsharpcode/SharpDevelop into newNR

pull/59/merge
Peter Forstmeier 12 years ago
parent
commit
54c45c04a4
  1. 5
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpContextActionWrapper.cs
  2. 27
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs
  3. 20
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/RenameFileToMatchTypeNameContextAction.cs
  4. 16
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs
  5. 7
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlUnresolvedFile.cs
  6. 13
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin
  7. 5
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
  8. 10
      src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptions.cs
  9. 8
      src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptionsPanel.xaml
  10. 149
      src/AddIns/Debugger/Debugger.AddIn/Pads/ClassBrowserSupport.cs
  11. 40
      src/AddIns/Debugger/Debugger.AddIn/Service/DebuggerCommands.cs
  12. 113
      src/AddIns/Debugger/Debugger.AddIn/Service/ExecuteProcessWindow.xaml
  13. 84
      src/AddIns/Debugger/Debugger.AddIn/Service/ExecuteProcessWindow.xaml.cs
  14. 6
      src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs
  15. 4
      src/AddIns/Debugger/Debugger.Core/Breakpoint.cs
  16. 16
      src/AddIns/Debugger/Debugger.Core/Module.cs
  17. 7
      src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs
  18. 21
      src/AddIns/Debugger/Debugger.Core/Process.cs
  19. 7
      src/AddIns/Debugger/Debugger.Core/TypeSystemExtensions.cs
  20. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionViewModel.cs
  21. 6
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/GoToEntityAction.cs
  22. 54
      src/AddIns/Misc/AddInManager2/AddInManager2.Tests/AvailableAddInsViewModelTests.cs
  23. 11
      src/AddIns/Misc/AddInManager2/Project/Src/Model/AddInSetup.cs
  24. 3
      src/AddIns/Misc/AddInManager2/Project/Src/ViewModel/AvailableAddInsViewModel.cs
  25. 3
      src/AddIns/Misc/AddInManager2/Project/Src/ViewModel/InstalledAddInsViewModel.cs
  26. 52
      src/Main/Base/Project/Dom/ClassBrowser/AssemblyTreeNode.cs
  27. 46
      src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs
  28. 84
      src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserWorkspace.cs
  29. 27
      src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs
  30. 82
      src/Main/Base/Project/Dom/ClassBrowser/MemberTreeNode.cs
  31. 56
      src/Main/Base/Project/Dom/ClassBrowser/NamespaceTreeNode.cs
  32. 53
      src/Main/Base/Project/Dom/ClassBrowser/ProjectTreeNode.cs
  33. 53
      src/Main/Base/Project/Dom/ClassBrowser/SolutionTreeNode.cs
  34. 70
      src/Main/Base/Project/Dom/ClassBrowser/TypeDefinitionTreeNode.cs
  35. 48
      src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs
  36. 257
      src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs
  37. 11
      src/Main/Base/Project/Dom/IAssemblyModel.cs
  38. 6
      src/Main/Base/Project/Dom/IEntityModel.cs
  39. 47
      src/Main/Base/Project/Dom/IEntityModelContext.cs
  40. 6
      src/Main/Base/Project/Dom/IMemberModel.cs
  41. 31
      src/Main/Base/Project/Dom/IModelCollection.cs
  42. 2
      src/Main/Base/Project/Dom/INamespaceModel.cs
  43. 6
      src/Main/Base/Project/Dom/ITypeDefinitionModel.cs
  44. 4
      src/Main/Base/Project/Dom/ITypeDefinitionModelCollection.cs
  45. 15
      src/Main/Base/Project/Dom/ModelCollectionLinq.cs
  46. 9
      src/Main/Base/Project/Dom/ModelCollectionTreeNode.cs
  47. 17
      src/Main/Base/Project/Dom/SimpleModelCollection.cs
  48. 7
      src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
  49. 9
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  50. 5
      src/Main/Base/Project/Refactoring/ContextAction.cs
  51. 6
      src/Main/Base/Project/Refactoring/IContextAction.cs
  52. 17
      src/Main/Base/Project/Src/Internal/Doozers/PadDescriptor.cs
  53. 1
      src/Main/Base/Project/Src/Project/CompilableProject.cs
  54. 18
      src/Main/Base/Project/Src/Project/MSBuildConfigurationOrPlatformNameCollection.cs
  55. 4
      src/Main/Base/Project/Util/SharpDevelopExtensions.cs
  56. 2
      src/Main/Base/Test/Dom/CSharpModelTestBase.cs
  57. 29
      src/Main/SharpDevelop/Dom/AssemblyModel.cs
  58. 28
      src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs
  59. 5
      src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserTreeNodesFactory.cs
  60. 18
      src/Main/SharpDevelop/Dom/ClassBrowser/OpenAssemblyCommand.cs
  61. 9
      src/Main/SharpDevelop/Dom/MemberModel.cs
  62. 2
      src/Main/SharpDevelop/Dom/ModelFactory.cs
  63. 10
      src/Main/SharpDevelop/Dom/NamespaceModel.cs
  64. 16
      src/Main/SharpDevelop/Dom/NestedTypeDefinitionModelCollection.cs
  65. 36
      src/Main/SharpDevelop/Dom/TopLevelTypeDefinitionModelCollection.cs
  66. 33
      src/Main/SharpDevelop/Dom/TypeDefinitionModel.cs
  67. 18
      src/Main/SharpDevelop/Project/Configuration/SolutionConfigurationOrPlatformNameCollection.cs
  68. 5
      src/Main/SharpDevelop/SharpDevelop.csproj
  69. 3
      src/Main/SharpDevelop/Workbench/WpfWorkbench.cs

5
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpContextActionWrapper.cs

@ -47,6 +47,11 @@ namespace CSharpBinding.Refactoring
get { return description; } get { return description; }
} }
public string GetDisplayName(EditorRefactoringContext context)
{
return DisplayName;
}
public void Execute(EditorRefactoringContext context) public void Execute(EditorRefactoringContext context)
{ {
SD.AnalyticsMonitor.TrackFeature(provider.ID); SD.AnalyticsMonitor.TrackFeature(provider.ID);

27
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs

@ -42,6 +42,29 @@ namespace CSharpBinding.Refactoring
return identifier.Parent is TypeDeclaration || identifier.Parent is DelegateDeclaration; return identifier.Parent is TypeDeclaration || identifier.Parent is DelegateDeclaration;
} }
public override string DisplayName
{
get {
return "Move type to file";
}
}
public override string GetDisplayName(EditorRefactoringContext context)
{
CSharpFullParseInformation parseInformation = context.GetParseInformation() as CSharpFullParseInformation;
if (parseInformation != null) {
SyntaxTree st = parseInformation.SyntaxTree;
Identifier identifier = (Identifier) st.GetNodeAt(context.CaretLocation, node => node.Role == Roles.Identifier);
if (identifier == null)
return DisplayName;
return StringParser.Parse("${res:SharpDevelop.Refactoring.MoveClassToFile}",
new StringTagPair("FileName", MakeValidFileName(identifier.Name)));
}
return DisplayName;
}
public override async void Execute(EditorRefactoringContext context) public override async void Execute(EditorRefactoringContext context)
{ {
SyntaxTree st = await context.GetSyntaxTreeAsync().ConfigureAwait(false); SyntaxTree st = await context.GetSyntaxTreeAsync().ConfigureAwait(false);
@ -131,9 +154,5 @@ namespace CSharpBinding.Refactoring
return name.RemoveAny(Path.GetInvalidFileNameChars()) + ".cs"; return name.RemoveAny(Path.GetInvalidFileNameChars()) + ".cs";
return name + ".cs"; return name + ".cs";
} }
public override string DisplayName {
get { return "Move type to file"; }
}
} }
} }

20
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/RenameFileToMatchTypeNameContextAction.cs

@ -52,13 +52,29 @@ namespace CSharpBinding.Refactoring
} }
} }
public override string DisplayName { public override string DisplayName
{
get { get {
// TODO Use the string from resource file! But this needs to become GetDisplayName(context) first.
return "Rename file to match type name"; return "Rename file to match type name";
} }
} }
public override string GetDisplayName(EditorRefactoringContext context)
{
CSharpFullParseInformation parseInformation = context.GetParseInformation() as CSharpFullParseInformation;
if (parseInformation != null) {
SyntaxTree st = parseInformation.SyntaxTree;
Identifier identifier = (Identifier) st.GetNodeAt(context.CaretLocation, node => node.Role == Roles.Identifier);
if (identifier == null)
return DisplayName;
return StringParser.Parse("${res:SharpDevelop.Refactoring.RenameFileTo}",
new StringTagPair("FileName", MakeValidFileName(identifier.Name)));
}
return DisplayName;
}
string MakeValidFileName(string name) string MakeValidFileName(string name)
{ {
if (name == null) if (name == null)

16
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs

@ -3,19 +3,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Runtime.Remoting.Lifetime;
using System.Threading;
using ICSharpCode.NRefactory; using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Xml;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.XmlEditor;
namespace ICSharpCode.XamlBinding namespace ICSharpCode.XamlBinding
{ {
@ -37,12 +28,7 @@ namespace ICSharpCode.XamlBinding
{ {
string prefix, memberName; string prefix, memberName;
string name = ParseName(expression, out prefix, out memberName); string name = ParseName(expression, out prefix, out memberName);
string namespaceUrl; string namespaceUrl = context.ActiveElement.LookupNamespace(prefix);
if (prefix == "")
namespaceUrl = context.ActiveElement.Namespace;
else
namespaceUrl = context.ActiveElement.ResolvePrefix(prefix);
if (string.IsNullOrEmpty(memberName)) { if (string.IsNullOrEmpty(memberName)) {
IType type = ResolveType(namespaceUrl, context.ActiveElement.LocalName); IType type = ResolveType(namespaceUrl, context.ActiveElement.LocalName);
IMember member = type.GetMembers(m => m.Name == name).FirstOrDefault(); IMember member = type.GetMembers(m => m.Name == name).FirstOrDefault();

7
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlUnresolvedFile.cs

@ -111,14 +111,17 @@ namespace ICSharpCode.XamlBinding
public static ITypeReference CreateTypeReference(string @namespace, string localName) public static ITypeReference CreateTypeReference(string @namespace, string localName)
{ {
if (@namespace.StartsWith("clr-namespace:", StringComparison.OrdinalIgnoreCase)) { if (@namespace == null)
return new UnknownType(null, localName);
if (@namespace.StartsWith("clr-namespace:", StringComparison.OrdinalIgnoreCase))
return CreateClrNamespaceTypeReference(@namespace.Substring("clr-namespace:".Length), localName); return CreateClrNamespaceTypeReference(@namespace.Substring("clr-namespace:".Length), localName);
}
return new XamlTypeReference(@namespace, localName); return new XamlTypeReference(@namespace, localName);
} }
public static ITypeReference CreateClrNamespaceTypeReference(string @namespace, string localName) public static ITypeReference CreateClrNamespaceTypeReference(string @namespace, string localName)
{ {
if (@namespace == null)
return new UnknownType(null, localName);
int assemblyNameIndex = @namespace.IndexOf(";assembly=", StringComparison.OrdinalIgnoreCase); int assemblyNameIndex = @namespace.IndexOf(";assembly=", StringComparison.OrdinalIgnoreCase);
IAssemblyReference asm = DefaultAssemblyReference.CurrentAssembly; IAssemblyReference asm = DefaultAssemblyReference.CurrentAssembly;
if (assemblyNameIndex > -1) { if (assemblyNameIndex > -1) {

13
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin

@ -68,6 +68,15 @@
</MenuItem> </MenuItem>
</Path> </Path>
<Path name="/SharpDevelop/Workbench/MainMenu/Debug">
<Condition name = "IsProcessRunning" isdebugging="False" action="Disable">
<MenuItem id = "DebugExecutable"
insertbefore = "ExecutionControlSeparator"
label = "${res:MainWindow.Windows.Debug.DebugExecutable}"
class = "Debugger.AddIn.DebugExecutableMenuCommand"/>
</Condition>
</Path>
<Path name = "/SharpDevelop/Workbench/Pads"> <Path name = "/SharpDevelop/Workbench/Pads">
<Pad id = "BreakPointsPad" <Pad id = "BreakPointsPad"
category = "Debugger" category = "Debugger"
@ -149,4 +158,8 @@
<Class class="Debugger.AddIn.Visualizers.ObjectGraphVisualizerDescriptor" /> <Class class="Debugger.AddIn.Visualizers.ObjectGraphVisualizerDescriptor" />
<Class class="Debugger.AddIn.Visualizers.GridVisualizerDescriptor" /> <Class class="Debugger.AddIn.Visualizers.GridVisualizerDescriptor" />
</Path> </Path>
<Path name="/SharpDevelop/TreeNodeFactories">
<Class id="DebuggerTreeNodesFactory" class="ICSharpCode.SharpDevelop.Gui.Pads.DebuggerTreeNodesFactory" />
</Path>
</AddIn> </AddIn>

5
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj

@ -111,6 +111,7 @@
<Compile Include="Pads\CallStackPad.cs"> <Compile Include="Pads\CallStackPad.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Pads\ClassBrowserSupport.cs" />
<Compile Include="Pads\WatchPadCommands.cs" /> <Compile Include="Pads\WatchPadCommands.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Options\DebuggingOptions.cs" /> <Compile Include="Options\DebuggingOptions.cs" />
@ -138,6 +139,9 @@
<DependentUpon>EditBreakpointScriptWindow.xaml</DependentUpon> <DependentUpon>EditBreakpointScriptWindow.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Service\ExecuteProcessWindow.xaml.cs">
<DependentUpon>ExecuteProcessWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Tooltips\DebuggerTooltipControl.xaml.cs" /> <Compile Include="Tooltips\DebuggerTooltipControl.xaml.cs" />
<Compile Include="Tooltips\VisualizerPicker.cs" /> <Compile Include="Tooltips\VisualizerPicker.cs" />
<Compile Include="TreeModel\SharpTreeNodeAdapter.cs" /> <Compile Include="TreeModel\SharpTreeNodeAdapter.cs" />
@ -311,6 +315,7 @@
<Page Include="Options\DebuggingSymbolsPanel.xaml" /> <Page Include="Options\DebuggingSymbolsPanel.xaml" />
<Page Include="Pads\CommonResources.xaml" /> <Page Include="Pads\CommonResources.xaml" />
<Page Include="Service\EditBreakpointScriptWindow.xaml" /> <Page Include="Service\EditBreakpointScriptWindow.xaml" />
<Page Include="Service\ExecuteProcessWindow.xaml" />
<Page Include="Tooltips\DebuggerTooltipControl.xaml" /> <Page Include="Tooltips\DebuggerTooltipControl.xaml" />
<Page Include="Tooltips\VisualizerPicker.xaml" /> <Page Include="Tooltips\VisualizerPicker.xaml" />
<Page Include="Visualizers\GraphVisualizer\Presentation\NodeControlResources.xaml" /> <Page Include="Visualizers\GraphVisualizer\Presentation\NodeControlResources.xaml" />

10
src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptions.cs

@ -69,6 +69,16 @@ namespace ICSharpCode.SharpDevelop.Services
set { PS.Set<bool>("Debugger.PauseOnHandledExceptions", value); } set { PS.Set<bool>("Debugger.PauseOnHandledExceptions", value); }
} }
public bool AskForArguments {
get { return PS.Get<bool>("Debugger.AskForArguments", false); }
set { PS.Set<bool>("Debugger.AskForArguments", value); }
}
public bool BreakAtBeginning {
get { return PS.Get<bool>("Debugger.BreakAtBeginning", false); }
set { PS.Set<bool>("Debugger.BreakAtBeginning", value); }
}
public ShowIntegersAs ShowIntegersAs { public ShowIntegersAs ShowIntegersAs {
get { return PS.Get<ShowIntegersAs>("Debugger.ShowIntegersAs", ShowIntegersAs.Decimal); } get { return PS.Get<ShowIntegersAs>("Debugger.ShowIntegersAs", ShowIntegersAs.Decimal); }
set { PS.Set<ShowIntegersAs>("Debugger.ShowIntegersAs", value); } set { PS.Set<ShowIntegersAs>("Debugger.ShowIntegersAs", value); }

8
src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptionsPanel.xaml

@ -34,5 +34,13 @@
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.SuppressNGENOptimization}" /> IsChecked="{sd:OptionBinding debugger:DebuggingOptions.SuppressNGENOptimization}" />
</widgets:StackPanelWithSpacing> </widgets:StackPanelWithSpacing>
</GroupBox> </GroupBox>
<GroupBox Margin="5" Header="{sd:Localize Dialog.Options.IDEOptions.Debugging.WithoutSource}">
<widgets:StackPanelWithSpacing SpaceBetweenItems="5">
<CheckBox Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.AskForArguments}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.AskForArguments}" />
<CheckBox Content="{sd:Localize Dialog.Options.IDEOptions.Debugging.BreakAtBeginning}"
IsChecked="{sd:OptionBinding debugger:DebuggingOptions.BreakAtBeginning}" />
</widgets:StackPanelWithSpacing>
</GroupBox>
</StackPanel> </StackPanel>
</gui:OptionPanel> </gui:OptionPanel>

149
src/AddIns/Debugger/Debugger.AddIn/Pads/ClassBrowserSupport.cs

@ -0,0 +1,149 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.IO;
using Debugger;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.ClassBrowser;
using System.Linq;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
/// <summary>
/// Description of ClassBrowserSupport.
/// </summary>
public static class ClassBrowserSupport
{
public static void Attach(Debugger.Process process)
{
var classBrowser = SD.GetService<IClassBrowser>();
classBrowser.SpecialNodes.Add(new DebuggerProcessTreeNode(process));
}
public static void Detach(Debugger.Process process)
{
var classBrowser = SD.GetService<IClassBrowser>();
var nodes = classBrowser.SpecialNodes
.Where(n => n.Model == process)
.ToArray();
foreach (var node in nodes) {
classBrowser.SpecialNodes.Remove(node);
}
}
}
class DebuggerTreeNodesFactory : ITreeNodeFactory
{
public Type GetSupportedType(object model)
{
if (model is Debugger.Process)
return typeof(Debugger.Process);
if (model is Debugger.Module)
return typeof(Debugger.Module);
return null;
}
public ICSharpCode.TreeView.SharpTreeNode CreateTreeNode(object model)
{
if (model is Debugger.Process)
return new DebuggerProcessTreeNode((Debugger.Process)model);
if (model is Debugger.Module)
return new DebuggerModuleTreeNode((Debugger.Module)model);
return null;
}
}
class DebuggerProcessTreeNode : ModelCollectionTreeNode
{
Debugger.Process process;
IMutableModelCollection<Debugger.Module> modules;
public DebuggerProcessTreeNode(Debugger.Process process)
{
if (process == null)
throw new ArgumentNullException("process");
this.process = process;
this.modules = new SimpleModelCollection<Debugger.Module>(this.process.Modules);
this.process.ModuleLoaded += ModuleLoaded;
this.process.ModuleUnloaded += ModuleUnloaded;
}
void ModuleLoaded(object sender, ModuleEventArgs e)
{
modules.Add(e.Module);
}
void ModuleUnloaded(object sender, ModuleEventArgs e)
{
modules.Remove(e.Module);
}
protected override object GetModel()
{
return process;
}
protected override IModelCollection<object> ModelChildren {
get {
return modules;
}
}
protected override System.Collections.Generic.IComparer<ICSharpCode.TreeView.SharpTreeNode> NodeComparer {
get {
return NodeTextComparer;
}
}
public override object Text {
get {
return Path.GetFileName(process.Filename);
}
}
public override object Icon {
get {
return IconService.GetImageSource("Icons.16x16.Debug.Start");
}
}
}
class DebuggerModuleTreeNode : AssemblyTreeNode
{
Debugger.Module module;
public DebuggerModuleTreeNode(Module module)
: base(CreateAssemblyModel(module))
{
if (module == null)
throw new ArgumentNullException("module");
this.module = module;
}
public override object Icon {
get {
return IconService.GetImageSource("PadIcons.LoadedModules");
}
}
public override object Text {
get {
return module.Name;
}
}
static IAssemblyModel CreateAssemblyModel(Module module)
{
// references??
IEntityModelContext context = new AssemblyEntityModelContext(module.Assembly.UnresolvedAssembly);
IAssemblyModel model = SD.GetRequiredService<IModelFactory>().CreateAssemblyModel(context);
if (model is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)model).Update(EmptyList<IUnresolvedTypeDefinition>.Instance, module.Assembly.TopLevelTypeDefinitions.SelectMany(td => td.Parts).ToList());
}
return model;
}
}
}

40
src/AddIns/Debugger/Debugger.AddIn/Service/DebuggerCommands.cs

@ -3,11 +3,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq; using System.Linq;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Debugging; using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor;
using Microsoft.Win32;
using ICSharpCode.SharpDevelop.Services; using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn namespace Debugger.AddIn
@ -97,4 +100,41 @@ namespace Debugger.AddIn
return BreakpointUtil.BreakpointsOnCaret.Any(); return BreakpointUtil.BreakpointsOnCaret.Any();
} }
} }
public class DebugExecutableMenuCommand : AbstractMenuCommand
{
public override void Run()
{
if (DebuggingOptions.Instance.AskForArguments) {
var window = new ExecuteProcessWindow { Owner = SD.Workbench.MainWindow };
if (window.ShowDialog() == true) {
string fileName = window.SelectedExecutable;
// execute the process
StartExecutable(fileName, window.WorkingDirectory, window.Arguments);
}
} else {
OpenFileDialog dialog = new OpenFileDialog() {
Filter = ".NET Executable (*.exe) | *.exe",
RestoreDirectory = true,
DefaultExt = "exe"
};
if (dialog.ShowDialog() == true) {
string fileName = dialog.FileName;
// execute the process
StartExecutable(fileName);
}
}
}
void StartExecutable(string fileName, string workingDirectory = null, string arguments = null)
{
DebuggerService.CurrentDebugger.BreakAtBeginning = DebuggingOptions.Instance.BreakAtBeginning;
DebuggerService.CurrentDebugger.Start(new ProcessStartInfo {
FileName = fileName,
WorkingDirectory = workingDirectory ?? Path.GetDirectoryName(fileName),
Arguments = arguments
});
}
}
} }

113
src/AddIns/Debugger/Debugger.AddIn/Service/ExecuteProcessWindow.xaml

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="ICSharpCode.SharpDevelop.Services.ExecuteProcessWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Select process to debug..."
WindowStartupLocation="CenterOwner"
WindowState="Normal"
WindowStyle="ToolWindow"
ShowInTaskbar="False"
Height="250"
Width="596">
<Grid
Height="217">
<Grid.RowDefinitions>
<RowDefinition
Height="1.4*" />
<RowDefinition
Height="0.2*" />
</Grid.RowDefinitions>
<Label
Content="Executable"
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="19.5,28.5,0,0"
Width="92"
Height="25" />
<TextBox
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="0,28.5,84.5,0"
Width="368"
Height="25"
Name="pathTextBox" />
<Button
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="502.5,28.5,0,0"
Width="25"
Height="25"
Content="..."
Name="pathButton"
Click="pathButton_Click" />
<TextBox
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="133.5,81,0,0"
Width="368"
Height="25"
Name="argumentsTextBox" />
<Label
Content="Arguments"
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="19.5,81,0,0"
Width="92"
Height="31" />
<Button
Content="..."
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Left"
Width="25"
Click="workingDirectoryButton_Click"
Height="25"
VerticalAlignment="Bottom"
Margin="502.5,0,0,30.875"
Name="workingDirectoryButton" />
<TextBox
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="133.5,134,0,0"
Width="368"
Height="25"
Name="workingDirectoryTextBox" />
<Label
Content="Working directory"
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="19.5,134,0,0"
Width="113"
Height="31" />
<DockPanel
Grid.Row="1"
LastChildFill="False">
<Button
DockPanel.Dock="Left"
HorizontalAlignment="Center"
x:Name="ExecuteButton"
Click="ExecuteButton_Click"
Content="Execute"
Width="100" />
<Button
DockPanel.Dock="Right"
x:Name="CancelButton"
Content="Cancel"
Click="CancelButton_Click"
Width="100" />
</DockPanel>
</Grid>
</Window>

84
src/AddIns/Debugger/Debugger.AddIn/Service/ExecuteProcessWindow.xaml.cs

@ -0,0 +1,84 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Forms;
namespace ICSharpCode.SharpDevelop.Services
{
/// <summary>
/// Interaction logic for ExecuteProcessWindow.xaml
/// </summary>
public partial class ExecuteProcessWindow : Window
{
public ExecuteProcessWindow()
{
InitializeComponent();
}
public string SelectedExecutable {
get {
return pathTextBox.Text;
}
set {
pathTextBox.Text = value;
workingDirectoryTextBox.Text = Path.GetDirectoryName(value);
}
}
public string WorkingDirectory {
get {
return workingDirectoryTextBox.Text;
}
set {
workingDirectoryTextBox.Text = value;
}
}
public string Arguments {
get {
return argumentsTextBox.Text;
}
}
void pathButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog() {
Filter = ".NET Executable (*.exe) | *.exe",
InitialDirectory = workingDirectoryTextBox.Text,
RestoreDirectory = true,
DefaultExt = "exe"
};
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
SelectedExecutable = dialog.FileName;
}
}
void ExecuteButton_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(SelectedExecutable))
return;
this.DialogResult = true;
}
void CancelButton_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
void workingDirectoryButton_Click(object sender, RoutedEventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog() {
SelectedPath = workingDirectoryTextBox.Text
};
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
workingDirectoryTextBox.Text = dialog.SelectedPath;
}
}
}
}

6
src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs

@ -10,6 +10,7 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
using Debugger; using Debugger;
using ICSharpCode.SharpDevelop.Gui.Pads;
using Debugger.AddIn; using Debugger.AddIn;
using Debugger.AddIn.Tooltips; using Debugger.AddIn.Tooltips;
using Debugger.AddIn.TreeModel; using Debugger.AddIn.TreeModel;
@ -232,6 +233,7 @@ namespace ICSharpCode.SharpDevelop.Services
public void Detach() public void Detach()
{ {
ClassBrowserSupport.Detach(CurrentProcess);
CurrentDebugger.Detach(); CurrentDebugger.Detach();
} }
@ -438,6 +440,7 @@ namespace ICSharpCode.SharpDevelop.Services
CurrentProcess.Paused += debuggedProcess_DebuggingPaused; CurrentProcess.Paused += debuggedProcess_DebuggingPaused;
CurrentProcess.Resumed += debuggedProcess_DebuggingResumed; CurrentProcess.Resumed += debuggedProcess_DebuggingResumed;
CurrentProcess.Exited += (s, e) => debugger_ProcessExited(); CurrentProcess.Exited += (s, e) => debugger_ProcessExited();
ClassBrowserSupport.Attach(CurrentProcess);
UpdateBreakpointIcons(); UpdateBreakpointIcons();
} }
@ -448,6 +451,7 @@ namespace ICSharpCode.SharpDevelop.Services
DebugStopped(this, EventArgs.Empty); DebugStopped(this, EventArgs.Empty);
} }
ClassBrowserSupport.Detach(CurrentProcess);
CurrentProcess = null; CurrentProcess = null;
CurrentThread = null; CurrentThread = null;
CurrentStackFrame = null; CurrentStackFrame = null;
@ -462,7 +466,7 @@ namespace ICSharpCode.SharpDevelop.Services
CurrentProcess = e.Process; CurrentProcess = e.Process;
CurrentThread = e.Thread; CurrentThread = e.Thread;
CurrentStackFrame = CurrentThread != null ? CurrentThread.MostRecentUserStackFrame : null; CurrentStackFrame = CurrentThread != null ? CurrentThread.MostRecentStackFrame : null;
// We can have several events happening at the same time // We can have several events happening at the same time
bool breakProcess = e.Break; bool breakProcess = e.Break;

4
src/AddIns/Debugger/Debugger.Core/Breakpoint.cs

@ -72,8 +72,8 @@ namespace Debugger
foreach(var symbolSource in module.Process.Debugger.SymbolSources) { foreach(var symbolSource in module.Process.Debugger.SymbolSources) {
var seq = symbolSource.GetSequencePoint(module, this.FileName, this.Line, this.Column); var seq = symbolSource.GetSequencePoint(module, this.FileName, this.Line, this.Column);
if (seq != null) { if (seq != null) {
ICorDebugFunction corFuction = module.CorModule.GetFunctionFromToken(seq.MethodDefToken); ICorDebugFunction corFunction = module.CorModule.GetFunctionFromToken(seq.MethodDefToken);
ICorDebugFunctionBreakpoint corBreakpoint = corFuction.GetILCode().CreateBreakpoint((uint)seq.ILOffset); ICorDebugFunctionBreakpoint corBreakpoint = corFunction.GetILCode().CreateBreakpoint((uint)seq.ILOffset);
corBreakpoint.Activate(enabled ? 1 : 0); corBreakpoint.Activate(enabled ? 1 : 0);
corBreakpoints.Add(corBreakpoint); corBreakpoints.Add(corBreakpoint);
} }

16
src/AddIns/Debugger/Debugger.Core/Module.cs

@ -64,6 +64,22 @@ namespace Debugger
} }
} }
[Debugger.Tests.Ignore]
public uint GetEntryPoint()
{
try {
if (symReader != null)
return symReader.GetUserEntryPoint();
var info = TypeSystemExtensions.GetInfo(Assembly);
var ep = info.CecilModule.EntryPoint;
if (ep != null)
return ep.MetadataToken.ToUInt32();
return 0;
} catch {
return 0;
}
}
[Debugger.Tests.Ignore] [Debugger.Tests.Ignore]
public ISymUnmanagedReader SymReader { public ISymUnmanagedReader SymReader {
get { get {

7
src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs

@ -88,7 +88,9 @@ namespace Debugger
{ {
public bool Handles(IMethod method) public bool Handles(IMethod method)
{ {
return method.ParentAssembly.GetModule().SymReader != null; return method.ParentAssembly.GetModule().HasSymbols
&& !IsCompilerGenerated(method)
&& GetSequencePoint(method, 0) != null;
} }
public bool IsCompilerGenerated(IMethod method) public bool IsCompilerGenerated(IMethod method)
@ -171,6 +173,7 @@ namespace Debugger
var sequencePoint = realSeqPoints.FirstOrDefault(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)) ?? var sequencePoint = realSeqPoints.FirstOrDefault(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)) ??
realSeqPoints.FirstOrDefault(p => iloffset <= p.ILOffset); realSeqPoints.FirstOrDefault(p => iloffset <= p.ILOffset);
if (sequencePoint != null) {
// VB.NET sometimes produces temporary files which it then deletes // VB.NET sometimes produces temporary files which it then deletes
// (eg 17d14f5c-a337-4978-8281-53493378c1071.vb) // (eg 17d14f5c-a337-4978-8281-53493378c1071.vb)
string name = Path.GetFileName(sequencePoint.Filename); string name = Path.GetFileName(sequencePoint.Filename);
@ -180,7 +183,7 @@ namespace Debugger
} }
} }
if (sequencePoint != null) {
sequencePoint.Filename = GetSourceCodePath(method.ParentAssembly.GetModule().Process, sequencePoint.Filename); sequencePoint.Filename = GetSourceCodePath(method.ParentAssembly.GetModule().Process, sequencePoint.Filename);
} }

21
src/AddIns/Debugger/Debugger.Core/Process.cs

@ -561,7 +561,7 @@ namespace Debugger
} }
} }
#region Break at begining #region Break at beginning
int lastAssignedModuleOrderOfLoading = 0; int lastAssignedModuleOrderOfLoading = 0;
@ -570,21 +570,22 @@ namespace Debugger
module.OrderOfLoading = lastAssignedModuleOrderOfLoading++; module.OrderOfLoading = lastAssignedModuleOrderOfLoading++;
module.AppDomain.InvalidateCompilation(); module.AppDomain.InvalidateCompilation();
if (this.BreakInMain) { if (BreakInMain) {
if (module.SymReader == null) return; // No symbols
try { try {
// create a BP at entry point // create a BP at entry point
uint entryPoint = module.SymReader.GetUserEntryPoint(); uint entryPoint = module.GetEntryPoint();
if (entryPoint == 0) return; // no EP if (entryPoint != 0) { // no EP
var corBreakpoint = module.CorModule.GetFunctionFromToken(entryPoint).CreateBreakpoint(); var corBreakpoint = module.CorModule
.GetFunctionFromToken(entryPoint)
.CreateBreakpoint();
corBreakpoint.Activate(1); corBreakpoint.Activate(1);
this.tempBreakpoints.Add(corBreakpoint); tempBreakpoints.Add(corBreakpoint);
BreakInMain = false;
}
} catch { } catch {
// the app does not have an entry point - COM exception // the app does not have an entry point - COM exception
} }
this.BreakInMain = false;
} }
if (this.ModuleLoaded != null) { if (this.ModuleLoaded != null) {

7
src/AddIns/Debugger/Debugger.Core/TypeSystemExtensions.cs

@ -26,9 +26,10 @@ namespace Debugger
#region Module Loading #region Module Loading
static ConditionalWeakTable<IUnresolvedAssembly, ModuleMetadataInfo> weakTable = new ConditionalWeakTable<IUnresolvedAssembly, ModuleMetadataInfo>(); static ConditionalWeakTable<IUnresolvedAssembly, ModuleMetadataInfo> weakTable = new ConditionalWeakTable<IUnresolvedAssembly, ModuleMetadataInfo>();
class ModuleMetadataInfo internal class ModuleMetadataInfo
{ {
public readonly Module Module; public readonly Module Module;
public readonly Mono.Cecil.ModuleDefinition CecilModule;
Dictionary<IUnresolvedEntity, uint> metadataTokens = new Dictionary<IUnresolvedEntity, uint>(); Dictionary<IUnresolvedEntity, uint> metadataTokens = new Dictionary<IUnresolvedEntity, uint>();
Dictionary<uint, IUnresolvedMethod> tokenToMethod = new Dictionary<uint, IUnresolvedMethod>(); Dictionary<uint, IUnresolvedMethod> tokenToMethod = new Dictionary<uint, IUnresolvedMethod>();
Dictionary<IUnresolvedMember, ITypeReference[]> localVariableTypes = new Dictionary<IUnresolvedMember, ITypeReference[]>(); Dictionary<IUnresolvedMember, ITypeReference[]> localVariableTypes = new Dictionary<IUnresolvedMember, ITypeReference[]>();
@ -38,7 +39,7 @@ namespace Debugger
public ModuleMetadataInfo(Module module, Mono.Cecil.ModuleDefinition cecilModule) public ModuleMetadataInfo(Module module, Mono.Cecil.ModuleDefinition cecilModule)
{ {
this.Module = module; this.Module = module;
this.CecilModule = cecilModule;
typeRefLoader = new CecilLoader(); typeRefLoader = new CecilLoader();
typeRefLoader.SetCurrentModule(cecilModule); typeRefLoader.SetCurrentModule(cecilModule);
} }
@ -160,7 +161,7 @@ namespace Debugger
return asm; return asm;
} }
static ModuleMetadataInfo GetInfo(IAssembly assembly) internal static ModuleMetadataInfo GetInfo(IAssembly assembly)
{ {
ModuleMetadataInfo info; ModuleMetadataInfo info;
if (!weakTable.TryGetValue(assembly.UnresolvedAssembly, out info)) if (!weakTable.TryGetValue(assembly.UnresolvedAssembly, out info))

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionViewModel.cs

@ -33,7 +33,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
} }
public string Name { public string Name {
get { return this.action != null ? this.action.DisplayName : string.Empty; } get { return this.action != null ? this.action.GetDisplayName(context) : string.Empty; }
} }
public string Comment { get; set; } public string Comment { get; set; }

6
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/GoToEntityAction.cs

@ -27,8 +27,14 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
} }
public string DisplayName { get; private set; } public string DisplayName { get; private set; }
public IEntity Entity { get; private set; } public IEntity Entity { get; private set; }
public string GetDisplayName(EditorRefactoringContext context)
{
return DisplayName;
}
public GoToEntityAction(IEntity entity, string displayName) public GoToEntityAction(IEntity entity, string displayName)
{ {
if (entity == null) if (entity == null)

54
src/AddIns/Misc/AddInManager2/AddInManager2.Tests/AvailableAddInsViewModelTests.cs

@ -88,19 +88,22 @@ namespace ICSharpCode.AddInManager2.Tests
{ {
Id = _addIn1.Manifest.PrimaryIdentity, Id = _addIn1.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn1.Version), Version = new SemanticVersion(_addIn1.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = false
}; };
FakePackage fakePackage1_new = new FakePackage() FakePackage fakePackage1_new = new FakePackage()
{ {
Id = _addIn1_new.Manifest.PrimaryIdentity, Id = _addIn1_new.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn1_new.Version), Version = new SemanticVersion(_addIn1_new.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
FakePackage fakePackage2 = new FakePackage() FakePackage fakePackage2 = new FakePackage()
{ {
Id = _addIn2.Manifest.PrimaryIdentity, Id = _addIn2.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn2.Version), Version = new SemanticVersion(_addIn2.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
// List of NuGet repositories // List of NuGet repositories
@ -155,13 +158,15 @@ namespace ICSharpCode.AddInManager2.Tests
{ {
Id = _addIn1.Manifest.PrimaryIdentity, Id = _addIn1.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn1.Version), Version = new SemanticVersion(_addIn1.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
FakePackage fakePackage2 = new FakePackage() FakePackage fakePackage2 = new FakePackage()
{ {
Id = _addIn2.Manifest.PrimaryIdentity, Id = _addIn2.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn2.Version), Version = new SemanticVersion(_addIn2.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
// List of NuGet repositories // List of NuGet repositories
@ -230,13 +235,15 @@ namespace ICSharpCode.AddInManager2.Tests
{ {
Id = _addIn1.Manifest.PrimaryIdentity, Id = _addIn1.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn1.Version), Version = new SemanticVersion(_addIn1.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
FakePackage fakePackage2 = new FakePackage() FakePackage fakePackage2 = new FakePackage()
{ {
Id = _addIn2.Manifest.PrimaryIdentity, Id = _addIn2.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn2.Version), Version = new SemanticVersion(_addIn2.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
// List of NuGet repositories // List of NuGet repositories
@ -285,20 +292,23 @@ namespace ICSharpCode.AddInManager2.Tests
Id = _addIn2_new.Manifest.PrimaryIdentity, Id = _addIn2_new.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn2_new.Version), Version = new SemanticVersion(_addIn2_new.Version),
Tags = SharpDevelopAddInTag, Tags = SharpDevelopAddInTag,
DownloadCount = 30 DownloadCount = 30,
IsLatestVersion = true
}; };
FakePackage fakePackage1 = new FakePackage() FakePackage fakePackage1 = new FakePackage()
{ {
Id = _addIn1.Manifest.PrimaryIdentity, Id = _addIn1.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn1.Version), Version = new SemanticVersion(_addIn1.Version),
Tags = SharpDevelopAddInTag, Tags = SharpDevelopAddInTag,
DownloadCount = 10 DownloadCount = 10,
IsLatestVersion = true
}; };
FakePackage fakePackage2 = new FakePackage() FakePackage fakePackage2 = new FakePackage()
{ {
Id = _addIn2.Manifest.PrimaryIdentity, Id = _addIn2.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn2.Version), Version = new SemanticVersion(_addIn2.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = false
}; };
// List of NuGet repositories // List of NuGet repositories
@ -400,7 +410,8 @@ namespace ICSharpCode.AddInManager2.Tests
{ {
Id = _addIn1.Manifest.PrimaryIdentity + i.ToString("00"), Id = _addIn1.Manifest.PrimaryIdentity + i.ToString("00"),
Version = new SemanticVersion(_addIn1.Version), Version = new SemanticVersion(_addIn1.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
} }
@ -478,13 +489,15 @@ namespace ICSharpCode.AddInManager2.Tests
{ {
Id = _addIn1.Manifest.PrimaryIdentity, Id = _addIn1.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn1.Version), Version = new SemanticVersion(_addIn1.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
FakePackage fakePackage2 = new FakePackage() FakePackage fakePackage2 = new FakePackage()
{ {
Id = _addIn2.Manifest.PrimaryIdentity, Id = _addIn2.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn2.Version), Version = new SemanticVersion(_addIn2.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
_addIn1.Properties.Set(ManagedAddIn.NuGetPackageIDManifestAttribute, fakePackage1.Id); _addIn1.Properties.Set(ManagedAddIn.NuGetPackageIDManifestAttribute, fakePackage1.Id);
@ -575,13 +588,15 @@ namespace ICSharpCode.AddInManager2.Tests
{ {
Id = _addIn_noVersion.Manifest.PrimaryIdentity, Id = _addIn_noVersion.Manifest.PrimaryIdentity,
Version = new SemanticVersion("1.0.2.0"), Version = new SemanticVersion("1.0.2.0"),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
FakePackage fakePackage2 = new FakePackage() FakePackage fakePackage2 = new FakePackage()
{ {
Id = _addIn2.Manifest.PrimaryIdentity, Id = _addIn2.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn2.Version), Version = new SemanticVersion(_addIn2.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
_addIn_noVersion.Properties.Set(ManagedAddIn.NuGetPackageIDManifestAttribute, fakePackage1.Id); _addIn_noVersion.Properties.Set(ManagedAddIn.NuGetPackageIDManifestAttribute, fakePackage1.Id);
@ -672,19 +687,22 @@ namespace ICSharpCode.AddInManager2.Tests
{ {
Id = _addIn1.Manifest.PrimaryIdentity, Id = _addIn1.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn1.Version), Version = new SemanticVersion(_addIn1.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = false
}; };
FakePackage fakePackage1_new = new FakePackage() FakePackage fakePackage1_new = new FakePackage()
{ {
Id = _addIn1_new.Manifest.PrimaryIdentity, Id = _addIn1_new.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn1_new.Version), Version = new SemanticVersion(_addIn1_new.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
FakePackage fakePackage2 = new FakePackage() FakePackage fakePackage2 = new FakePackage()
{ {
Id = _addIn2.Manifest.PrimaryIdentity, Id = _addIn2.Manifest.PrimaryIdentity,
Version = new SemanticVersion(_addIn2.Version), Version = new SemanticVersion(_addIn2.Version),
Tags = SharpDevelopAddInTag Tags = SharpDevelopAddInTag,
IsLatestVersion = true
}; };
_addIn1.Properties.Set(ManagedAddIn.NuGetPackageIDManifestAttribute, fakePackage1_old.Id); _addIn1.Properties.Set(ManagedAddIn.NuGetPackageIDManifestAttribute, fakePackage1_old.Id);

11
src/AddIns/Misc/AddInManager2/Project/Src/Model/AddInSetup.cs

@ -417,11 +417,20 @@ namespace ICSharpCode.AddInManager2.Model
{ {
Directory.Delete(targetDir, true); Directory.Delete(targetDir, true);
} }
Directory.CreateDirectory(targetDir); var directoryInfo = Directory.CreateDirectory(targetDir);
FastZip fastZip = new FastZip(); FastZip fastZip = new FastZip();
fastZip.CreateEmptyDirectories = true; fastZip.CreateEmptyDirectories = true;
fastZip.ExtractZip(zipFile, targetDir, null); fastZip.ExtractZip(zipFile, targetDir, null);
if (addIn.FileName == null) {
// Find .addin file to set it in AddIn object
var addInFiles = directoryInfo.GetFiles("*.addin", SearchOption.TopDirectoryOnly);
var addInFile = addInFiles.FirstOrDefault();
if (addInFile != null) {
addIn.FileName = addInFile.FullName;
}
}
return true; return true;
} }
catch (Exception) catch (Exception)

3
src/AddIns/Misc/AddInManager2/Project/Src/ViewModel/AvailableAddInsViewModel.cs

@ -44,7 +44,8 @@ namespace ICSharpCode.AddInManager2.ViewModel
protected override IQueryable<IPackage> GetAllPackages() protected override IQueryable<IPackage> GetAllPackages()
{ {
return (ActiveRepository ?? AddInManager.Repositories.AllRegistered).GetPackages(); return (ActiveRepository ?? AddInManager.Repositories.AllRegistered).GetPackages()
.Where(package => package.IsLatestVersion);
} }
protected override IEnumerable<IPackage> GetFilteredPackagesBeforePagingResults(IQueryable<IPackage> allPackages) protected override IEnumerable<IPackage> GetFilteredPackagesBeforePagingResults(IQueryable<IPackage> allPackages)

3
src/AddIns/Misc/AddInManager2/Project/Src/ViewModel/InstalledAddInsViewModel.cs

@ -159,6 +159,9 @@ namespace ICSharpCode.AddInManager2.ViewModel
protected override void InstallFromArchive() protected override void InstallFromArchive()
{ {
// Notify about new operation
AddInManager.Events.OnOperationStarted();
OpenFileDialog dlg = new OpenFileDialog(); OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = SD.ResourceService.GetString("AddInManager2.SDAddInFileFilter"); dlg.Filter = SD.ResourceService.GetString("AddInManager2.SDAddInFileFilter");
dlg.Multiselect = true; dlg.Multiselect = true;

52
src/Main/Base/Project/Dom/ClassBrowser/AssemblyTreeNode.cs

@ -0,0 +1,52 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
public class AssemblyTreeNode : ModelCollectionTreeNode
{
IAssemblyModel model;
public AssemblyTreeNode(IAssemblyModel model)
{
if (model == null)
throw new ArgumentNullException("model");
this.model = model;
}
protected override object GetModel()
{
return model;
}
protected override IComparer<SharpTreeNode> NodeComparer {
get {
return NodeTextComparer;
}
}
protected override IModelCollection<object> ModelChildren {
get {
return model.Namespaces;
}
}
public override object Text {
get {
return model.AssemblyName;
}
}
public override object Icon {
get {
return base.Icon;
}
}
}
}

46
src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs

@ -2,40 +2,50 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using System.Diagnostics; using System.Collections.Generic;
using System.Windows.Controls; using System.Windows.Controls;
using ICSharpCode.Core.Presentation;
using ICSharpCode.TreeView; using ICSharpCode.TreeView;
using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{ {
public class ClassBrowserTreeView : SharpTreeView, IClassBrowserTreeView public class ClassBrowserTreeView : SharpTreeView, IClassBrowserTreeView
{ {
ClassBrowserWorkspace currentWorkspace; #region IClassBrowser implementation
public ICollection<SharpTreeNode> SpecialNodes {
get { return ((WorkspaceTreeNode)Root).SpecialNodes; }
}
public AssemblyList AssemblyList {
get { return ((WorkspaceTreeNode)Root).AssemblyList; }
set { ((WorkspaceTreeNode)Root).AssemblyList = value; }
}
#endregion
public ClassBrowserTreeView() public ClassBrowserTreeView()
{ {
Workspace = ClassBrowserSettings.LoadDefaultWorkspace(); WorkspaceTreeNode root = new WorkspaceTreeNode();
ClassBrowserTreeView instance = this;
root.SpecialNodes.CollectionChanged += delegate {
instance.ShowRoot = root.Children.Count > 1;
};
root.PropertyChanged += delegate {
instance.ShowRoot = root.Children.Count > 1;
};
this.Root = root;
} }
public ClassBrowserWorkspace Workspace { protected override void OnContextMenuOpening(ContextMenuEventArgs e)
get { return currentWorkspace; } {
set { var treeNode = this.SelectedItem as ModelCollectionTreeNode;
if (currentWorkspace == value) if (treeNode != null) {
return; treeNode.ShowContextMenu();
currentWorkspace = value;
if (currentWorkspace != null) {
this.Root = new WorkspaceTreeNode(currentWorkspace);
this.ShowRoot = currentWorkspace.LoadedAssemblies.Count > 0 || !currentWorkspace.IsAssigned;
} else {
this.Root = null;
}
} }
} }
} }
public interface IClassBrowserTreeView public interface IClassBrowserTreeView : IClassBrowser
{ {
} }

84
src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserWorkspace.cs

@ -1,84 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
/// <summary>
/// Description of ClassBrowserWorkspace.
/// </summary>
public class ClassBrowserWorkspace
{
ISolution assignedSolution;
IModelCollection<IUnresolvedAssembly> loadedAssemblies;
string workspaceName;
public ClassBrowserWorkspace(ISolution assignedSolution, IEnumerable<IUnresolvedAssembly> assemblies = null)
: this(assignedSolution.FileName, assemblies)
{
this.assignedSolution = assignedSolution;
}
public ClassBrowserWorkspace(string workspaceName, IEnumerable<IUnresolvedAssembly> assemblies = null)
{
this.workspaceName = workspaceName;
this.loadedAssemblies = new SimpleModelCollection<IUnresolvedAssembly>(assemblies ?? EmptyList<IUnresolvedAssembly>.Instance);
}
public bool IsAssigned {
get { return assignedSolution != null; }
}
public ISolution AssignedSolution {
get { return assignedSolution; }
}
public string Name {
get { return workspaceName; }
}
public IModelCollection<IUnresolvedAssembly> LoadedAssemblies {
get { return loadedAssemblies; }
}
}
public static class ClassBrowserSettings
{
static IUnresolvedAssembly[] LoadAssemblyList(string name)
{
var assemblyNames = Container.GetList<string>("AssemblyList." + name);
CecilLoader loader = new CecilLoader();
return assemblyNames.Select(loader.LoadAssemblyFile).ToArray();
}
static readonly Properties Container = SD.PropertyService.NestedProperties(typeof(ClassBrowserSettings).FullName);
public static ClassBrowserWorkspace LoadDefaultWorkspace()
{
return LoadWorkspace("<default>");
}
public static ClassBrowserWorkspace LoadWorkspace(string name)
{
return new ClassBrowserWorkspace(name, LoadAssemblyList(name));
}
public static ClassBrowserWorkspace LoadForSolution(ISolution solution)
{
return new ClassBrowserWorkspace(solution, LoadAssemblyList(solution.FileName));
}
public static void SaveWorkspace(ClassBrowserWorkspace workspace)
{
}
}
}

27
src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs

@ -0,0 +1,27 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
public interface IClassBrowser
{
ICollection<SharpTreeNode> SpecialNodes { get; }
AssemblyList AssemblyList { get; set; }
}
public class AssemblyList
{
public string Name { get; set; }
public IMutableModelCollection<IAssemblyModel> Assemblies { get; set; }
public AssemblyList()
{
Name = "<default>";
Assemblies = new SimpleModelCollection<IAssemblyModel>();
}
}
}

82
src/Main/Base/Project/Dom/ClassBrowser/MemberTreeNode.cs

@ -0,0 +1,82 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using ICSharpCode.Core.Presentation;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
public class MemberTreeNode : ModelCollectionTreeNode
{
IMemberModel model;
public MemberTreeNode(IMemberModel model)
{
if (model == null)
throw new ArgumentNullException("model");
this.model = model;
// disable lazy loading to avoid showing a useless + sign in the tree.
// remove this line if you add child nodes
LazyLoading = false;
}
protected override object GetModel()
{
return model;
}
public override object Icon {
// TODO why do I have to resolve this?
get {
return ClassBrowserIconService.GetIcon(model.Resolve()).ImageSource;
}
}
object cachedText;
public override object Text {
get {
if (cachedText == null)
cachedText = GetText();
return cachedText;
}
}
object GetText()
{
var member = model.Resolve();
if (member == null)
return model.Name;
IAmbience ambience = AmbienceService.GetCurrentAmbience();
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.ShowParameterList | ConversionFlags.ShowParameterNames;
return ambience.ConvertEntity(member);
}
protected override IModelCollection<object> ModelChildren {
get { return ImmutableModelCollection<object>.Empty; }
}
protected override System.Collections.Generic.IComparer<SharpTreeNode> NodeComparer {
get { return NodeTextComparer; }
}
public override void ActivateItem(System.Windows.RoutedEventArgs e)
{
var target = model.Resolve();
if (target != null)
NavigationService.NavigateTo(target);
}
public override void ShowContextMenu()
{
var entityModel = this.Model as IEntityModel;
if ((entityModel != null) && (entityModel.ParentProject != null)) {
var ctx = MenuService.ShowContextMenu(null, entityModel, "/SharpDevelop/EntityContextMenu");
}
}
}
}

56
src/Main/Base/Project/Dom/ClassBrowser/NamespaceTreeNode.cs

@ -0,0 +1,56 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Windows.Media;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.TreeView;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
public class NamespaceTreeNode : ModelCollectionTreeNode
{
INamespaceModel model;
public NamespaceTreeNode(INamespaceModel model)
{
if (model == null)
throw new ArgumentNullException("model");
this.model = model;
}
protected override object GetModel()
{
return model;
}
protected override IComparer<SharpTreeNode> NodeComparer {
get {
return NodeTextComparer;
}
}
protected override IModelCollection<object> ModelChildren {
get {
return model.Types;
}
}
public override object Icon {
get {
return ClassBrowserIconService.Namespace.ImageSource;
}
}
public override object Text {
get {
return model.FullName;
}
}
}
}

53
src/Main/Base/Project/Dom/ClassBrowser/ProjectTreeNode.cs

@ -0,0 +1,53 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.TreeView;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
public class ProjectTreeNode : ModelCollectionTreeNode
{
IProject project;
public ProjectTreeNode(IProject project)
{
if (project == null)
throw new ArgumentNullException("project");
this.project = project;
}
protected override object GetModel()
{
return project;
}
public override object Text {
get {
return project.Name;
}
}
public override object Icon {
get {
return IconService.GetImageSource(IconService.GetImageForProjectType(project.Language));
}
}
protected override IComparer<SharpTreeNode> NodeComparer {
get {
return NodeTextComparer;
}
}
protected override IModelCollection<object> ModelChildren {
get {
return project.AssemblyModel.Namespaces;
}
}
}
}

53
src/Main/Base/Project/Dom/ClassBrowser/SolutionTreeNode.cs

@ -0,0 +1,53 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.TreeView;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
public class SolutionTreeNode : ModelCollectionTreeNode
{
ISolution solution;
public SolutionTreeNode(ISolution solution)
{
if (solution == null)
throw new ArgumentNullException("solution");
this.solution = solution;
}
protected override object GetModel()
{
return solution;
}
public override object Text {
get {
return "Solution " + solution.Name;
}
}
public override object Icon {
get {
return IconService.GetImageSource("Icons.16x16.SolutionIcon");
}
}
protected override IComparer<SharpTreeNode> NodeComparer {
get {
return NodeTextComparer;
}
}
protected override IModelCollection<object> ModelChildren {
get {
return solution.Projects;
}
}
}
}

70
src/Main/Base/Project/Dom/ClassBrowser/TypeDefinitionTreeNode.cs

@ -0,0 +1,70 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.Core.Presentation;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
public class TypeDefinitionTreeNode : ModelCollectionTreeNode
{
ITypeDefinitionModel definition;
public TypeDefinitionTreeNode(ITypeDefinitionModel definition)
{
if (definition == null)
throw new ArgumentNullException("definition");
this.definition = definition;
}
protected override object GetModel()
{
return definition;
}
public override object Icon {
// TODO why do I have to resolve this?
get {
return ClassBrowserIconService.GetIcon(definition.Resolve()).ImageSource;
}
}
public override object Text {
get {
return definition.Name;
}
}
protected override IComparer<SharpTreeNode> NodeComparer {
get {
return NodeTextComparer;
}
}
protected override IModelCollection<object> ModelChildren {
get {
return definition.Members;
}
}
public override void ActivateItem(System.Windows.RoutedEventArgs e)
{
var target = definition.Resolve();
if (target != null)
NavigationService.NavigateTo(target);
}
public override void ShowContextMenu()
{
var entityModel = this.Model as IEntityModel;
if ((entityModel != null) && (entityModel.ParentProject != null)) {
var ctx = MenuService.ShowContextMenu(null, entityModel, "/SharpDevelop/EntityContextMenu");
}
}
}
}

48
src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs

@ -0,0 +1,48 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
/// <summary>
/// Description of WorkspaceModel.
/// </summary>
public class WorkspaceModel : System.ComponentModel.INotifyPropertyChanged
{
IMutableModelCollection<SharpTreeNode> specialNodes;
public IMutableModelCollection<SharpTreeNode> SpecialNodes {
get { return specialNodes; }
}
AssemblyList assemblyList;
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null) {
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
public AssemblyList AssemblyList {
get {
return assemblyList;
}
set {
if (assemblyList != value) {
assemblyList = value;
OnPropertyChanged("AssemblyList");
}
}
}
public WorkspaceModel()
{
this.specialNodes = new SimpleModelCollection<SharpTreeNode>();
this.AssemblyList = new AssemblyList();
}
}
}

257
src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs

@ -3,11 +3,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Media; using System.Collections.ObjectModel;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.TreeView; using ICSharpCode.TreeView;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{ {
@ -16,271 +13,61 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
/// </summary> /// </summary>
public class WorkspaceTreeNode : ModelCollectionTreeNode public class WorkspaceTreeNode : ModelCollectionTreeNode
{ {
ClassBrowserWorkspace workspace; WorkspaceModel workspace;
public WorkspaceTreeNode(ClassBrowserWorkspace workspace) public IMutableModelCollection<SharpTreeNode> SpecialNodes {
{ get { return workspace.SpecialNodes; }
if (workspace == null)
throw new ArgumentNullException("workspace");
this.workspace = workspace;
}
protected override object GetModel()
{
return workspace;
}
protected override IModelCollection<object> ModelChildren {
get { return workspace.LoadedAssemblies; }
}
protected override IComparer<SharpTreeNode> NodeComparer {
get { return NodeTextComparer; }
}
public override object Text {
get {
return "Workspace " + workspace.Name;
}
}
protected override bool IsSpecialNode()
{
return true;
}
protected override void InsertSpecialNodes()
{
if (workspace.IsAssigned) {
InsertChildren(new[] { workspace.AssignedSolution });
}
}
}
public class SolutionTreeNode : ModelCollectionTreeNode
{
ISolution solution;
public SolutionTreeNode(ISolution solution)
{
if (solution == null)
throw new ArgumentNullException("solution");
this.solution = solution;
}
protected override object GetModel()
{
return solution;
}
public override object Text {
get { return "Solution " + solution.Name; }
}
public override object Icon {
get { return IconService.GetImageSource("Icons.16x16.SolutionIcon"); }
} }
protected override IComparer<SharpTreeNode> NodeComparer { public AssemblyList AssemblyList {
get { return NodeTextComparer; } get { return workspace.AssemblyList; }
set { workspace.AssemblyList = value; }
} }
protected override IModelCollection<object> ModelChildren { public WorkspaceTreeNode()
get { return solution.Projects; }
}
}
public class ProjectTreeNode : ModelCollectionTreeNode
{
IProject project;
public ProjectTreeNode(IProject project)
{ {
if (project == null) this.workspace = new WorkspaceModel();
throw new ArgumentNullException("project"); this.workspace.SpecialNodes.CollectionChanged += SpecialNodesModelCollectionChanged;
this.project = project;
} }
protected override object GetModel() protected override object GetModel()
{ {
return project; return workspace;
}
public override object Text {
get { return project.Name; }
}
public override object Icon {
get { return IconService.GetImageSource(IconService.GetImageForProjectType(project.Language)); }
}
protected override IComparer<SharpTreeNode> NodeComparer {
get { return NodeTextComparer; }
}
protected override IModelCollection<object> ModelChildren {
get { return project.AssemblyModel.Namespaces; }
}
}
public class AssemblyTreeNode : ModelCollectionTreeNode
{
IAssemblyModel model;
public AssemblyTreeNode(IAssemblyModel model)
{
if (model == null)
throw new ArgumentNullException("model");
this.model = model;
}
protected override object GetModel()
{
return model;
}
protected override IComparer<SharpTreeNode> NodeComparer {
get { return NodeTextComparer; }
} }
protected override IModelCollection<object> ModelChildren { protected override IModelCollection<object> ModelChildren {
get { return model.Namespaces; } get { return workspace.AssemblyList.Assemblies; }
}
}
public class NamespaceTreeNode : ModelCollectionTreeNode
{
INamespaceModel model;
public NamespaceTreeNode(INamespaceModel model)
{
if (model == null)
throw new ArgumentNullException("model");
this.model = model;
}
protected override object GetModel()
{
return model;
} }
protected override IComparer<SharpTreeNode> NodeComparer { protected override IComparer<SharpTreeNode> NodeComparer {
get { return NodeTextComparer; } get { return NodeTextComparer; }
} }
protected override IModelCollection<object> ModelChildren {
get { return model.Types; }
}
public override object Icon {
get { return ClassBrowserIconService.Namespace.ImageSource; }
}
public override object Text { public override object Text {
get { return model.FullName; }
}
}
public class TypeDefinitionTreeNode : ModelCollectionTreeNode
{
ITypeDefinitionModel definition;
public TypeDefinitionTreeNode(ITypeDefinitionModel definition)
{
if (definition == null)
throw new ArgumentNullException("definition");
this.definition = definition;
}
protected override object GetModel()
{
return definition;
}
public override object Icon {
// TODO why do I have to resolve this?
get { return ClassBrowserIconService.GetIcon(definition.Resolve()).ImageSource; }
}
public override object Text {
get { return definition.Name; }
}
protected override IComparer<SharpTreeNode> NodeComparer {
get { return NodeTextComparer; }
}
protected override IModelCollection<object> ModelChildren {
get { return definition.Members; }
}
public override void ActivateItem(System.Windows.RoutedEventArgs e)
{
var target = definition.Resolve();
if (target != null)
NavigationService.NavigateTo(target);
}
}
public class MemberTreeNode : ModelCollectionTreeNode
{
IMemberModel model;
public MemberTreeNode(IMemberModel model)
{
if (model == null)
throw new ArgumentNullException("model");
this.model = model;
// disable lazy loading to avoid showing a useless + sign in the tree.
// remove this line if you add child nodes
LazyLoading = false;
}
protected override object GetModel()
{
return model;
}
public override object Icon {
// TODO why do I have to resolve this?
get { get {
return ClassBrowserIconService.GetIcon(model.Resolve()).ImageSource; return "Workspace " + AssemblyList.Name;
} }
} }
object cachedText; public override object Icon {
public override object Text {
get { get {
if (cachedText == null) return SD.ResourceService.GetImageSource("PadIcons.ClassBrowser");
cachedText = GetText();
return cachedText;
} }
} }
object GetText() protected override bool IsSpecialNode()
{ {
var member = model.Resolve(); return true;
if (member == null)
return model.Name;
IAmbience ambience = AmbienceService.GetCurrentAmbience();
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.ShowParameterList | ConversionFlags.ShowParameterNames;
return ambience.ConvertEntity(member);
}
protected override IComparer<SharpTreeNode> NodeComparer {
get { return NodeTextComparer; }
} }
protected override IModelCollection<object> ModelChildren { protected override void InsertSpecialNodes()
get { return ImmutableModelCollection<object>.Empty; } {
Children.AddRange(workspace.SpecialNodes);
} }
public override void ActivateItem(System.Windows.RoutedEventArgs e) void SpecialNodesModelCollectionChanged(IReadOnlyCollection<SharpTreeNode> removedItems, IReadOnlyCollection<SharpTreeNode> addedItems)
{ {
var target = model.Resolve(); SynchronizeModelChildren();
if (target != null)
NavigationService.NavigateTo(target);
} }
} }
} }

11
src/Main/Base/Project/Dom/IAssemblyModel.cs

@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
@ -56,6 +57,16 @@ namespace ICSharpCode.SharpDevelop.Dom
/// <paramref name="newFile"/> is null if the file is removed from the assembly. /// <paramref name="newFile"/> is null if the file is removed from the assembly.
/// </remarks> /// </remarks>
void Update(IUnresolvedFile oldFile, IUnresolvedFile newFile); void Update(IUnresolvedFile oldFile, IUnresolvedFile newFile);
/// <summary>
/// Updates the parse information with the given list of top-level type definitions.
/// </summary>
void Update(IList<IUnresolvedTypeDefinition> oldFile, IList<IUnresolvedTypeDefinition> newFile);
/// <summary>
/// Gets the assembly name (short name).
/// </summary>
new string AssemblyName { get; set; }
} }
public sealed class EmptyAssemblyModel : IAssemblyModel public sealed class EmptyAssemblyModel : IAssemblyModel

6
src/Main/Base/Project/Dom/IEntityModel.cs

@ -44,15 +44,15 @@ namespace ICSharpCode.SharpDevelop.Dom
bool IsShadowing { get; } bool IsShadowing { get; }
/// <summary> /// <summary>
/// Resolves the entity in the current solution snapshot. /// Resolves the entity in the current compilation.
/// Returns null if the entity could not be resolved. /// Returns null if the entity could not be resolved.
/// </summary> /// </summary>
IEntity Resolve(); IEntity Resolve();
/// <summary> /// <summary>
/// Resolves the entity in the specified solution snapshot. /// Resolves the entity in the specified compilation.
/// Returns null if the entity could not be resolved. /// Returns null if the entity could not be resolved.
/// </summary> /// </summary>
IEntity Resolve(ISolutionSnapshotWithProjectMapping solutionSnapshot); IEntity Resolve(ICompilation compilation);
} }
} }

47
src/Main/Base/Project/Dom/IEntityModelContext.cs

@ -3,6 +3,7 @@
using System; using System;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Refactoring; using ICSharpCode.SharpDevelop.Refactoring;
@ -27,7 +28,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// The solution snapshot provided to <see cref="IEntityModel.Resolve(ISolutionSnapshotWithProjectMapping)"/>, /// The solution snapshot provided to <see cref="IEntityModel.Resolve(ISolutionSnapshotWithProjectMapping)"/>,
/// or null if the <see cref="IEntityModel.Resolve()"/> overload was used. /// or null if the <see cref="IEntityModel.Resolve()"/> overload was used.
/// </param> /// </param>
ICompilation GetCompilation(ISolutionSnapshotWithProjectMapping solutionSnapshot); ICompilation GetCompilation();
/// <summary> /// <summary>
/// Returns true if part1 is considered a better candidate for the primary part than part2. /// Returns true if part1 is considered a better candidate for the primary part than part2.
@ -48,15 +49,16 @@ namespace ICSharpCode.SharpDevelop.Dom
this.primaryCodeFileExtension = primaryCodeFileExtension; this.primaryCodeFileExtension = primaryCodeFileExtension;
} }
public string AssemblyName {
get { return project.AssemblyName; }
}
public IProject Project { public IProject Project {
get { return project; } get { return project; }
} }
public ICompilation GetCompilation(ISolutionSnapshotWithProjectMapping solutionSnapshot) public ICompilation GetCompilation()
{ {
if (solutionSnapshot != null)
return solutionSnapshot.GetCompilation(project);
else
return SD.ParserService.GetCompilation(project); return SD.ParserService.GetCompilation(project);
} }
@ -66,6 +68,41 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
public class AssemblyEntityModelContext : IEntityModelContext
{
ICompilation compilation;
IUnresolvedAssembly mainAssembly;
IAssemblyReference[] references;
public AssemblyEntityModelContext(IUnresolvedAssembly mainAssembly, params IAssemblyReference[] references)
{
if (mainAssembly == null)
throw new ArgumentNullException("mainAssembly");
this.mainAssembly = mainAssembly;
this.references = references;
// implement lazy init + weak caching
this.compilation = new SimpleCompilation(mainAssembly, references);
}
public string AssemblyName {
get { return mainAssembly.AssemblyName; }
}
public ICompilation GetCompilation()
{
return compilation;
}
public bool IsBetterPart(IUnresolvedTypeDefinition part1, IUnresolvedTypeDefinition part2)
{
return false;
}
public IProject Project {
get { return null; }
}
}
public static class EntityModelContextUtils public static class EntityModelContextUtils
{ {
public static bool IsBetterPart(IUnresolvedTypeDefinition part1, IUnresolvedTypeDefinition part2, string codeFileExtension) public static bool IsBetterPart(IUnresolvedTypeDefinition part1, IUnresolvedTypeDefinition part2, string codeFileExtension)

6
src/Main/Base/Project/Dom/IMemberModel.cs

@ -13,16 +13,16 @@ namespace ICSharpCode.SharpDevelop.Dom
public interface IMemberModel : IEntityModel public interface IMemberModel : IEntityModel
{ {
/// <summary> /// <summary>
/// Resolves the member in the current solution snapshot. /// Resolves the member in the current compilation.
/// Returns null if the member could not be resolved. /// Returns null if the member could not be resolved.
/// </summary> /// </summary>
new IMember Resolve(); new IMember Resolve();
/// <summary> /// <summary>
/// Resolves the member in the specified solution snapshot. /// Resolves the member in the specified compilation.
/// Returns null if the member could not be resolved. /// Returns null if the member could not be resolved.
/// </summary> /// </summary>
new IMember Resolve(ISolutionSnapshotWithProjectMapping solutionSnapshot); new IMember Resolve(ICompilation compilation);
/// <summary> /// <summary>
/// Gets if the member is virtual. Is true only if the "virtual" modifier was used, but non-virtual /// Gets if the member is virtual. Is true only if the "virtual" modifier was used, but non-virtual

31
src/Main/Base/Project/Dom/IModelCollection.cs

@ -15,6 +15,37 @@ namespace ICSharpCode.SharpDevelop.Dom
/// </remarks> /// </remarks>
public delegate void ModelCollectionChangedEventHandler<in T>(IReadOnlyCollection<T> removedItems, IReadOnlyCollection<T> addedItems); public delegate void ModelCollectionChangedEventHandler<in T>(IReadOnlyCollection<T> removedItems, IReadOnlyCollection<T> addedItems);
public class ModelCollectionChangedEvent<T>
{
List<ModelCollectionChangedEventHandler<T>> _handlers = new List<ModelCollectionChangedEventHandler<T>>();
public void AddHandler(ModelCollectionChangedEventHandler<T> handler)
{
_handlers.Add(handler);
}
public void RemoveHandler(ModelCollectionChangedEventHandler<T> handler)
{
_handlers.Remove(handler);
}
public void Fire(IReadOnlyCollection<T> removedItems, IReadOnlyCollection<T> addedItems)
{
foreach (var handler in _handlers) {
if (handler != null) {
handler(removedItems, addedItems);
}
}
}
public bool ContainsHandlers
{
get {
return _handlers.Count > 0;
}
}
}
/// <summary> /// <summary>
/// A read-only collection that provides change notifications. /// A read-only collection that provides change notifications.
/// </summary> /// </summary>

2
src/Main/Base/Project/Dom/INamespaceModel.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
} }
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged { add {} remove {} }
public string FullName { public string FullName {
get { return string.Empty; } get { return string.Empty; }

6
src/Main/Base/Project/Dom/ITypeDefinitionModel.cs

@ -22,16 +22,16 @@ namespace ICSharpCode.SharpDevelop.Dom
IEnumerable<DomRegion> GetPartRegions(); IEnumerable<DomRegion> GetPartRegions();
/// <summary> /// <summary>
/// Resolves the type definition in the current solution snapshot. /// Resolves the type definition in the current compilation.
/// Returns null if the type definition could not be resolved. /// Returns null if the type definition could not be resolved.
/// </summary> /// </summary>
new ITypeDefinition Resolve(); new ITypeDefinition Resolve();
/// <summary> /// <summary>
/// Resolves the type definition in the specified solution snapshot. /// Resolves the type definition in the specified compilation.
/// Returns null if the type definition could not be resolved. /// Returns null if the type definition could not be resolved.
/// </summary> /// </summary>
new ITypeDefinition Resolve(ISolutionSnapshotWithProjectMapping solutionSnapshot); new ITypeDefinition Resolve(ICompilation compilation);
/// <summary> /// <summary>
/// Retrieves the nested type with the specified name and additional type parameter count /// Retrieves the nested type with the specified name and additional type parameter count

4
src/Main/Base/Project/Dom/ITypeDefinitionModelCollection.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// <summary> /// <summary>
/// Updates the collection when the parse information has changed. /// Updates the collection when the parse information has changed.
/// </summary> /// </summary>
void Update(IUnresolvedFile oldFile, IUnresolvedFile newFile); void Update(IList<IUnresolvedTypeDefinition> oldFile, IList<IUnresolvedTypeDefinition> newFile);
} }
public sealed class EmptyTypeDefinitionModelCollection : ITypeDefinitionModelCollection public sealed class EmptyTypeDefinitionModelCollection : ITypeDefinitionModelCollection
@ -70,7 +70,7 @@ namespace ICSharpCode.SharpDevelop.Dom
return Enumerable.Empty<ITypeDefinitionModel>().GetEnumerator(); return Enumerable.Empty<ITypeDefinitionModel>().GetEnumerator();
} }
void ITypeDefinitionModelCollection.Update(IUnresolvedFile oldFile, IUnresolvedFile newFile) void ITypeDefinitionModelCollection.Update(IList<IUnresolvedTypeDefinition> oldFile, IList<IUnresolvedTypeDefinition> newFile)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }

15
src/Main/Base/Project/Dom/ModelCollectionLinq.cs

@ -70,6 +70,7 @@ namespace ICSharpCode.SharpDevelop.Dom
sealed class SelectManyModelCollection<TSource, TCollection, TResult> : IModelCollection<TResult> sealed class SelectManyModelCollection<TSource, TCollection, TResult> : IModelCollection<TResult>
{ {
readonly ModelCollectionChangedEvent<TResult> collectionChangedEvent;
readonly IModelCollection<TSource> source; readonly IModelCollection<TSource> source;
readonly Func<TSource, IModelCollection<TCollection>> collectionSelector; readonly Func<TSource, IModelCollection<TCollection>> collectionSelector;
readonly Func<TSource, TCollection, TResult> resultSelector; readonly Func<TSource, TCollection, TResult> resultSelector;
@ -80,10 +81,9 @@ namespace ICSharpCode.SharpDevelop.Dom
this.source = source; this.source = source;
this.collectionSelector = collectionSelector; this.collectionSelector = collectionSelector;
this.resultSelector = resultSelector; this.resultSelector = resultSelector;
collectionChangedEvent = new ModelCollectionChangedEvent<TResult>();
} }
ModelCollectionChangedEventHandler<TResult> collectionChanged;
public event ModelCollectionChangedEventHandler<TResult> CollectionChanged { public event ModelCollectionChangedEventHandler<TResult> CollectionChanged {
add { add {
if (value == null) if (value == null)
@ -97,13 +97,13 @@ namespace ICSharpCode.SharpDevelop.Dom
inputCollections.Add(inputCollection); inputCollections.Add(inputCollection);
} }
} }
collectionChanged += value; collectionChangedEvent.AddHandler(value);
} }
remove { remove {
if (collectionChanged == null) if (!collectionChangedEvent.ContainsHandlers)
return; return;
collectionChanged -= value; collectionChangedEvent.RemoveHandler(value);
if (collectionChanged == null) { if (!collectionChangedEvent.ContainsHandlers) {
source.CollectionChanged -= OnSourceCollectionChanged; source.CollectionChanged -= OnSourceCollectionChanged;
foreach (var inputCollection in inputCollections) { foreach (var inputCollection in inputCollections) {
inputCollection.UnregisterEvent(); inputCollection.UnregisterEvent();
@ -115,8 +115,7 @@ namespace ICSharpCode.SharpDevelop.Dom
void OnCollectionChanged(IReadOnlyCollection<TResult> removedItems, IReadOnlyCollection<TResult> addedItems) void OnCollectionChanged(IReadOnlyCollection<TResult> removedItems, IReadOnlyCollection<TResult> addedItems)
{ {
if (collectionChanged != null) collectionChangedEvent.Fire(removedItems, addedItems);
collectionChanged(removedItems, addedItems);
} }
void OnSourceCollectionChanged(IReadOnlyCollection<TSource> removedItems, IReadOnlyCollection<TSource> addedItems) void OnSourceCollectionChanged(IReadOnlyCollection<TSource> removedItems, IReadOnlyCollection<TSource> addedItems)

9
src/Main/Base/Project/Dom/ModelCollectionTreeNode.cs

@ -54,6 +54,11 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
public virtual void ShowContextMenu()
{
// Do nothing in base class
}
#region Manage Children #region Manage Children
protected override void LoadChildren() protected override void LoadChildren()
{ {
@ -73,12 +78,14 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
void SynchronizeModelChildren() protected void SynchronizeModelChildren()
{ {
HashSet<object> set = new HashSet<object>(ModelChildren); HashSet<object> set = new HashSet<object>(ModelChildren);
Children.RemoveAll(n => !set.Contains(n.Model)); Children.RemoveAll(n => !set.Contains(n.Model));
set.ExceptWith(Children.Select(n => n.Model)); set.ExceptWith(Children.Select(n => n.Model));
InsertChildren(set); InsertChildren(set);
if (IsSpecialNode())
InsertSpecialNodes();
} }
void ModelChildrenCollectionChanged(IReadOnlyCollection<object> removedItems, IReadOnlyCollection<object> addedItems) void ModelChildrenCollectionChanged(IReadOnlyCollection<object> removedItems, IReadOnlyCollection<object> addedItems)

17
src/Main/Base/Project/Dom/SimpleModelCollection.cs

@ -16,6 +16,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// </summary> /// </summary>
public class SimpleModelCollection<T> : IMutableModelCollection<T> public class SimpleModelCollection<T> : IMutableModelCollection<T>
{ {
readonly ModelCollectionChangedEvent<T> collectionChangedEvent;
readonly List<T> list; readonly List<T> list;
List<T> addedItems; List<T> addedItems;
List<T> removedItems; List<T> removedItems;
@ -23,11 +24,13 @@ namespace ICSharpCode.SharpDevelop.Dom
public SimpleModelCollection() public SimpleModelCollection()
{ {
this.list = new List<T>(); this.list = new List<T>();
collectionChangedEvent = new ModelCollectionChangedEvent<T>();
} }
public SimpleModelCollection(IEnumerable<T> items) public SimpleModelCollection(IEnumerable<T> items)
{ {
this.list = new List<T>(items); this.list = new List<T>(items);
collectionChangedEvent = new ModelCollectionChangedEvent<T>();
} }
protected void CheckReentrancy() protected void CheckReentrancy()
@ -41,7 +44,15 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
#region CollectionChanged / BatchUpdate() #region CollectionChanged / BatchUpdate()
public event ModelCollectionChangedEventHandler<T> CollectionChanged; public event ModelCollectionChangedEventHandler<T> CollectionChanged
{
add {
collectionChangedEvent.AddHandler(value);
}
remove {
collectionChangedEvent.RemoveHandler(value);
}
}
bool isWithinBatchOperation; bool isWithinBatchOperation;
bool isRaisingEvent; bool isRaisingEvent;
@ -64,9 +75,7 @@ namespace ICSharpCode.SharpDevelop.Dom
protected virtual void OnCollectionChanged(IReadOnlyCollection<T> removedItems, IReadOnlyCollection<T> addedItems) protected virtual void OnCollectionChanged(IReadOnlyCollection<T> removedItems, IReadOnlyCollection<T> addedItems)
{ {
var handler = CollectionChanged; collectionChangedEvent.Fire(removedItems, addedItems);
if (handler != null)
handler(removedItems, addedItems);
} }
public virtual IDisposable BatchUpdate() public virtual IDisposable BatchUpdate()

7
src/Main/Base/Project/ICSharpCode.SharpDevelop.addin

@ -134,6 +134,7 @@
title = "${res:MainWindow.Windows.ClassScoutLabel}" title = "${res:MainWindow.Windows.ClassScoutLabel}"
icon = "PadIcons.ClassBrowser" icon = "PadIcons.ClassBrowser"
class = "ICSharpCode.SharpDevelop.Dom.ClassBrowser.ClassBrowserPad" class = "ICSharpCode.SharpDevelop.Dom.ClassBrowser.ClassBrowserPad"
serviceInterface = "ICSharpCode.SharpDevelop.Dom.ClassBrowser.IClassBrowser"
defaultPosition = "Right" /> defaultPosition = "Right" />
<Pad id = "SideBar" <Pad id = "SideBar"
@ -919,6 +920,10 @@
class = "ICSharpCode.SharpDevelop.Gui.ClassBrowser.ClassBrowserNavigateForward"/> class = "ICSharpCode.SharpDevelop.Gui.ClassBrowser.ClassBrowserNavigateForward"/>
<ToolbarItem id = "NavigationSeparator" type = "Separator"/> <ToolbarItem id = "NavigationSeparator" type = "Separator"/>
<ToolbarItem id = "OpenAssembly"
icon = "Icons.16x16.OpenProjectIcon"
tooltip = "${res:MainWindow.Windows.ClassBrowser.OpenAssembly.ToolTip}"
class = "ICSharpCode.SharpDevelop.Dom.ClassBrowser.OpenAssemblyCommand"/>
<ToolbarItem id = "SelectFilter" <ToolbarItem id = "SelectFilter"
type = "DropDownButton" type = "DropDownButton"
icon = "Icons.16x16.FindInFiles" icon = "Icons.16x16.FindInFiles"
@ -2275,7 +2280,7 @@
</Path> </Path>
<Path name="/SharpDevelop/TreeNodeFactories"> <Path name="/SharpDevelop/TreeNodeFactories">
<Class id="WorkspaceTreeNodesFactory" class="ICSharpCode.SharpDevelop.Dom.ClassBrowser.WorkspaceTreeNodesFactory" /> <Class id="ClassBrowserTreeNodesFactory" class="ICSharpCode.SharpDevelop.Dom.ClassBrowser.ClassBrowserTreeNodesFactory" />
</Path> </Path>
<Path name = "/SharpDevelop/Views/ClassBrowser/ClassNodeBuilders"> <Path name = "/SharpDevelop/Views/ClassBrowser/ClassNodeBuilders">

9
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -84,8 +84,15 @@
</Compile> </Compile>
<Compile Include="Designer\IDesignerTypeResolutionService.cs" /> <Compile Include="Designer\IDesignerTypeResolutionService.cs" />
<Compile Include="Designer\TypeResolutionService.cs" /> <Compile Include="Designer\TypeResolutionService.cs" />
<Compile Include="Dom\ClassBrowser\AssemblyTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\ClassBrowserTreeView.cs" /> <Compile Include="Dom\ClassBrowser\ClassBrowserTreeView.cs" />
<Compile Include="Dom\ClassBrowser\ClassBrowserWorkspace.cs" /> <Compile Include="Dom\ClassBrowser\IClassBrowser.cs" />
<Compile Include="Dom\ClassBrowser\MemberTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\NamespaceTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\ProjectTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\SolutionTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\TypeDefinitionTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\WorkspaceModel.cs" />
<Compile Include="Dom\ClassBrowser\WorkspaceTreeNode.cs" /> <Compile Include="Dom\ClassBrowser\WorkspaceTreeNode.cs" />
<Compile Include="Dom\IAssemblyModel.cs" /> <Compile Include="Dom\IAssemblyModel.cs" />
<Compile Include="Dom\IEntityModelContext.cs" /> <Compile Include="Dom\IEntityModelContext.cs" />

5
src/Main/Base/Project/Refactoring/ContextAction.cs

@ -22,6 +22,11 @@ namespace ICSharpCode.SharpDevelop.Refactoring
public abstract string DisplayName { get; } public abstract string DisplayName { get; }
public virtual string GetDisplayName(EditorRefactoringContext context)
{
return DisplayName;
}
public virtual string Category { public virtual string Category {
get { return string.Empty; } get { return string.Empty; }
} }

6
src/Main/Base/Project/Refactoring/IContextAction.cs

@ -18,9 +18,11 @@ namespace ICSharpCode.SharpDevelop.Refactoring
IContextActionProvider Provider { get; } IContextActionProvider Provider { get; }
/// <summary> /// <summary>
/// Name displayed in the context actions popup. /// Name displayed in the context action's popup.
/// </summary> /// </summary>
string DisplayName { get; } /// <param name="context">Refactoring context that can be used by the context action to create the display name.</param>
/// <returns></returns>
string GetDisplayName(EditorRefactoringContext context);
/// <summary> /// <summary>
/// Executes this action. Called when this action is selected from the context actions popup. /// Executes this action. Called when this action is selected from the context actions popup.

17
src/Main/Base/Project/Src/Internal/Doozers/PadDescriptor.cs

@ -37,6 +37,9 @@ namespace ICSharpCode.SharpDevelop
AddIn addIn; AddIn addIn;
Type padType; Type padType;
string serviceInterfaceName;
Type serviceInterface;
IPadContent padContent; IPadContent padContent;
bool padContentCreated; bool padContentCreated;
@ -53,6 +56,7 @@ namespace ICSharpCode.SharpDevelop
icon = codon.Properties["icon"]; icon = codon.Properties["icon"];
title = codon.Properties["title"]; title = codon.Properties["title"];
@class = codon.Properties["class"]; @class = codon.Properties["class"];
serviceInterfaceName = codon.Properties["serviceInterface"];
if (!string.IsNullOrEmpty(codon.Properties["defaultPosition"])) { if (!string.IsNullOrEmpty(codon.Properties["defaultPosition"])) {
DefaultPosition = (DefaultPadPositions)Enum.Parse(typeof(DefaultPadPositions), codon.Properties["defaultPosition"]); DefaultPosition = (DefaultPadPositions)Enum.Parse(typeof(DefaultPadPositions), codon.Properties["defaultPosition"]);
} }
@ -75,6 +79,7 @@ namespace ICSharpCode.SharpDevelop
this.icon = icon; this.icon = icon;
this.category = "none"; this.category = "none";
this.shortcut = ""; this.shortcut = "";
this.serviceInterface = null;
} }
/// <summary> /// <summary>
@ -134,6 +139,18 @@ namespace ICSharpCode.SharpDevelop
} }
} }
/// <summary>
/// Gets the type of the service interface.
/// </summary>
public Type ServiceInterface {
get {
if (serviceInterface == null && addIn != null && !string.IsNullOrEmpty(serviceInterfaceName)) {
serviceInterface = addIn.FindType(serviceInterfaceName);
}
return serviceInterface;
}
}
/// <summary> /// <summary>
/// Gets/sets the default position of the pad. /// Gets/sets the default position of the pad.
/// </summary> /// </summary>

1
src/Main/Base/Project/Src/Project/CompilableProject.cs

@ -358,6 +358,7 @@ namespace ICSharpCode.SharpDevelop.Project
assemblyModel = SD.GetRequiredService<IModelFactory>().CreateAssemblyModel(new ProjectEntityModelContext(this, ".cs")); assemblyModel = SD.GetRequiredService<IModelFactory>().CreateAssemblyModel(new ProjectEntityModelContext(this, ".cs"));
var pc = ProjectContent; var pc = ProjectContent;
if (pc != null && assemblyModel is IUpdateableAssemblyModel) { if (pc != null && assemblyModel is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)assemblyModel).AssemblyName = AssemblyName;
// Add the already loaded files into the model // Add the already loaded files into the model
foreach (var file in pc.Files) { foreach (var file in pc.Files) {
((IUpdateableAssemblyModel)assemblyModel).Update(null, file); ((IUpdateableAssemblyModel)assemblyModel).Update(null, file);

18
src/Main/Base/Project/Src/Project/MSBuildConfigurationOrPlatformNameCollection.cs

@ -16,9 +16,8 @@ namespace ICSharpCode.SharpDevelop.Project
/// </summary> /// </summary>
class MSBuildConfigurationOrPlatformNameCollection : IConfigurationOrPlatformNameCollection class MSBuildConfigurationOrPlatformNameCollection : IConfigurationOrPlatformNameCollection
{ {
public event ModelCollectionChangedEventHandler<string> CollectionChanged;
volatile IReadOnlyList<string> listSnapshot = EmptyList<string>.Instance; volatile IReadOnlyList<string> listSnapshot = EmptyList<string>.Instance;
readonly ModelCollectionChangedEvent<string> collectionChangedEvent;
readonly MSBuildBasedProject project; readonly MSBuildBasedProject project;
readonly bool isPlatform; readonly bool isPlatform;
@ -26,6 +25,7 @@ namespace ICSharpCode.SharpDevelop.Project
{ {
this.project = project; this.project = project;
this.isPlatform = isPlatform; this.isPlatform = isPlatform;
collectionChangedEvent = new ModelCollectionChangedEvent<string>();
} }
internal void SetContents(IEnumerable<string> updatedItems) internal void SetContents(IEnumerable<string> updatedItems)
@ -33,13 +33,21 @@ namespace ICSharpCode.SharpDevelop.Project
this.listSnapshot = updatedItems.ToArray(); this.listSnapshot = updatedItems.ToArray();
} }
public event ModelCollectionChangedEventHandler<string> CollectionChanged
{
add {
collectionChangedEvent.AddHandler(value);
}
remove {
collectionChangedEvent.RemoveHandler(value);
}
}
internal void OnCollectionChanged(IReadOnlyCollection<string> oldItems, IReadOnlyCollection<string> newItems) internal void OnCollectionChanged(IReadOnlyCollection<string> oldItems, IReadOnlyCollection<string> newItems)
{ {
if (oldItems.SequenceEqual(newItems)) if (oldItems.SequenceEqual(newItems))
return; return;
var eh = CollectionChanged; collectionChangedEvent.Fire(oldItems, newItems);
if (eh != null)
eh(oldItems, newItems);
} }
#region IReadOnlyCollection implementation #region IReadOnlyCollection implementation

4
src/Main/Base/Project/Util/SharpDevelopExtensions.cs

@ -537,7 +537,7 @@ namespace ICSharpCode.SharpDevelop
foreach (var memberModel in typeModel.Members) { foreach (var memberModel in typeModel.Members) {
if (memberModel.Name == member.Name) { if (memberModel.Name == member.Name) {
if (memberModel.Resolve(snapshot) == member.MemberDefinition) { if (memberModel.Resolve() == member.MemberDefinition) {
return memberModel; return memberModel;
} }
} }
@ -580,7 +580,7 @@ namespace ICSharpCode.SharpDevelop
foreach (var memberModel in typeModel.Members) { foreach (var memberModel in typeModel.Members) {
if (memberModel.Name == unresolvedMember.Name) { if (memberModel.Name == unresolvedMember.Name) {
if (memberModel.Resolve(snapshot) == member.MemberDefinition) { if (memberModel.Resolve() == member.MemberDefinition) {
return memberModel; return memberModel;
} }
} }

2
src/Main/Base/Test/Dom/CSharpModelTestBase.cs

@ -43,7 +43,7 @@ namespace ICSharpCode.SharpDevelop.Dom
project = MockRepository.GenerateStrictMock<IProject>(); project = MockRepository.GenerateStrictMock<IProject>();
projectContent = new CSharpProjectContent().AddAssemblyReferences(AssemblyLoader.Corlib); projectContent = new CSharpProjectContent().AddAssemblyReferences(AssemblyLoader.Corlib);
context = new ProjectEntityModelContext(project, ".cs"); context = new ProjectEntityModelContext(project, ".cs");
assemblyModel = new ProjectAssemblyModel(context); assemblyModel = new AssemblyModel(context);
SD.ParserService.Stub(p => p.GetCompilation(project)).WhenCalled(c => c.ReturnValue = projectContent.CreateCompilation()); SD.ParserService.Stub(p => p.GetCompilation(project)).WhenCalled(c => c.ReturnValue = projectContent.CreateCompilation());
} }

29
src/Main/SharpDevelop/Dom/ProjectAssemblyModel.cs → src/Main/SharpDevelop/Dom/AssemblyModel.cs

@ -5,35 +5,32 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
{ {
sealed class ProjectAssemblyModel : IUpdateableAssemblyModel sealed class AssemblyModel : IUpdateableAssemblyModel
{ {
IEntityModelContext context; IEntityModelContext context;
TopLevelTypeDefinitionModelCollection typeDeclarations; TopLevelTypeDefinitionModelCollection typeDeclarations;
KeyedModelCollection<string, NamespaceModel> namespaces; KeyedModelCollection<string, NamespaceModel> namespaces;
NamespaceModel rootNamespace; NamespaceModel rootNamespace;
public ProjectAssemblyModel(IEntityModelContext context) public AssemblyModel(IEntityModelContext context)
{ {
if (context == null) if (context == null)
throw new ArgumentNullException("context"); throw new ArgumentNullException("context");
this.context = context; this.context = context;
this.rootNamespace = new NamespaceModel(context, null, ""); this.rootNamespace = new NamespaceModel(context.Project, null, "");
this.typeDeclarations = new TopLevelTypeDefinitionModelCollection(context); this.typeDeclarations = new TopLevelTypeDefinitionModelCollection(context);
this.typeDeclarations.CollectionChanged += TypeDeclarationsCollectionChanged; this.typeDeclarations.CollectionChanged += TypeDeclarationsCollectionChanged;
this.namespaces = new KeyedModelCollection<string, NamespaceModel>(value => value.FullName); this.namespaces = new KeyedModelCollection<string, NamespaceModel>(value => value.FullName);
} }
public string AssemblyName { public string AssemblyName { get; set; }
get {
return context.Project.AssemblyName;
}
}
public ITypeDefinitionModelCollection TopLevelTypeDefinitions { public ITypeDefinitionModelCollection TopLevelTypeDefinitions {
get { get {
@ -54,6 +51,18 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
public void Update(IUnresolvedFile oldFile, IUnresolvedFile newFile) public void Update(IUnresolvedFile oldFile, IUnresolvedFile newFile)
{
IList<IUnresolvedTypeDefinition> old = EmptyList<IUnresolvedTypeDefinition>.Instance;
IList<IUnresolvedTypeDefinition> @new = EmptyList<IUnresolvedTypeDefinition>.Instance;
if (oldFile != null)
old = oldFile.TopLevelTypeDefinitions;
if (newFile != null)
@new = newFile.TopLevelTypeDefinitions;
typeDeclarations.Update(old, @new);
}
public void Update(IList<IUnresolvedTypeDefinition> oldFile, IList<IUnresolvedTypeDefinition> newFile)
{ {
typeDeclarations.Update(oldFile, newFile); typeDeclarations.Update(oldFile, newFile);
} }
@ -76,7 +85,7 @@ namespace ICSharpCode.SharpDevelop.Dom
level++; level++;
} }
while (level < parts.Length) { while (level < parts.Length) {
var child = new NamespaceModel(context, ns, parts[level]); var child = new NamespaceModel(context.Project, ns, parts[level]);
batchList.AddIfNotNull(ns.ChildNamespaces.BatchUpdate()); batchList.AddIfNotNull(ns.ChildNamespaces.BatchUpdate());
ns.ChildNamespaces.Add(child); ns.ChildNamespaces.Add(child);
ns = child; ns = child;
@ -116,5 +125,3 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
} }

28
src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs

@ -2,6 +2,8 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Windows.Controls; using System.Windows.Controls;
using ICSharpCode.Core.Presentation; using ICSharpCode.Core.Presentation;
@ -11,8 +13,21 @@ using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{ {
public class ClassBrowserPad : AbstractPadContent class ClassBrowserPad : AbstractPadContent, IClassBrowser
{ {
#region IClassBrowser implementation
public ICollection<SharpTreeNode> SpecialNodes {
get { return treeView.SpecialNodes; }
}
public AssemblyList AssemblyList {
get { return treeView.AssemblyList; }
set { treeView.AssemblyList = value; }
}
#endregion
IProjectService projectService; IProjectService projectService;
ClassBrowserTreeView treeView; ClassBrowserTreeView treeView;
DockPanel panel; DockPanel panel;
@ -26,7 +41,6 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
public ClassBrowserPad(IProjectService projectService) public ClassBrowserPad(IProjectService projectService)
{ {
this.projectService = projectService; this.projectService = projectService;
panel = new DockPanel(); panel = new DockPanel();
treeView = new ClassBrowserTreeView(); // treeView must be created first because it's used by CreateToolBar treeView = new ClassBrowserTreeView(); // treeView must be created first because it's used by CreateToolBar
@ -37,7 +51,6 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
panel.Children.Add(treeView); panel.Children.Add(treeView);
//treeView.ContextMenu = CreateContextMenu("/SharpDevelop/Pads/UnitTestsPad/ContextMenu"); //treeView.ContextMenu = CreateContextMenu("/SharpDevelop/Pads/UnitTestsPad/ContextMenu");
projectService.CurrentSolutionChanged += ProjectServiceCurrentSolutionChanged; projectService.CurrentSolutionChanged += ProjectServiceCurrentSolutionChanged;
ProjectServiceCurrentSolutionChanged(null, null); ProjectServiceCurrentSolutionChanged(null, null);
} }
@ -58,11 +71,10 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
void ProjectServiceCurrentSolutionChanged(object sender, EventArgs e) void ProjectServiceCurrentSolutionChanged(object sender, EventArgs e)
{ {
if (projectService.CurrentSolution == null) { foreach (var node in treeView.SpecialNodes.OfType<SolutionTreeNode>().ToArray())
treeView.Workspace = ClassBrowserSettings.LoadDefaultWorkspace(); treeView.SpecialNodes.Remove(node);
} else { if (projectService.CurrentSolution != null)
treeView.Workspace = ClassBrowserSettings.LoadForSolution(projectService.CurrentSolution); treeView.SpecialNodes.Add(new SolutionTreeNode(projectService.CurrentSolution));
}
} }
/// <summary> /// <summary>

5
src/Main/SharpDevelop/Dom/ClassBrowser/WorkspaceTreeNodesFactory.cs → src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserTreeNodesFactory.cs

@ -2,15 +2,12 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using System.Collections.Generic;
using System.Windows.Media;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.TreeView; using ICSharpCode.TreeView;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{ {
public class WorkspaceTreeNodesFactory : ITreeNodeFactory class ClassBrowserTreeNodesFactory : ITreeNodeFactory
{ {
public Type GetSupportedType(object model) public Type GetSupportedType(object model)
{ {

18
src/Main/SharpDevelop/Dom/ClassBrowser/OpenAssemblyCommand.cs

@ -0,0 +1,18 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using Microsoft.Win32;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
/// <summary>
/// Description of OpenAssemblyCommand.
/// </summary>
class OpenAssemblyCommand : SimpleCommand
{
public override void Execute(object parameter)
{
}
}
}

9
src/Main/SharpDevelop/Dom/MemberModel.cs

@ -77,13 +77,12 @@ namespace ICSharpCode.SharpDevelop.Dom
#region Resolve #region Resolve
public IMember Resolve() public IMember Resolve()
{ {
var compilation = context.GetCompilation(null); var compilation = context.GetCompilation();
return member.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)); return member.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly));
} }
public IMember Resolve(ISolutionSnapshotWithProjectMapping solutionSnapshot) public IMember Resolve(ICompilation compilation)
{ {
var compilation = context.GetCompilation(solutionSnapshot);
return member.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)); return member.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly));
} }
@ -92,9 +91,9 @@ namespace ICSharpCode.SharpDevelop.Dom
return Resolve(); return Resolve();
} }
IEntity IEntityModel.Resolve(ISolutionSnapshotWithProjectMapping solutionSnapshot) IEntity IEntityModel.Resolve(ICompilation compilation)
{ {
return Resolve(solutionSnapshot); return Resolve(compilation);
} }
#endregion #endregion

2
src/Main/SharpDevelop/Dom/ModelFactory.cs

@ -10,7 +10,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
public IAssemblyModel CreateAssemblyModel(IEntityModelContext context) public IAssemblyModel CreateAssemblyModel(IEntityModelContext context)
{ {
return new ProjectAssemblyModel(context); return new AssemblyModel(context);
} }
public ITypeDefinitionModel CreateTypeDefinitionModel(IEntityModelContext context, params IUnresolvedTypeDefinition[] parts) public ITypeDefinitionModel CreateTypeDefinitionModel(IEntityModelContext context, params IUnresolvedTypeDefinition[] parts)

10
src/Main/SharpDevelop/Dom/NamespaceModel.cs

@ -11,17 +11,15 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
sealed class NamespaceModel : INamespaceModel sealed class NamespaceModel : INamespaceModel
{ {
IEntityModelContext context; IProject parentProject;
string name; string name;
NamespaceModel parent; NamespaceModel parent;
NullSafeSimpleModelCollection<NamespaceModel> childNamespaces; NullSafeSimpleModelCollection<NamespaceModel> childNamespaces;
NullSafeSimpleModelCollection<ITypeDefinitionModel> typeDefinitions; NullSafeSimpleModelCollection<ITypeDefinitionModel> typeDefinitions;
public NamespaceModel(IEntityModelContext context, NamespaceModel parent, string name) public NamespaceModel(IProject parentProject, NamespaceModel parent, string name)
{ {
if (context == null) this.parentProject = parentProject;
throw new ArgumentNullException("context");
this.context = context;
this.parent = parent; this.parent = parent;
this.name = name; this.name = name;
this.typeDefinitions = new NullSafeSimpleModelCollection<ITypeDefinitionModel>(); this.typeDefinitions = new NullSafeSimpleModelCollection<ITypeDefinitionModel>();
@ -67,7 +65,7 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
public IProject ParentProject { public IProject ParentProject {
get { return context.Project; } get { return parentProject; }
} }
public DomRegion Region { public DomRegion Region {

16
src/Main/SharpDevelop/Dom/NestedTypeDefinitionModelCollection.cs

@ -11,15 +11,25 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
sealed class NestedTypeDefinitionModelCollection : IModelCollection<ITypeDefinitionModel> sealed class NestedTypeDefinitionModelCollection : IModelCollection<ITypeDefinitionModel>
{ {
readonly ModelCollectionChangedEvent<ITypeDefinitionModel> collectionChangedEvent;
readonly IEntityModelContext context; readonly IEntityModelContext context;
List<TypeDefinitionModel> list = new List<TypeDefinitionModel>(); List<TypeDefinitionModel> list = new List<TypeDefinitionModel>();
public NestedTypeDefinitionModelCollection(IEntityModelContext context) public NestedTypeDefinitionModelCollection(IEntityModelContext context)
{ {
this.context = context; this.context = context;
collectionChangedEvent = new ModelCollectionChangedEvent<ITypeDefinitionModel>();
} }
public event ModelCollectionChangedEventHandler<ITypeDefinitionModel> CollectionChanged; public event ModelCollectionChangedEventHandler<ITypeDefinitionModel> CollectionChanged
{
add {
collectionChangedEvent.AddHandler(value);
}
remove {
collectionChangedEvent.RemoveHandler(value);
}
}
public IReadOnlyCollection<ITypeDefinitionModel> CreateSnapshot() public IReadOnlyCollection<ITypeDefinitionModel> CreateSnapshot()
{ {
@ -107,9 +117,9 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
// Raise the event if necessary: // Raise the event if necessary:
if (CollectionChanged != null && (oldModels != null || newModels != null)) { if (collectionChangedEvent.ContainsHandlers && (oldModels != null || newModels != null)) {
IReadOnlyCollection<ITypeDefinitionModel> emptyList = EmptyList<ITypeDefinitionModel>.Instance; IReadOnlyCollection<ITypeDefinitionModel> emptyList = EmptyList<ITypeDefinitionModel>.Instance;
CollectionChanged(oldModels ?? emptyList, newModels ?? emptyList); collectionChangedEvent.Fire(oldModels ?? emptyList, newModels ?? emptyList);
} }
} }
} }

36
src/Main/SharpDevelop/Dom/TopLevelTypeDefinitionModelCollection.cs

@ -16,6 +16,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// </summary> /// </summary>
sealed class TopLevelTypeDefinitionModelCollection : ITypeDefinitionModelCollection sealed class TopLevelTypeDefinitionModelCollection : ITypeDefinitionModelCollection
{ {
readonly ModelCollectionChangedEvent<ITypeDefinitionModel> collectionChangedEvent;
readonly IEntityModelContext context; readonly IEntityModelContext context;
Dictionary<TopLevelTypeName, TypeDefinitionModel> dict = new Dictionary<TopLevelTypeName, TypeDefinitionModel>(); Dictionary<TopLevelTypeName, TypeDefinitionModel> dict = new Dictionary<TopLevelTypeName, TypeDefinitionModel>();
@ -24,9 +25,18 @@ namespace ICSharpCode.SharpDevelop.Dom
if (context == null) if (context == null)
throw new ArgumentNullException("context"); throw new ArgumentNullException("context");
this.context = context; this.context = context;
collectionChangedEvent = new ModelCollectionChangedEvent<ITypeDefinitionModel>();
} }
public event ModelCollectionChangedEventHandler<ITypeDefinitionModel> CollectionChanged; public event ModelCollectionChangedEventHandler<ITypeDefinitionModel> CollectionChanged
{
add {
collectionChangedEvent.AddHandler(value);
}
remove {
collectionChangedEvent.RemoveHandler(value);
}
}
public IReadOnlyCollection<ITypeDefinitionModel> CreateSnapshot() public IReadOnlyCollection<ITypeDefinitionModel> CreateSnapshot()
{ {
@ -62,29 +72,28 @@ namespace ICSharpCode.SharpDevelop.Dom
/// <summary> /// <summary>
/// Updates the parse information. /// Updates the parse information.
/// </summary> /// </summary>
public void Update(IUnresolvedFile oldFile, IUnresolvedFile newFile) public void Update(IList<IUnresolvedTypeDefinition> oldFile, IList<IUnresolvedTypeDefinition> newFile)
{ {
List<ITypeDefinitionModel> oldModels = null; List<ITypeDefinitionModel> oldModels = null;
List<ITypeDefinitionModel> newModels = null; List<ITypeDefinitionModel> newModels = null;
bool[] oldTypeDefHandled = null; bool[] oldTypeDefHandled = null;
if (oldFile != null) { if (oldFile.Count > 0) {
oldTypeDefHandled = new bool[oldFile.TopLevelTypeDefinitions.Count]; oldTypeDefHandled = new bool[oldFile.Count];
} }
if (newFile != null) { foreach (var newPart in newFile) {
foreach (var newPart in newFile.TopLevelTypeDefinitions) {
FullTypeName newFullTypeName = newPart.FullTypeName; FullTypeName newFullTypeName = newPart.FullTypeName;
TypeDefinitionModel model; TypeDefinitionModel model;
if (dict.TryGetValue(newFullTypeName.TopLevelTypeName, out model)) { if (dict.TryGetValue(newFullTypeName.TopLevelTypeName, out model)) {
// Existing type changed // Existing type changed
// Find a matching old part: // Find a matching old part:
IUnresolvedTypeDefinition oldPart = null; IUnresolvedTypeDefinition oldPart = null;
if (oldFile != null) { if (oldTypeDefHandled != null) {
for (int i = 0; i < oldTypeDefHandled.Length; i++) { for (int i = 0; i < oldTypeDefHandled.Length; i++) {
if (oldTypeDefHandled[i]) if (oldTypeDefHandled[i])
continue; continue;
if (oldFile.TopLevelTypeDefinitions[i].FullTypeName == newFullTypeName) { if (oldFile[i].FullTypeName == newFullTypeName) {
oldTypeDefHandled[i] = true; oldTypeDefHandled[i] = true;
oldPart = oldFile.TopLevelTypeDefinitions[i]; oldPart = oldFile[i];
break; break;
} }
} }
@ -99,12 +108,11 @@ namespace ICSharpCode.SharpDevelop.Dom
newModels.Add(model); newModels.Add(model);
} }
} }
}
// Remove all old parts that weren't updated: // Remove all old parts that weren't updated:
if (oldFile != null) { if (oldTypeDefHandled != null) {
for (int i = 0; i < oldTypeDefHandled.Length; i++) { for (int i = 0; i < oldTypeDefHandled.Length; i++) {
if (!oldTypeDefHandled[i]) { if (!oldTypeDefHandled[i]) {
IUnresolvedTypeDefinition oldPart = oldFile.TopLevelTypeDefinitions[i]; IUnresolvedTypeDefinition oldPart = oldFile[i];
TopLevelTypeName topLevelTypeName = oldPart.FullTypeName.TopLevelTypeName; TopLevelTypeName topLevelTypeName = oldPart.FullTypeName.TopLevelTypeName;
TypeDefinitionModel model; TypeDefinitionModel model;
if (dict.TryGetValue(topLevelTypeName, out model)) { if (dict.TryGetValue(topLevelTypeName, out model)) {
@ -122,9 +130,9 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
// Raise the event if necessary: // Raise the event if necessary:
if (CollectionChanged != null && (oldModels != null || newModels != null)) { if (collectionChangedEvent.ContainsHandlers && (oldModels != null || newModels != null)) {
IReadOnlyCollection<ITypeDefinitionModel> emptyList = EmptyList<ITypeDefinitionModel>.Instance; IReadOnlyCollection<ITypeDefinitionModel> emptyList = EmptyList<ITypeDefinitionModel>.Instance;
CollectionChanged(oldModels ?? emptyList, newModels ?? emptyList); collectionChangedEvent.Fire(oldModels ?? emptyList, newModels ?? emptyList);
} }
} }

33
src/Main/SharpDevelop/Dom/TypeDefinitionModel.cs

@ -79,13 +79,12 @@ namespace ICSharpCode.SharpDevelop.Dom
#region Resolve #region Resolve
public ITypeDefinition Resolve() public ITypeDefinition Resolve()
{ {
var compilation = context.GetCompilation(null); var compilation = context.GetCompilation();
return compilation.MainAssembly.GetTypeDefinition(fullTypeName); return compilation.MainAssembly.GetTypeDefinition(fullTypeName);
} }
public ITypeDefinition Resolve(ISolutionSnapshotWithProjectMapping solutionSnapshot) public ITypeDefinition Resolve(ICompilation compilation)
{ {
var compilation = context.GetCompilation(solutionSnapshot);
return compilation.MainAssembly.GetTypeDefinition(fullTypeName); return compilation.MainAssembly.GetTypeDefinition(fullTypeName);
} }
@ -94,9 +93,9 @@ namespace ICSharpCode.SharpDevelop.Dom
return Resolve(); return Resolve();
} }
IEntity IEntityModel.Resolve(ISolutionSnapshotWithProjectMapping solutionSnapshot) IEntity IEntityModel.Resolve(ICompilation compilation)
{ {
return Resolve(solutionSnapshot); return Resolve(compilation);
} }
#endregion #endregion
@ -105,12 +104,14 @@ namespace ICSharpCode.SharpDevelop.Dom
#region Members collection #region Members collection
sealed class MemberCollection : IModelCollection<MemberModel> sealed class MemberCollection : IModelCollection<MemberModel>
{ {
readonly ModelCollectionChangedEvent<MemberModel> collectionChangedEvent;
readonly TypeDefinitionModel parent; readonly TypeDefinitionModel parent;
List<List<MemberModel>> lists = new List<List<MemberModel>>(); List<List<MemberModel>> lists = new List<List<MemberModel>>();
public MemberCollection(TypeDefinitionModel parent) public MemberCollection(TypeDefinitionModel parent)
{ {
this.parent = parent; this.parent = parent;
collectionChangedEvent = new ModelCollectionChangedEvent<MemberModel>();
} }
public void InsertPart(int partIndex, IUnresolvedTypeDefinition newPart) public void InsertPart(int partIndex, IUnresolvedTypeDefinition newPart)
@ -120,16 +121,14 @@ namespace ICSharpCode.SharpDevelop.Dom
newItems.Add(new MemberModel(parent.context, newMember) { strongParentCollectionReference = this }); newItems.Add(new MemberModel(parent.context, newMember) { strongParentCollectionReference = this });
} }
lists.Insert(partIndex, newItems); lists.Insert(partIndex, newItems);
if (collectionChanged != null) collectionChangedEvent.Fire(EmptyList<MemberModel>.Instance, newItems);
collectionChanged(EmptyList<MemberModel>.Instance, newItems);
} }
public void RemovePart(int partIndex) public void RemovePart(int partIndex)
{ {
var oldItems = lists[partIndex]; var oldItems = lists[partIndex];
lists.RemoveAt(partIndex); lists.RemoveAt(partIndex);
if (collectionChanged != null) collectionChangedEvent.Fire(oldItems, EmptyList<MemberModel>.Instance);
collectionChanged(oldItems, EmptyList<MemberModel>.Instance);
} }
public void UpdatePart(int partIndex, IUnresolvedTypeDefinition newPart) public void UpdatePart(int partIndex, IUnresolvedTypeDefinition newPart)
@ -158,7 +157,7 @@ namespace ICSharpCode.SharpDevelop.Dom
// We might try to be clever here and find a LCS so that we only update the members that were actually changed, // We might try to be clever here and find a LCS so that we only update the members that were actually changed,
// or we might consider moving members around (INotifyCollectionChanged supports moves) // or we might consider moving members around (INotifyCollectionChanged supports moves)
// However, the easiest solution by far is to just remove + readd the whole middle portion. // However, the easiest solution by far is to just remove + readd the whole middle portion.
var oldItems = collectionChanged != null ? list.GetRange(startPos, endPosOld - startPos) : null; var oldItems = collectionChangedEvent.ContainsHandlers ? list.GetRange(startPos, endPosOld - startPos) : null;
list.RemoveRange(startPos, endPosOld - startPos); list.RemoveRange(startPos, endPosOld - startPos);
var newItems = new MemberModel[endPosNew - startPos]; var newItems = new MemberModel[endPosNew - startPos];
for (int i = 0; i < newItems.Length; i++) { for (int i = 0; i < newItems.Length; i++) {
@ -166,8 +165,8 @@ namespace ICSharpCode.SharpDevelop.Dom
newItems[i].strongParentCollectionReference = this; newItems[i].strongParentCollectionReference = this;
} }
list.InsertRange(startPos, newItems); list.InsertRange(startPos, newItems);
if (collectionChanged != null && (oldItems.Count > 0 || newItems.Length > 0)) { if (collectionChangedEvent.ContainsHandlers && (oldItems.Count > 0 || newItems.Length > 0)) {
collectionChanged(oldItems, newItems); collectionChangedEvent.Fire(oldItems, newItems);
} }
} }
@ -176,18 +175,16 @@ namespace ICSharpCode.SharpDevelop.Dom
return memberModel.SymbolKind == newMember.SymbolKind && memberModel.Name == newMember.Name; return memberModel.SymbolKind == newMember.SymbolKind && memberModel.Name == newMember.Name;
} }
ModelCollectionChangedEventHandler<MemberModel> collectionChanged;
public event ModelCollectionChangedEventHandler<MemberModel> CollectionChanged { public event ModelCollectionChangedEventHandler<MemberModel> CollectionChanged {
add { add {
collectionChanged += value; collectionChangedEvent.AddHandler(value);
// Set strong reference to collection while there are event listeners // Set strong reference to collection while there are event listeners
if (collectionChanged != null) if (collectionChangedEvent.ContainsHandlers)
parent.membersStrongReference = this; parent.membersStrongReference = this;
} }
remove { remove {
collectionChanged -= value; collectionChangedEvent.RemoveHandler(value);
if (collectionChanged == null) if (!collectionChangedEvent.ContainsHandlers)
parent.membersStrongReference = null; parent.membersStrongReference = null;
} }
} }

18
src/Main/SharpDevelop/Project/Configuration/SolutionConfigurationOrPlatformNameCollection.cs

@ -22,8 +22,7 @@ namespace ICSharpCode.SharpDevelop.Project
/// </remarks> /// </remarks>
class SolutionConfigurationOrPlatformNameCollection : IConfigurationOrPlatformNameCollection class SolutionConfigurationOrPlatformNameCollection : IConfigurationOrPlatformNameCollection
{ {
public event ModelCollectionChangedEventHandler<string> CollectionChanged; readonly ModelCollectionChangedEvent<string> collectionChangedEvent;
readonly List<string> list = new List<string>(); readonly List<string> list = new List<string>();
volatile IReadOnlyList<string> listSnapshot = EmptyList<string>.Instance; volatile IReadOnlyList<string> listSnapshot = EmptyList<string>.Instance;
readonly ISolution solution; readonly ISolution solution;
@ -33,14 +32,23 @@ namespace ICSharpCode.SharpDevelop.Project
{ {
this.solution = solution; this.solution = solution;
this.isPlatform = isPlatform; this.isPlatform = isPlatform;
collectionChangedEvent = new ModelCollectionChangedEvent<string>();
} }
void OnCollectionChanged(IReadOnlyCollection<string> oldItems, IReadOnlyCollection<string> newItems) void OnCollectionChanged(IReadOnlyCollection<string> oldItems, IReadOnlyCollection<string> newItems)
{ {
this.listSnapshot = list.ToArray(); this.listSnapshot = list.ToArray();
var eh = CollectionChanged; collectionChangedEvent.Fire(oldItems, newItems);
if (eh != null) }
eh(oldItems, newItems);
public event ModelCollectionChangedEventHandler<string> CollectionChanged
{
add {
collectionChangedEvent.AddHandler(value);
}
remove {
collectionChangedEvent.RemoveHandler(value);
}
} }
#region IReadOnlyCollection implementation #region IReadOnlyCollection implementation

5
src/Main/SharpDevelop/SharpDevelop.csproj

@ -107,12 +107,13 @@
<Link>Project\Build\MSBuildEngine\ExtendedBinaryReader.cs</Link> <Link>Project\Build\MSBuildEngine\ExtendedBinaryReader.cs</Link>
</Compile> </Compile>
<Compile Include="Dom\ClassBrowser\ClassBrowserPad.cs" /> <Compile Include="Dom\ClassBrowser\ClassBrowserPad.cs" />
<Compile Include="Dom\ClassBrowser\WorkspaceTreeNodesFactory.cs" /> <Compile Include="Dom\ClassBrowser\ClassBrowserTreeNodesFactory.cs" />
<Compile Include="Dom\ClassBrowser\OpenAssemblyCommand.cs" />
<Compile Include="Dom\ModelFactory.cs" /> <Compile Include="Dom\ModelFactory.cs" />
<Compile Include="Dom\MemberModel.cs" /> <Compile Include="Dom\MemberModel.cs" />
<Compile Include="Dom\NamespaceModel.cs" /> <Compile Include="Dom\NamespaceModel.cs" />
<Compile Include="Dom\NestedTypeDefinitionModelCollection.cs" /> <Compile Include="Dom\NestedTypeDefinitionModelCollection.cs" />
<Compile Include="Dom\ProjectAssemblyModel.cs" /> <Compile Include="Dom\AssemblyModel.cs" />
<Compile Include="Dom\TopLevelTypeDefinitionModelCollection.cs" /> <Compile Include="Dom\TopLevelTypeDefinitionModelCollection.cs" />
<Compile Include="Dom\TreeNodeFactoryService.cs" /> <Compile Include="Dom\TreeNodeFactoryService.cs" />
<Compile Include="Dom\TypeDefinitionModel.cs" /> <Compile Include="Dom\TypeDefinitionModel.cs" />

3
src/Main/SharpDevelop/Workbench/WpfWorkbench.cs

@ -432,6 +432,9 @@ namespace ICSharpCode.SharpDevelop.Workbench
throw new ArgumentException("Pad is already loaded"); throw new ArgumentException("Pad is already loaded");
padDescriptorCollection.Add(content); padDescriptorCollection.Add(content);
if (content.ServiceInterface != null) {
SD.Services.AddService(content.ServiceInterface, delegate { return content.PadContent; });
}
if (WorkbenchLayout != null) { if (WorkbenchLayout != null) {
WorkbenchLayout.ShowPad(content); WorkbenchLayout.ShowPad(content);

Loading…
Cancel
Save