Browse Source

ICSharpCode.Core: Disable lexical condition inheritance, and allow doozers to control whether to perform dynamic condition inheritance.

Building a menu node will still inherit conditions into subnodes, but included nodes now inherit conditions from the menu they are included into instead of where they are defined.
Moreover, conditions applied to an <Include> codon now are applied to the included nodes. Previously, they would be evaluated only at item build time and would disable the <Include> doozer.
4.1
Daniel Grunwald 15 years ago
parent
commit
eb0d93724e
  1. 4
      src/AddIns/Analysis/UnitTesting/Src/TestFrameworkDoozer.cs
  2. 3
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/SyntaxModeDoozer.cs
  3. 1
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/ImageSourceEditor/ChooseImageDialog.xaml.cs
  4. 3
      src/AddIns/Misc/FiletypeRegisterer/Project/Src/FiletypeAssociationDoozer.cs
  5. 21
      src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/Wizard/DialogPanelDoozer.cs
  6. 8
      src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionBinding.cs
  7. 6
      src/Main/Base/Project/Src/Editor/IEditorControlService.cs
  8. 4
      src/Main/Base/Project/Src/Gui/BrowserDisplayBinding/SchemeExtension.cs
  9. 4
      src/Main/Base/Project/Src/Internal/Doozers/DirectoryDoozer.cs
  10. 21
      src/Main/Base/Project/Src/Internal/Doozers/OptionPanelDoozer.cs
  11. 4
      src/Main/Base/Project/Src/Internal/Doozers/PadDoozer.cs
  12. 3
      src/Main/Base/Project/Src/Project/ContextSpecificProperties.cs
  13. 3
      src/Main/Base/Project/Src/Project/CustomTool.cs
  14. 2
      src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs
  15. 4
      src/Main/Base/Project/Src/Project/MSBuildEngine/MSBuildAdditionalLogger.cs
  16. 4
      src/Main/Base/Project/Src/Project/MSBuildEngine/MSBuildLoggerFilter.cs
  17. 4
      src/Main/Base/Project/Src/Services/Debugger/DebuggerDoozer.cs
  18. 7
      src/Main/Base/Project/Src/Services/DisplayBinding/DisplayBindingDoozer.cs
  19. 4
      src/Main/Base/Project/Src/Services/IconService.cs
  20. 8
      src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingDoozer.cs
  21. 4
      src/Main/Base/Project/Src/Services/ParserService/Doozer/ParserDoozer.cs
  22. 4
      src/Main/Base/Project/Src/Services/ParserService/Doozer/ProjectContentRegistryDoozer.cs
  23. 4
      src/Main/Base/Project/Src/Services/ProjectBinding/ProjectBindingDoozer.cs
  24. 1
      src/Main/Core/Project/ICSharpCode.Core.csproj
  25. 78
      src/Main/Core/Project/Src/AddInTree/AddIn/BuildItemArgs.cs
  26. 10
      src/Main/Core/Project/Src/AddInTree/AddIn/Codon.cs
  27. 3
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/ClassDoozer.cs
  28. 3
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/FileFilterDoozer.cs
  29. 4
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Icon/IconDoozer.cs
  30. 23
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/IncludeDoozer.cs
  31. 5
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/LazyDoozer.cs
  32. 4
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuItemDoozer.cs
  33. 4
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/StringDoozer.cs
  34. 4
      src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/ToolBarItem/ToolBarItemDoozer.cs
  35. 8
      src/Main/Core/Project/Src/AddInTree/AddIn/ExtensionPath.cs
  36. 11
      src/Main/Core/Project/Src/AddInTree/AddIn/IDoozer.cs
  37. 63
      src/Main/Core/Project/Src/AddInTree/AddInTree.cs
  38. 74
      src/Main/Core/Project/Src/AddInTree/AddInTreeNode.cs
  39. 3
      src/Main/Core/Test/AddInTreeTests/AddInTreeLoadingTests.cs

4
src/AddIns/Analysis/UnitTesting/Src/TestFrameworkDoozer.cs

@ -17,9 +17,9 @@ namespace ICSharpCode.UnitTesting @@ -17,9 +17,9 @@ namespace ICSharpCode.UnitTesting
get { return false; }
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return BuildItem(codon, new TestFrameworkFactory(codon.AddIn));
return BuildItem(args.Codon, new TestFrameworkFactory(args.AddIn));
}
public TestFrameworkDescriptor BuildItem(Codon codon, ITestFrameworkFactory factory)

3
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/SyntaxModeDoozer.cs

@ -100,8 +100,9 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -100,8 +100,9 @@ namespace ICSharpCode.AvalonEdit.AddIn
get { return false; }
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
Codon codon = args.Codon;
string highlightingName = codon.Properties["name"];
string[] extensions = codon.Properties["extensions"].Split(';');
string resource = codon.Properties["resource"];

1
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/ImageSourceEditor/ChooseImageDialog.xaml.cs

@ -27,7 +27,6 @@ namespace ICSharpCode.WpfDesign.AddIn.ImageSourceEditor @@ -27,7 +27,6 @@ namespace ICSharpCode.WpfDesign.AddIn.ImageSourceEditor
static readonly string[] Extension = {".jpg", ".bmp", ".png", ".gif", ".ico", ".dib", ".jpe", ".jpeg", ".tif", ".tiff"};
private ObservableCollection<ImageData> _data = new ObservableCollection<ImageData>();
string initiallySelectedFileName;
public ChooseImageDialog()
{

3
src/AddIns/Misc/FiletypeRegisterer/Project/Src/FiletypeAssociationDoozer.cs

@ -77,8 +77,9 @@ namespace ICSharpCode.FiletypeRegisterer @@ -77,8 +77,9 @@ namespace ICSharpCode.FiletypeRegisterer
/// Creates an item with the specified sub items. And the current
/// Condition status for this item.
/// </summary>
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
Codon codon = args.Codon;
return new FiletypeAssociation(codon.Id,
StringParser.Parse(codon.Properties["icon"]),
StringParser.Parse(codon.Properties["text"]));

21
src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/Wizard/DialogPanelDoozer.cs

@ -41,24 +41,21 @@ namespace ICSharpCode.Reports.Addin.ReportWizard @@ -41,24 +41,21 @@ namespace ICSharpCode.Reports.Addin.ReportWizard
/// Creates an item with the specified sub items. And the current
/// Condition status for this item.
/// </summary>
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
string label = codon.Properties["label"];
string label = args.Codon["label"];
string id = args.Codon.Id;
if (subItems == null || subItems.Count == 0) {
if (codon.Properties.Contains("class")) {
return new DefaultDialogPanelDescriptor(codon.Id, StringParser.Parse(label), codon.AddIn, codon.Properties["class"]);
var subItems = args.BuildSubItems<IDialogPanelDescriptor>();
if (subItems.Count == 0) {
if (args.Codon.Properties.Contains("class")) {
return new DefaultDialogPanelDescriptor(id, StringParser.Parse(label), args.AddIn, args.Codon["class"]);
} else {
return new DefaultDialogPanelDescriptor(codon.Id, StringParser.Parse(label));
return new DefaultDialogPanelDescriptor(id, StringParser.Parse(label));
}
}
List<IDialogPanelDescriptor> newList = new List<IDialogPanelDescriptor>();
foreach (IDialogPanelDescriptor d in subItems) {
newList.Add(d);
}
return new DefaultDialogPanelDescriptor(codon.Id, StringParser.Parse(label), newList);
return new DefaultDialogPanelDescriptor(id, StringParser.Parse(label), subItems);
}
}
}

8
src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionBinding.cs

@ -70,13 +70,13 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -70,13 +70,13 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
string ext = codon.Properties["extensions"];
string ext = args.Codon["extensions"];
if (ext != null && ext.Length > 0)
return new LazyCodeCompletionBinding(codon, ext.Split(';'));
return new LazyCodeCompletionBinding(args.Codon, ext.Split(';'));
else
return codon.AddIn.CreateObject(codon.Properties["class"]);
return args.AddIn.CreateObject(args.Codon["class"]);
}
}

6
src/Main/Base/Project/Src/Editor/IEditorControlService.cs

@ -25,11 +25,11 @@ namespace ICSharpCode.SharpDevelop.Editor @@ -25,11 +25,11 @@ namespace ICSharpCode.SharpDevelop.Editor
delegate {
// fetch IEditorControlService that's normally implemented in AvalonEdit.AddIn
var node = Core.AddInTree.GetTreeNode("/SharpDevelop/ViewContent/TextEditor/EditorControlService", false);
IEditorControlService ecs = null;
if (node != null && node.Codons.Count > 0) {
return (IEditorControlService)node.Codons[0].BuildItem(null, null);
} else {
return new DummyService();
ecs = (IEditorControlService)node.BuildChildItem(node.Codons[0], null);
}
return ecs ?? new DummyService();
}
);

4
src/Main/Base/Project/Src/Gui/BrowserDisplayBinding/SchemeExtension.cs

@ -91,9 +91,9 @@ namespace ICSharpCode.SharpDevelop.BrowserDisplayBinding @@ -91,9 +91,9 @@ namespace ICSharpCode.SharpDevelop.BrowserDisplayBinding
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return new SchemeExtensionDescriptor(codon);
return new SchemeExtensionDescriptor(args.Codon);
}
}
}

4
src/Main/Base/Project/Src/Internal/Doozers/DirectoryDoozer.cs

@ -24,9 +24,9 @@ namespace ICSharpCode.SharpDevelop @@ -24,9 +24,9 @@ namespace ICSharpCode.SharpDevelop
{
public bool HandleConditions { get { return false; } }
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return Path.Combine(Path.GetDirectoryName(codon.AddIn.FileName), codon.Properties["path"]);
return Path.Combine(Path.GetDirectoryName(args.AddIn.FileName), args.Codon["path"]);
}
}
}

21
src/Main/Base/Project/Src/Internal/Doozers/OptionPanelDoozer.cs

@ -42,24 +42,21 @@ namespace ICSharpCode.SharpDevelop @@ -42,24 +42,21 @@ namespace ICSharpCode.SharpDevelop
/// Creates an item with the specified sub items. And the current
/// Condition status for this item.
/// </summary>
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
string label = codon.Properties["label"];
string label = args.Codon["label"];
string id = args.Codon.Id;
if (subItems == null || subItems.Count == 0) {
if (codon.Properties.Contains("class")) {
return new DefaultOptionPanelDescriptor(codon.Id, StringParser.Parse(label), codon.AddIn, caller, codon.Properties["class"]);
var subItems = args.BuildSubItems<IOptionPanelDescriptor>();
if (subItems.Count == 0) {
if (args.Codon.Properties.Contains("class")) {
return new DefaultOptionPanelDescriptor(id, StringParser.Parse(label), args.AddIn, args.Caller, args.Codon["class"]);
} else {
return new DefaultOptionPanelDescriptor(codon.Id, StringParser.Parse(label));
return new DefaultOptionPanelDescriptor(id, StringParser.Parse(label));
}
}
List<IOptionPanelDescriptor> newList = new List<IOptionPanelDescriptor>();
foreach (IOptionPanelDescriptor d in subItems) {
newList.Add(d);
}
return new DefaultOptionPanelDescriptor(codon.Id, StringParser.Parse(label), newList);
return new DefaultOptionPanelDescriptor(id, StringParser.Parse(label), subItems);
}
}
}

4
src/Main/Base/Project/Src/Internal/Doozers/PadDoozer.cs

@ -51,9 +51,9 @@ namespace ICSharpCode.SharpDevelop @@ -51,9 +51,9 @@ namespace ICSharpCode.SharpDevelop
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return new PadDescriptor(codon);
return new PadDescriptor(args.Codon);
}
}
}

3
src/Main/Base/Project/Src/Project/ContextSpecificProperties.cs

@ -38,8 +38,9 @@ namespace ICSharpCode.SharpDevelop.Project @@ -38,8 +38,9 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
public object BuildItem(object caller, Codon codon, System.Collections.ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
Codon codon = args.Codon;
CustomProperty cp = new CustomProperty(codon.Properties["name"]) {
displayName = codon.Properties["displayName"],
description = codon.Properties["description"]

3
src/Main/Base/Project/Src/Project/CustomTool.cs

@ -322,8 +322,9 @@ namespace ICSharpCode.SharpDevelop.Project @@ -322,8 +322,9 @@ namespace ICSharpCode.SharpDevelop.Project
/// Creates an item with the specified sub items. And the current
/// Condition status for this item.
/// </summary>
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
Codon codon = args.Codon;
return new CustomToolDescriptor(codon.Id, codon.Properties["fileNamePattern"],
codon.Properties["class"], codon.AddIn);
}

2
src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs

@ -1176,7 +1176,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -1176,7 +1176,7 @@ namespace ICSharpCode.SharpDevelop.Project
AddInTreeNode node = AddInTree.GetTreeNode(MSBuildEngine.AdditionalPropertiesPath, false);
if (node != null) {
foreach (Codon codon in node.Codons) {
object item = codon.BuildItem(null, new System.Collections.ArrayList());
object item = node.BuildChildItem(codon, null);
if (item != null) {
string text = item.ToString();
globalProperties[codon.Id] = text;

4
src/Main/Base/Project/Src/Project/MSBuildEngine/MSBuildAdditionalLogger.cs

@ -45,9 +45,9 @@ namespace ICSharpCode.SharpDevelop.Project @@ -45,9 +45,9 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
public object BuildItem(object caller, Codon codon, System.Collections.ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return new TaskBoundAdditionalLoggerDescriptor(codon);
return new TaskBoundAdditionalLoggerDescriptor(args.Codon);
}
private class TaskBoundAdditionalLoggerDescriptor : IMSBuildAdditionalLogger

4
src/Main/Base/Project/Src/Project/MSBuildEngine/MSBuildLoggerFilter.cs

@ -55,9 +55,9 @@ namespace ICSharpCode.SharpDevelop.Project @@ -55,9 +55,9 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
public object BuildItem(object caller, Codon codon, System.Collections.ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return new TaskBoundLoggerFilterDescriptor(codon);
return new TaskBoundLoggerFilterDescriptor(args.Codon);
}
sealed class TaskBoundLoggerFilterDescriptor : IMSBuildLoggerFilter

4
src/Main/Base/Project/Src/Services/Debugger/DebuggerDoozer.cs

@ -44,9 +44,9 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -44,9 +44,9 @@ namespace ICSharpCode.SharpDevelop.Debugging
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return new DebuggerDescriptor(codon);
return new DebuggerDescriptor(args.Codon);
}
}

7
src/Main/Base/Project/Src/Services/DisplayBinding/DisplayBindingDoozer.cs

@ -65,12 +65,9 @@ namespace ICSharpCode.SharpDevelop @@ -65,12 +65,9 @@ namespace ICSharpCode.SharpDevelop
/// Creates an item with the specified sub items. And the current
/// Condition status for this item.
/// </summary>
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
// if (subItems == null || subItems.Count > 0) {
// throw new ApplicationException("Tried to buil a command with sub commands, please check the XML definition.");
// }
return new DisplayBindingDescriptor(codon);
return new DisplayBindingDescriptor(args.Codon);
}
}
}

4
src/Main/Base/Project/Src/Services/IconService.cs

@ -109,9 +109,7 @@ namespace ICSharpCode.SharpDevelop @@ -109,9 +109,7 @@ namespace ICSharpCode.SharpDevelop
extensionHashtable[".CMBX"] = "Icons.16x16.CombineIcon";
extensionHashtable[".SLN"] = "Icons.16x16.CombineIcon";
IconDescriptor[] icons = (IconDescriptor[])treeNode.BuildChildItems(null).ToArray(typeof(IconDescriptor));
for (int i = 0; i < icons.Length; ++i) {
IconDescriptor iconCodon = icons[i];
foreach (IconDescriptor iconCodon in treeNode.BuildChildItems<IconDescriptor>(null)) {
string imageName = iconCodon.Resource != null ? iconCodon.Resource : iconCodon.Id;
if (iconCodon.Extensions != null) {

8
src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingDoozer.cs

@ -29,12 +29,12 @@ namespace ICSharpCode.SharpDevelop @@ -29,12 +29,12 @@ namespace ICSharpCode.SharpDevelop
}
}
public object BuildItem(object caller, Codon codon, System.Collections.ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
ITextEditor editor = (ITextEditor)caller;
string[] extensions = codon.Properties["extensions"].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
ITextEditor editor = (ITextEditor)args.Caller;
string[] extensions = args.Codon["extensions"].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
if (CanAttach(extensions, editor.FileName)) {
return codon.AddIn.CreateObject(codon.Properties["class"]);
return args.AddIn.CreateObject(args.Codon["class"]);
} else {
return null;
}

4
src/Main/Base/Project/Src/Services/ParserService/Doozer/ParserDoozer.cs

@ -36,9 +36,9 @@ namespace ICSharpCode.SharpDevelop @@ -36,9 +36,9 @@ namespace ICSharpCode.SharpDevelop
/// Creates an item with the specified sub items. And the current
/// Condition status for this item.
/// </summary>
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return new ParserDescriptor(codon);
return new ParserDescriptor(args.Codon);
}
}
}

4
src/Main/Base/Project/Src/Services/ParserService/Doozer/ProjectContentRegistryDoozer.cs

@ -38,9 +38,9 @@ namespace ICSharpCode.SharpDevelop @@ -38,9 +38,9 @@ namespace ICSharpCode.SharpDevelop
/// Creates an item with the specified sub items. And the current
/// Condition status for this item.
/// </summary>
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return new ProjectContentRegistryDescriptor(codon);
return new ProjectContentRegistryDescriptor(args.Codon);
}
}
}

4
src/Main/Base/Project/Src/Services/ProjectBinding/ProjectBindingDoozer.cs

@ -42,9 +42,9 @@ namespace ICSharpCode.SharpDevelop @@ -42,9 +42,9 @@ namespace ICSharpCode.SharpDevelop
/// Creates an item with the specified sub items. And the current
/// Condition status for this item.
/// </summary>
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return new ProjectBindingDescriptor(codon);
return new ProjectBindingDescriptor(args.Codon);
}
}
}

1
src/Main/Core/Project/ICSharpCode.Core.csproj

@ -60,6 +60,7 @@ @@ -60,6 +60,7 @@
<Compile Include="Src\AddInTree\AddIn\AddIn.cs" />
<Compile Include="Src\AddInTree\AddIn\AddInLoadException.cs" />
<Compile Include="Src\AddInTree\AddIn\AssemblyLocator.cs" />
<Compile Include="Src\AddInTree\AddIn\BuildItemArgs.cs" />
<Compile Include="Src\AddInTree\AddIn\Codon.cs" />
<Compile Include="Src\AddInTree\AddIn\ComplexCondition.cs" />
<Compile Include="Src\AddInTree\AddIn\Condition.cs" />

78
src/Main/Core/Project/Src/AddInTree/AddIn/BuildItemArgs.cs

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
// 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;
namespace ICSharpCode.Core
{
/// <summary>
/// Argument class used for <see cref="IDoozer.BuildItem"/>.
/// </summary>
public class BuildItemArgs
{
object caller;
Codon codon;
IEnumerable<ICondition> conditions;
AddInTreeNode subItemNode;
public BuildItemArgs(object caller, Codon codon, IEnumerable<ICondition> conditions, AddInTreeNode subItemNode)
{
if (codon == null)
throw new ArgumentNullException("codon");
this.caller = caller;
this.codon = codon;
this.conditions = conditions ?? Enumerable.Empty<ICondition>();
this.subItemNode = subItemNode;
}
/// <summary>
/// The caller passed to <see cref="AddInTree.BuildItem(string,object)"/>.
/// </summary>
public object Caller {
get { return caller; }
}
/// <summary>
/// The codon to build.
/// </summary>
public Codon Codon {
get { return codon; }
}
/// <summary>
/// The addin containing the codon.
/// </summary>
public AddIn AddIn {
get { return codon.AddIn; }
}
/// <summary>
/// The conditions applied to this item.
/// </summary>
public IEnumerable<ICondition> Conditions {
get { return conditions; }
}
/// <summary>
/// The addin tree node containing the sub-items.
/// Returns null if no sub-items exist.
/// </summary>
public AddInTreeNode SubItemNode {
get { return subItemNode; }
}
/// <summary>
/// Builds the sub-items.
/// Conditions on this node are also applied to the sub-nodes.
/// </summary>
public List<T> BuildSubItems<T>()
{
if (subItemNode == null)
return new List<T>();
else
return subItemNode.BuildChildItems<T>(caller, conditions);
}
}
}

10
src/Main/Core/Project/Src/AddInTree/AddIn/Codon.cs

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace ICSharpCode.Core
{
@ -86,19 +87,20 @@ namespace ICSharpCode.Core @@ -86,19 +87,20 @@ namespace ICSharpCode.Core
// properties.BinarySerialize(writer);
// }
//
public object BuildItem(object owner, ArrayList subItems)
internal object BuildItem(BuildItemArgs args)
{
IDoozer doozer;
if (!AddInTree.Doozers.TryGetValue(Name, out doozer))
throw new CoreException("Doozer " + Name + " not found! " + ToString());
if (!doozer.HandleConditions && conditions.Length > 0) {
ConditionFailedAction action = GetFailedAction(owner);
if (!doozer.HandleConditions) {
ConditionFailedAction action = Condition.GetFailedAction(args.Conditions, args.Caller);
if (action != ConditionFailedAction.Nothing) {
return null;
}
}
return doozer.BuildItem(owner, this, subItems);
return doozer.BuildItem(args);
}
public override string ToString()

3
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/ClassDoozer.cs

@ -29,8 +29,9 @@ namespace ICSharpCode.Core @@ -29,8 +29,9 @@ namespace ICSharpCode.Core
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
Codon codon = args.Codon;
return codon.AddIn.CreateObject(codon.Properties["class"]);
}
}

3
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/FileFilterDoozer.cs

@ -31,8 +31,9 @@ namespace ICSharpCode.Core @@ -31,8 +31,9 @@ namespace ICSharpCode.Core
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
Codon codon = args.Codon;
return new FileFilterDescriptor {
Name = StringParser.Parse(codon.Properties["name"]),
Extensions = codon.Properties["extensions"]

4
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/Icon/IconDoozer.cs

@ -37,9 +37,9 @@ namespace ICSharpCode.Core @@ -37,9 +37,9 @@ namespace ICSharpCode.Core
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return new IconDescriptor(codon);
return new IconDescriptor(args.Codon);
}
}
}

23
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/IncludeDoozer.cs

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace ICSharpCode.Core
{
@ -32,46 +33,48 @@ namespace ICSharpCode.Core @@ -32,46 +33,48 @@ namespace ICSharpCode.Core
/// </summary>
public bool HandleConditions {
get {
return false;
return true;
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
Codon codon = args.Codon;
string item = codon.Properties["item"];
string path = codon.Properties["path"];
if (item != null && item.Length > 0) {
// include item
return AddInTree.BuildItem(item, caller);
return AddInTree.BuildItem(item, args.Caller, args.Conditions);
} else if (path != null && path.Length > 0) {
// include path (=multiple items)
return new IncludeReturnItem(caller, path);
return new IncludeReturnItem(args.Caller, path, args.Conditions);
} else {
MessageService.ShowMessage("<Include> requires the attribute 'item' (to include one item) or the attribute 'path' (to include multiple items)");
return null;
throw new CoreException("<Include> requires the attribute 'item' (to include one item) or the attribute 'path' (to include multiple items)");
}
}
class IncludeReturnItem : IBuildItemsModifier
sealed class IncludeReturnItem : IBuildItemsModifier
{
string path;
object caller;
IEnumerable<ICondition> additionalConditions;
public IncludeReturnItem(object caller, string path)
public IncludeReturnItem(object caller, string path, IEnumerable<ICondition> additionalConditions)
{
this.caller = caller;
this.path = path;
this.additionalConditions = additionalConditions;
}
public void Apply(IList items)
{
AddInTreeNode node = AddInTree.GetTreeNode(path, false);
if (node != null) {
foreach (object o in node.BuildChildItems(caller)) {
foreach (object o in node.BuildChildItems<object>(caller, additionalConditions)) {
items.Add(o);
}
} else {
MessageService.ShowError("IncludeDoozer: AddinTree-Path not found: " + path);
throw new CoreException("IncludeDoozer: AddinTree-Path not found: " + path);
}
}
}

5
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/LazyDoozer.cs

@ -51,14 +51,14 @@ namespace ICSharpCode.Core @@ -51,14 +51,14 @@ namespace ICSharpCode.Core
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
IDoozer doozer = (IDoozer)addIn.CreateObject(className);
if (doozer == null) {
return null;
}
AddInTree.Doozers[name] = doozer;
return doozer.BuildItem(caller, codon, subItems);
return doozer.BuildItem(args);
}
public override string ToString()
@ -67,6 +67,5 @@ namespace ICSharpCode.Core @@ -67,6 +67,5 @@ namespace ICSharpCode.Core
className,
name);
}
}
}

4
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/MenuItem/MenuItemDoozer.cs

@ -61,9 +61,9 @@ namespace ICSharpCode.Core @@ -61,9 +61,9 @@ namespace ICSharpCode.Core
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return new MenuItemDescriptor(caller, codon, subItems);
return new MenuItemDescriptor(args.Caller, args.Codon, args.BuildSubItems<object>());
}
}

4
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/StringDoozer.cs

@ -27,9 +27,9 @@ namespace ICSharpCode.Core @@ -27,9 +27,9 @@ namespace ICSharpCode.Core
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return StringParser.Parse(codon.Properties["text"]);
return StringParser.Parse(args.Codon.Properties["text"]);
}
}
}

4
src/Main/Core/Project/Src/AddInTree/AddIn/DefaultDoozers/ToolBarItem/ToolBarItemDoozer.cs

@ -51,9 +51,9 @@ namespace ICSharpCode.Core @@ -51,9 +51,9 @@ namespace ICSharpCode.Core
}
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
public object BuildItem(BuildItemArgs args)
{
return new ToolbarItemDescriptor(caller, codon, subItems);
return new ToolbarItemDescriptor(args.Caller, args.Codon, args.BuildSubItems<object>());
}
}

8
src/Main/Core/Project/Src/AddInTree/AddIn/ExtensionPath.cs

@ -57,12 +57,12 @@ namespace ICSharpCode.Core @@ -57,12 +57,12 @@ namespace ICSharpCode.Core
public static void SetUp(ExtensionPath extensionPath, XmlReader reader, string endElement)
{
Stack<ICondition> conditionStack = new Stack<ICondition>();
extensionPath.DoSetUp(reader, endElement, conditionStack);
extensionPath.DoSetUp(reader, endElement);
}
void DoSetUp(XmlReader reader, string endElement, Stack<ICondition> conditionStack)
void DoSetUp(XmlReader reader, string endElement)
{
Stack<ICondition> conditionStack = new Stack<ICondition>();
List<Codon> innerCodons = new List<Codon>();
while (reader.Read()) {
switch (reader.NodeType) {
@ -86,7 +86,7 @@ namespace ICSharpCode.Core @@ -86,7 +86,7 @@ namespace ICSharpCode.Core
innerCodons.Add(newCodon);
if (!reader.IsEmptyElement) {
ExtensionPath subPath = this.AddIn.GetExtensionPath(this.Name + "/" + newCodon.Id);
subPath.DoSetUp(reader, elementName, conditionStack);
subPath.DoSetUp(reader, elementName);
}
}
break;

11
src/Main/Core/Project/Src/AddInTree/AddIn/IDoozer.cs

@ -21,10 +21,11 @@ namespace ICSharpCode.Core @@ -21,10 +21,11 @@ namespace ICSharpCode.Core
/// <summary>
/// Construct the item.
/// </summary>
/// <param name="caller">The caller passed to <see cref="AddInTree.BuildItem"/>.</param>
/// <param name="codon">The codon to build.</param>
/// <param name="subItems">The list of objects created by (other) doozers for the sub items.</param>
/// <returns>The constructed item.</returns>
object BuildItem(object caller, Codon codon, ArrayList subItems);
/// <returns>
/// The constructed item.
/// May return an object implementing <see cref="IBuildItemsModifier"/> for returning
/// multiple arguments.
/// </returns>
object BuildItem(BuildItemArgs args);
}
}

63
src/Main/Core/Project/Src/AddInTree/AddInTree.cs

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Resources;
@ -17,21 +18,21 @@ namespace ICSharpCode.Core @@ -17,21 +18,21 @@ namespace ICSharpCode.Core
static List<AddIn> addIns = new List<AddIn>();
static AddInTreeNode rootNode = new AddInTreeNode();
static Dictionary<string, IDoozer> doozers = new Dictionary<string, IDoozer>();
static Dictionary<string, IConditionEvaluator> conditionEvaluators = new Dictionary<string, IConditionEvaluator>();
static ConcurrentDictionary<string, IDoozer> doozers = new ConcurrentDictionary<string, IDoozer>();
static ConcurrentDictionary<string, IConditionEvaluator> conditionEvaluators = new ConcurrentDictionary<string, IConditionEvaluator>();
static AddInTree()
{
doozers.Add("Class", new ClassDoozer());
doozers.Add("FileFilter", new FileFilterDoozer());
doozers.Add("String", new StringDoozer());
doozers.Add("Icon", new IconDoozer());
doozers.Add("MenuItem", new MenuItemDoozer());
doozers.Add("ToolbarItem", new ToolbarItemDoozer());
doozers.Add("Include", new IncludeDoozer());
doozers.TryAdd("Class", new ClassDoozer());
doozers.TryAdd("FileFilter", new FileFilterDoozer());
doozers.TryAdd("String", new StringDoozer());
doozers.TryAdd("Icon", new IconDoozer());
doozers.TryAdd("MenuItem", new MenuItemDoozer());
doozers.TryAdd("ToolbarItem", new ToolbarItemDoozer());
doozers.TryAdd("Include", new IncludeDoozer());
conditionEvaluators.Add("Compare", new CompareConditionEvaluator());
conditionEvaluators.Add("Ownerstate", new OwnerStateConditionEvaluator());
conditionEvaluators.TryAdd("Compare", new CompareConditionEvaluator());
conditionEvaluators.TryAdd("Ownerstate", new OwnerStateConditionEvaluator());
ApplicationStateInfoService.RegisterStateGetter("Installed 3rd party AddIns", GetInstalledThirdPartyAddInsListAsString);
}
@ -76,7 +77,7 @@ namespace ICSharpCode.Core @@ -76,7 +77,7 @@ namespace ICSharpCode.Core
/// <summary>
/// Gets a dictionary of registered doozers.
/// </summary>
public static Dictionary<string, IDoozer> Doozers {
public static ConcurrentDictionary<string, IDoozer> Doozers {
get {
return doozers;
}
@ -85,7 +86,7 @@ namespace ICSharpCode.Core @@ -85,7 +86,7 @@ namespace ICSharpCode.Core
/// <summary>
/// Gets a dictionary of registered condition evaluators.
/// </summary>
public static Dictionary<string, IConditionEvaluator> ConditionEvaluators {
public static ConcurrentDictionary<string, IConditionEvaluator> ConditionEvaluators {
get {
return conditionEvaluators;
}
@ -96,21 +97,7 @@ namespace ICSharpCode.Core @@ -96,21 +97,7 @@ namespace ICSharpCode.Core
/// </summary>
public static bool ExistsTreeNode(string path)
{
if (path == null || path.Length == 0) {
return true;
}
string[] splittedPath = path.Split('/');
AddInTreeNode curPath = rootNode;
int i = 0;
while (i < splittedPath.Length) {
// curPath = curPath.ChildNodes[splittedPath[i]] - check if child path exists
if (!curPath.ChildNodes.TryGetValue(splittedPath[i], out curPath)) {
return false;
}
++i;
}
return true;
return GetTreeNode(path, false) != null;
}
/// <summary>
@ -139,16 +126,13 @@ namespace ICSharpCode.Core @@ -139,16 +126,13 @@ namespace ICSharpCode.Core
}
string[] splittedPath = path.Split('/');
AddInTreeNode curPath = rootNode;
int i = 0;
while (i < splittedPath.Length) {
for (int i = 0; i < splittedPath.Length; i++) {
if (!curPath.ChildNodes.TryGetValue(splittedPath[i], out curPath)) {
if (throwOnNotFound)
throw new TreePathNotFoundException(path);
else
return null;
}
// curPath = curPath.ChildNodes[splittedPath[i]]; already done by TryGetValue
++i;
}
return curPath;
}
@ -161,12 +145,17 @@ namespace ICSharpCode.Core @@ -161,12 +145,17 @@ namespace ICSharpCode.Core
/// <exception cref="TreePathNotFoundException">The path does not
/// exist or does not point to an item.</exception>
public static object BuildItem(string path, object caller)
{
return BuildItem(path, caller, null);
}
public static object BuildItem(string path, object caller, IEnumerable<ICondition> additionalConditions)
{
int pos = path.LastIndexOf('/');
string parent = path.Substring(0, pos);
string child = path.Substring(pos + 1);
AddInTreeNode node = GetTreeNode(parent);
return node.BuildChildItem(child, caller, new ArrayList(BuildItems<object>(path, caller, false)));
return node.BuildChildItem(child, caller, additionalConditions);
}
/// <summary>
@ -239,16 +228,12 @@ namespace ICSharpCode.Core @@ -239,16 +228,12 @@ namespace ICSharpCode.Core
foreach (Runtime runtime in addIn.Runtimes) {
if (runtime.IsActive) {
foreach (LazyLoadDoozer doozer in runtime.DefinedDoozers) {
if (AddInTree.Doozers.ContainsKey(doozer.Name)) {
if (!doozers.TryAdd(doozer.Name, doozer))
throw new AddInLoadException("Duplicate doozer: " + doozer.Name);
}
AddInTree.Doozers.Add(doozer.Name, doozer);
}
foreach (LazyConditionEvaluator condition in runtime.DefinedConditionEvaluators) {
if (AddInTree.ConditionEvaluators.ContainsKey(condition.Name)) {
if (!conditionEvaluators.TryAdd(condition.Name, condition))
throw new AddInLoadException("Duplicate condition evaluator: " + condition.Name);
}
AddInTree.ConditionEvaluators.Add(condition.Name, condition);
}
}
}

74
src/Main/Core/Project/Src/AddInTree/AddInTreeNode.cs

@ -5,6 +5,7 @@ using System; @@ -5,6 +5,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace ICSharpCode.Core
{
@ -60,39 +61,17 @@ namespace ICSharpCode.Core @@ -60,39 +61,17 @@ namespace ICSharpCode.Core
}
}
//
// public void BinarySerialize(BinaryWriter writer)
// {
// if (!isSorted) {
// (new SortCodons(this)).Execute();
// isSorted = true;
// }
// writer.Write((ushort)codons.Count);
// foreach (Codon codon in codons) {
// codon.BinarySerialize(writer);
// }
//
// writer.Write((ushort)childNodes.Count);
// foreach (KeyValuePair<string, AddInTreeNode> child in childNodes) {
// writer.Write(AddInTree.GetNameOffset(child.Key));
// child.Value.BinarySerialize(writer);
// }
// }
/// <summary>
/// Builds the child items in this path. Ensures that all items have the type T.
/// </summary>
/// <param name="caller">The owner used to create the objects.</param>
public List<T> BuildChildItems<T>(object caller)
/// <param name="additionalConditions">Additional conditions applied to the node.</param>
public List<T> BuildChildItems<T>(object caller, IEnumerable<ICondition> additionalConditions = null)
{
var codons = this.Codons;
List<T> items = new List<T>(codons.Count);
foreach (Codon codon in codons) {
ArrayList subItems = null;
if (childNodes.ContainsKey(codon.Id)) {
subItems = childNodes[codon.Id].BuildChildItems(caller);
}
object result = codon.BuildItem(caller, subItems);
object result = BuildChildItem(codon, caller, additionalConditions);
if (result == null)
continue;
IBuildItemsModifier mod = result as IBuildItemsModifier;
@ -109,30 +88,33 @@ namespace ICSharpCode.Core @@ -109,30 +88,33 @@ namespace ICSharpCode.Core
return items;
}
public object BuildChildItem(Codon codon, object caller, IEnumerable<ICondition> additionalConditions = null)
{
if (codon == null)
throw new ArgumentNullException("codon");
AddInTreeNode subItemNode;
childNodes.TryGetValue(codon.Id, out subItemNode);
IEnumerable<ICondition> conditions;
if (additionalConditions == null)
conditions = codon.Conditions;
else if (codon.Conditions.Length == 0)
conditions = additionalConditions;
else
conditions = additionalConditions.Concat(codon.Conditions);
return codon.BuildItem(new BuildItemArgs(caller, codon, conditions, subItemNode));
}
/// <summary>
/// Builds the child items in this path.
/// </summary>
/// <param name="caller">The owner used to create the objects.</param>
[Obsolete("Use the generic BuildChildItems version instead")]
public ArrayList BuildChildItems(object caller)
{
var codons = this.Codons;
ArrayList items = new ArrayList(codons.Count);
foreach (Codon codon in codons) {
ArrayList subItems = null;
if (childNodes.ContainsKey(codon.Id)) {
subItems = childNodes[codon.Id].BuildChildItems(caller);
}
object result = codon.BuildItem(caller, subItems);
if (result == null)
continue;
IBuildItemsModifier mod = result as IBuildItemsModifier;
if (mod != null) {
mod.Apply(items);
} else {
items.Add(result);
}
}
return items;
return new ArrayList(this.BuildChildItems<object>(caller));
}
/// <summary>
@ -142,15 +124,15 @@ namespace ICSharpCode.Core @@ -142,15 +124,15 @@ namespace ICSharpCode.Core
/// The ID of the child item to build.
/// </param>
/// <param name="caller">The owner used to create the objects.</param>
/// <param name="subItems">The subitems to pass to the doozer</param>
/// <param name="additionalConditions">Additional conditions applied to the created object</param>
/// <exception cref="TreePathNotFoundException">
/// Occurs when <paramref name="childItemID"/> does not exist in this path.
/// </exception>
public object BuildChildItem(string childItemID, object caller, ArrayList subItems)
public object BuildChildItem(string childItemID, object caller, IEnumerable<ICondition> additionalConditions = null)
{
foreach (Codon codon in this.Codons) {
if (codon.Id == childItemID) {
return codon.BuildItem(caller, subItems);
return BuildChildItem(codon, caller, additionalConditions);
}
}
throw new TreePathNotFoundException(childItemID);

3
src/Main/Core/Test/AddInTreeTests/AddInTreeLoadingTests.cs

@ -193,7 +193,8 @@ namespace ICSharpCode.Core.Tests.AddInTreeTests.Tests @@ -193,7 +193,8 @@ namespace ICSharpCode.Core.Tests.AddInTreeTests.Tests
Assert.AreEqual(1, codons2.Count);
Assert.AreEqual("Codon2", codons2[0].Name);
Assert.AreEqual("Sub2", codons2[0].Id);
Assert.AreEqual(1, codons2[0].Conditions.Length); // condition is inherited into sub-codon
// condition is not inherited lexically
Assert.AreEqual(0, codons2[0].Conditions.Length);
}
[Test]

Loading…
Cancel
Save