Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-addins.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLluis Sanchez <llsan@microsoft.com>2022-06-15 11:18:40 +0300
committerLluis Sanchez <llsan@microsoft.com>2022-09-13 20:38:42 +0300
commit6d80ced6405cbc3e307cc9e484ced46b7bbdf24d (patch)
tree3e1ec43b518aaee780c151f244f3a3c8d1f07eca
parent831a6714d10976c4f5845efd06c9333dbf4c18d1 (diff)
Fix unit tests
-rw-r--r--Mono.Addins/Mono.Addins.Database/AddinDatabase.cs92
-rw-r--r--Mono.Addins/Mono.Addins/ExtensionContext.cs2
-rw-r--r--Mono.Addins/Mono.Addins/ExtensionNode.cs2
-rw-r--r--Mono.Addins/Mono.Addins/ExtensionTree.cs32
-rw-r--r--Mono.Addins/Mono.Addins/InstanceExtensionNode.cs2
-rw-r--r--Mono.Addins/Mono.Addins/RuntimeAddin.cs2
-rw-r--r--Mono.Addins/Mono.Addins/TreeNode.cs96
-rw-r--r--Mono.Addins/Mono.Addins/TreeNodeBuilder.cs108
-rw-r--r--Test/CommandExtension/CommandExtension.csproj2
-rw-r--r--Test/FileContentExtension/FileContentExtension.csproj2
-rw-r--r--Test/HelloWorldExtension/HelloWorldExtension.csproj2
-rw-r--r--Test/MultiAssemblyAddin/MultiAssemblyAddin.csproj2
-rw-r--r--Test/MultiAssemblyAddin/OptionalModule/OptionalModule.csproj2
-rw-r--r--Test/MultiAssemblyAddin/SecondAssembly/SecondAssembly.csproj2
-rw-r--r--Test/SystemInfoExtension/SystemInfoExtension.csproj2
-rw-r--r--Test/UnitTests/UnitTests.csproj1
-rw-r--r--Test/UnitTests/Util.cs2
-rw-r--r--Test/UnitTests/test.addins4
18 files changed, 208 insertions, 149 deletions
diff --git a/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs b/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs
index 4029185..938ad8a 100644
--- a/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs
+++ b/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs
@@ -195,61 +195,30 @@ namespace Mono.Addins.Database
// Get the cached list if the add-in list has already been loaded.
// The domain doesn't have to be checked again, since it is always the same
- IEnumerable<Addin> result = null;
-
- if ((flags & AddinSearchFlagsInternal.IncludeAll) == AddinSearchFlagsInternal.IncludeAll) {
- if (allSetupInfos != null)
- result = allSetupInfos;
- }
- else if ((flags & AddinSearchFlagsInternal.IncludeAddins) == AddinSearchFlagsInternal.IncludeAddins) {
- if (addinSetupInfos != null)
- result = addinSetupInfos;
- }
- else {
- if (rootSetupInfos != null)
- result = rootSetupInfos;
- }
-
- if (result == null) {
- InternalCheck (domain);
- using (fileDatabase.LockRead ()) {
- result = InternalGetInstalledAddins (domain, null, flags & ~AddinSearchFlagsInternal.LatestVersionsOnly);
- }
- }
-
- if ((flags & AddinSearchFlagsInternal.LatestVersionsOnly) == AddinSearchFlagsInternal.LatestVersionsOnly)
- result = result.Where (a => a.IsLatestVersion);
-
- if ((flags & AddinSearchFlagsInternal.ExcludePendingUninstall) == AddinSearchFlagsInternal.ExcludePendingUninstall)
- result = result.Where (a => !IsRegisteredForUninstall (a.Description.Domain, a.Id));
-
- return result;
+ return InternalGetInstalledAddins (domain, null, flags & ~AddinSearchFlagsInternal.LatestVersionsOnly, false);
}
- IEnumerable<Addin> InternalGetInstalledAddins (string domain, AddinSearchFlagsInternal type)
+ IEnumerable<Addin> InternalGetInstalledAddins (string domain, AddinSearchFlagsInternal type, bool dbIsLockedForRead)
{
- return InternalGetInstalledAddins (domain, null, type);
+ return InternalGetInstalledAddins (domain, null, type, dbIsLockedForRead);
}
- IEnumerable<Addin> InternalGetInstalledAddins (string domain, string idFilter, AddinSearchFlagsInternal type)
+ IEnumerable<Addin> InternalGetInstalledAddins (string domain, string idFilter, AddinSearchFlagsInternal type, bool dbIsLockedForRead)
{
- if ((type & AddinSearchFlagsInternal.LatestVersionsOnly) != 0)
- throw new InvalidOperationException ("LatestVersionsOnly flag not supported here");
-
if (!allSetupInfosLoaded) {
lock (localLock) {
if (!allSetupInfosLoaded) {
Dictionary<string, Addin> adict = new Dictionary<string, Addin> ();
- // Global add-ins are valid for any private domain
- if (domain != AddinDatabase.GlobalDomain)
- FindInstalledAddins (adict, AddinDatabase.GlobalDomain, idFilter);
+ using (!dbIsLockedForRead ? fileDatabase.LockRead() : null) {
+ // Global add-ins are valid for any private domain
+ if (domain != AddinDatabase.GlobalDomain)
+ FindInstalledAddins (adict, AddinDatabase.GlobalDomain);
- FindInstalledAddins (adict, domain, idFilter);
+ FindInstalledAddins (adict, domain);
+ }
List<Addin> alist = new List<Addin> (adict.Values);
UpdateLastVersionFlags (alist);
- if (idFilter != null)
- return alist;
allSetupInfos = alist.ToImmutableArray ();
addinSetupInfos = alist.Where (addin => !addin.Description.IsRoot).ToImmutableArray ();
rootSetupInfos = alist.Where (addin => addin.Description.IsRoot).ToImmutableArray ();
@@ -257,17 +226,26 @@ namespace Mono.Addins.Database
}
}
}
- if ((type & AddinSearchFlagsInternal.IncludeAll) == AddinSearchFlagsInternal.IncludeAll)
- return FilterById (allSetupInfos, idFilter);
-
- if ((type & AddinSearchFlagsInternal.IncludeAddins) == AddinSearchFlagsInternal.IncludeAddins) {
- return FilterById (addinSetupInfos, idFilter);
- }
- else {
- return FilterById (rootSetupInfos, idFilter);
+ IEnumerable<Addin> result;
+
+ if ((type & AddinSearchFlagsInternal.IncludeAll) == AddinSearchFlagsInternal.IncludeAll) {
+ result = allSetupInfos;
+ } else if ((type & AddinSearchFlagsInternal.IncludeAddins) == AddinSearchFlagsInternal.IncludeAddins) {
+ result = addinSetupInfos;
+ } else {
+ result = rootSetupInfos;
}
+
+ result = FilterById (result, idFilter);
+
+ if ((type & AddinSearchFlagsInternal.LatestVersionsOnly) == AddinSearchFlagsInternal.LatestVersionsOnly)
+ result = result.Where (a => a.IsLatestVersion);
+
+ if ((type & AddinSearchFlagsInternal.ExcludePendingUninstall) == AddinSearchFlagsInternal.ExcludePendingUninstall)
+ result = result.Where (a => !IsRegisteredForUninstall (a.Description.Domain, a.Id));
+ return result;
}
-
+
IEnumerable<Addin> FilterById (IEnumerable<Addin> addins, string id)
{
if (id == null)
@@ -275,13 +253,11 @@ namespace Mono.Addins.Database
return addins.Where (a => Addin.GetIdName (a.Id) == id);
}
- void FindInstalledAddins (Dictionary<string,Addin> result, string domain, string idFilter)
+ void FindInstalledAddins (Dictionary<string,Addin> result, string domain)
{
- if (idFilter == null)
- idFilter = "*";
string dir = Path.Combine (AddinCachePath, domain);
if (Directory.Exists (dir)) {
- foreach (string file in fileDatabase.GetDirectoryFiles (dir, idFilter + ",*.maddin")) {
+ foreach (string file in fileDatabase.GetDirectoryFiles (dir, "*,*.maddin")) {
string id = Path.GetFileNameWithoutExtension (file);
if (!result.ContainsKey (id)) {
var adesc = GetInstalledDomainAddin (domain, id, true, false, false);
@@ -398,7 +374,7 @@ namespace Mono.Addins.Database
string bestVersion = null;
Addin.GetIdParts (id, out name, out version);
- foreach (Addin ia in InternalGetInstalledAddins (domain, name, AddinSearchFlagsInternal.IncludeAll))
+ foreach (Addin ia in InternalGetInstalledAddins (domain, name, AddinSearchFlagsInternal.IncludeAll, true))
{
if ((!enabledOnly || ia.Enabled) &&
(version.Length == 0 || ia.SupportsVersion (version)) &&
@@ -1149,10 +1125,8 @@ namespace Mono.Addins.Database
// to be done in an external process
if (domain != null) {
- using (fileDatabase.LockRead ()) {
- foreach (Addin ainfo in InternalGetInstalledAddins (domain, AddinSearchFlagsInternal.IncludeAddins)) {
- installed [ainfo.Id] = ainfo.Id;
- }
+ foreach (Addin ainfo in InternalGetInstalledAddins (domain, AddinSearchFlagsInternal.IncludeAddins, false)) {
+ installed [ainfo.Id] = ainfo.Id;
}
}
diff --git a/Mono.Addins/Mono.Addins/ExtensionContext.cs b/Mono.Addins/Mono.Addins/ExtensionContext.cs
index 980a27f..00db5d1 100644
--- a/Mono.Addins/Mono.Addins/ExtensionContext.cs
+++ b/Mono.Addins/Mono.Addins/ExtensionContext.cs
@@ -939,7 +939,7 @@ namespace Mono.Addins
TreeNode node = GetNode (ext.Path);
if (node != null && node.ExtensionNodeSet != null) {
if (node.ChildrenLoaded) {
- var builder = new TreeNodeBuilder (node);
+ var builder = TreeNodeBuilder.FromNode (node);
LoadModuleExtensionNodes (transaction, builder, ext, data.AddinId);
builder.Build (transaction);
}
diff --git a/Mono.Addins/Mono.Addins/ExtensionNode.cs b/Mono.Addins/Mono.Addins/ExtensionNode.cs
index dc490bc..404881e 100644
--- a/Mono.Addins/Mono.Addins/ExtensionNode.cs
+++ b/Mono.Addins/Mono.Addins/ExtensionNode.cs
@@ -131,7 +131,7 @@ namespace Mono.Addins
internal void SetData (AddinEngine addinEngine, string plugid, ExtensionNodeType nodeType, ModuleDescription module)
{
// SetData can only be called once (it's set during the node initialization)
- if (addinEngine != null)
+ if (this.addinEngine != null)
throw new InvalidOperationException ();
this.addinEngine = addinEngine;
diff --git a/Mono.Addins/Mono.Addins/ExtensionTree.cs b/Mono.Addins/Mono.Addins/ExtensionTree.cs
index b8da472..a3af268 100644
--- a/Mono.Addins/Mono.Addins/ExtensionTree.cs
+++ b/Mono.Addins/Mono.Addins/ExtensionTree.cs
@@ -64,7 +64,7 @@ namespace Mono.Addins
LoadExtensionElement (transaction, tnode, addin, extension.ExtensionNodes, (ModuleDescription) extension.Parent, ref curPos, tnode.Condition, false, addedNodes);
}
- void LoadExtensionElement (ExtensionContextTransaction transaction, TreeNodeBuilder tnode, string addin, ExtensionNodeDescriptionCollection extension, ModuleDescription module, ref int curPos, BaseCondition parentCondition, bool inComplextCondition, List<TreeNode> addedNodes)
+ void LoadExtensionElement (ExtensionContextTransaction transaction, TreeNodeBuilder parentNode, string addin, ExtensionNodeDescriptionCollection extension, ModuleDescription module, ref int curPos, BaseCondition parentCondition, bool inComplextCondition, List<TreeNode> addedNodes)
{
foreach (ExtensionNodeDescription elem in extension) {
@@ -75,23 +75,23 @@ namespace Mono.Addins
}
if (elem.NodeName == "ComplexCondition") {
- LoadExtensionElement (transaction, tnode, addin, elem.ChildNodes, module, ref curPos, parentCondition, true, addedNodes);
+ LoadExtensionElement (transaction, parentNode, addin, elem.ChildNodes, module, ref curPos, parentCondition, true, addedNodes);
continue;
}
if (elem.NodeName == "Condition") {
Condition cond = new Condition (AddinEngine, elem, parentCondition);
- LoadExtensionElement (transaction, tnode, addin, elem.ChildNodes, module, ref curPos, cond, false, addedNodes);
+ LoadExtensionElement (transaction, parentNode, addin, elem.ChildNodes, module, ref curPos, cond, false, addedNodes);
continue;
}
- ExtensionPoint extensionPoint = tnode.GetExtensionPoint ();
+ ExtensionPoint extensionPoint = parentNode.GetExtensionPoint ();
string after = elem.GetAttribute ("insertafter");
if (after.Length == 0 && extensionPoint != null && curPos == -1)
after = extensionPoint.DefaultInsertAfter;
if (after.Length > 0) {
- int i = tnode.IndexOfChild (after);
+ int i = parentNode.IndexOfChild (after);
if (i != -1)
curPos = i+1;
}
@@ -99,20 +99,20 @@ namespace Mono.Addins
if (before.Length == 0 && extensionPoint != null && curPos == -1)
before = extensionPoint.DefaultInsertBefore;
if (before.Length > 0) {
- int i = tnode.IndexOfChild (before);
+ int i = parentNode.IndexOfChild (before);
if (i != -1)
curPos = i;
}
// If node position is not explicitly set, add the node at the end
if (curPos == -1)
- curPos = tnode.Children.Count;
+ curPos = parentNode.ChildrenCount;
// Find the type of the node in this extension
- ExtensionNodeType ntype = addinEngine.FindType (tnode.ExtensionNodeSet, elem.NodeName, addin);
+ ExtensionNodeType ntype = addinEngine.FindType (parentNode.ExtensionNodeSet, elem.NodeName, addin);
if (ntype == null) {
- addinEngine.ReportError ("Node '" + elem.NodeName + "' not allowed in extension: " + tnode.GetPath (), addin, null, false);
+ addinEngine.ReportError ("Node '" + elem.NodeName + "' not allowed in extension: " + parentNode.GetPath (), addin, null, false);
continue;
}
@@ -120,20 +120,20 @@ namespace Mono.Addins
if (id.Length == 0)
id = AutoIdPrefix + (++internalId);
- TreeNodeBuilder cnode = new TreeNodeBuilder (addinEngine, id);
+ TreeNodeBuilder childNode = TreeNodeBuilder.CreateNew (addinEngine, id, parentNode);
- ExtensionNode enode = ReadNode (cnode, addin, ntype, elem, module);
+ ExtensionNode enode = ReadNode (childNode, addin, ntype, elem, module);
if (enode == null)
continue;
- cnode.Condition = parentCondition;
- cnode.ExtensionNodeSet = ntype;
- tnode.InsertChild (curPos, cnode);
-
+ childNode.Condition = parentCondition;
+ childNode.ExtensionNodeSet = ntype;
+ parentNode.InsertChild (curPos, childNode);
+
// Load children
if (elem.ChildNodes.Count > 0) {
int cp = 0;
- LoadExtensionElement (transaction, cnode, addin, elem.ChildNodes, module, ref cp, parentCondition, false, addedNodes);
+ LoadExtensionElement (transaction, childNode, addin, elem.ChildNodes, module, ref cp, parentCondition, false, addedNodes);
}
curPos++;
diff --git a/Mono.Addins/Mono.Addins/InstanceExtensionNode.cs b/Mono.Addins/Mono.Addins/InstanceExtensionNode.cs
index e49632e..37e2791 100644
--- a/Mono.Addins/Mono.Addins/InstanceExtensionNode.cs
+++ b/Mono.Addins/Mono.Addins/InstanceExtensionNode.cs
@@ -72,7 +72,7 @@ namespace Mono.Addins
if (cachedInstance == null) {
lock (localLock) {
// Use locking here to avoid creating more than one instance per ExtensionNode
- if (cachedInstance != null)
+ if (cachedInstance == null)
cachedInstance = CreateInstance ();
}
}
diff --git a/Mono.Addins/Mono.Addins/RuntimeAddin.cs b/Mono.Addins/Mono.Addins/RuntimeAddin.cs
index d5a03ac..a23c9b8 100644
--- a/Mono.Addins/Mono.Addins/RuntimeAddin.cs
+++ b/Mono.Addins/Mono.Addins/RuntimeAddin.cs
@@ -355,7 +355,7 @@ namespace Mono.Addins
foreach (var kvp in loadedAssemblies) {
var assembly = kvp.Value;
- if (string.IsNullOrEmpty (assemblyName) || assembly.FullName == assemblyName) {
+ if (string.IsNullOrEmpty (assemblyName) || assembly.GetName().Name == assemblyName) {
Type type = assembly.GetType (typeName, false);
if (type != null)
return type;
diff --git a/Mono.Addins/Mono.Addins/TreeNode.cs b/Mono.Addins/Mono.Addins/TreeNode.cs
index 8cccdab..34d475b 100644
--- a/Mono.Addins/Mono.Addins/TreeNode.cs
+++ b/Mono.Addins/Mono.Addins/TreeNode.cs
@@ -37,7 +37,7 @@ using System.Linq;
namespace Mono.Addins
{
- class TreeNode
+ class TreeNode
{
ImmutableArray<TreeNode> children;
ExtensionNode extensionNode;
@@ -49,10 +49,11 @@ namespace Mono.Addins
BaseCondition condition;
protected readonly AddinEngine addinEngine;
- public TreeNode (AddinEngine addinEngine, string id)
+ public TreeNode (AddinEngine addinEngine, string id, TreeNode parent = null)
{
this.id = id;
this.addinEngine = addinEngine;
+ this.parent = parent;
children = ImmutableArray<TreeNode>.Empty;
@@ -60,22 +61,22 @@ namespace Mono.Addins
if (id.Length == 0)
childrenLoaded = true;
}
-
+
public AddinEngine AddinEngine {
get { return addinEngine; }
}
-
+
internal void AttachExtensionNode (ExtensionNode enode)
{
this.extensionNode = enode;
if (extensionNode != null)
extensionNode.SetTreeNode (this);
}
-
+
public string Id {
get { return id; }
}
-
+
public ExtensionNode ExtensionNode {
get {
if (extensionNode == null && extensionPoint != null) {
@@ -113,23 +114,23 @@ namespace Mono.Addins
get { return extensionPoint; }
set { extensionPoint = value; }
}
-
+
public ExtensionNodeSet ExtensionNodeSet {
get { return nodeTypes; }
set { nodeTypes = value; }
}
-
+
public TreeNode Parent {
get { return parent; }
}
-
+
public BaseCondition Condition {
get { return condition; }
set {
condition = value;
}
}
-
+
public virtual ExtensionContext Context {
get {
if (parent != null)
@@ -138,7 +139,7 @@ namespace Mono.Addins
return null;
}
}
-
+
public bool IsEnabled {
get {
if (condition == null)
@@ -150,22 +151,29 @@ namespace Mono.Addins
return condition.Evaluate (ctx);
}
}
-
+
public bool ChildrenLoaded {
get { return childrenLoaded; }
}
-
+
public void AddChildNode (ExtensionContextTransaction transaction, TreeNode node)
{
node.parent = this;
children = children.Add (node);
transaction.ReportChildrenChanged (this);
}
-
+
internal void SetChildren (ExtensionContextTransaction transaction, ImmutableArray<TreeNode> children)
{
+ foreach (var node in children) {
+ node.parent = this;
+ if (node == this)
+ throw new InvalidOperationException ();
+ }
+
this.children = children;
+
if (childrenLoaded) {
// If children were already loaded, we need to notify that they have changed
transaction.ReportChildrenChanged (this);
@@ -181,13 +189,13 @@ namespace Mono.Addins
TreeNode node = GetNode (path, childId);
return node != null ? node.ExtensionNode : null;
}
-
+
public ExtensionNode GetExtensionNode (string path)
{
TreeNode node = GetNode (path);
return node != null ? node.ExtensionNode : null;
}
-
+
public TreeNode GetNode (string path, string childId)
{
if (childId == null || childId.Length == 0)
@@ -195,28 +203,28 @@ namespace Mono.Addins
else
return GetNode (path + "/" + childId);
}
-
+
public TreeNode GetNode (string path)
{
return GetNode (path, false);
}
-
+
public TreeNode GetNode (string path, bool buildPath)
{
if (path.StartsWith ("/"))
path = path.Substring (1);
- string[] parts = path.Split ('/');
+ string [] parts = path.Split ('/');
TreeNode curNode = this;
- for(int n=0; n<parts.Length; n++) {
+ for (int n = 0; n < parts.Length; n++) {
var part = parts [n];
var node = curNode.GetChildNode (part);
if (node != null) {
curNode = node;
continue;
}
-
+
if (buildPath) {
// A new branch has to be created. Begin a transaction
using var transaction = Context.BeginTransaction ();
@@ -224,36 +232,42 @@ namespace Mono.Addins
// Don't rise events since we are just building the tree, not modifying it
transaction.DisableEvents = true;
+ // Check again inside the lock, just in case
+ node = curNode.GetChildNode (part);
+ if (node != null) {
+ curNode = node;
+ continue;
+ }
+
// Build the branch
- var nodeBuilder = new TreeNodeBuilder(addinEngine, part);
- BuildNodePath (nodeBuilder, parts, n);
+ var parentNode = TreeNodeBuilder.FromNode (curNode);
+ BuildNodeBranch (parentNode, parts, n);
- // Add the new node
- var newNode = nodeBuilder.Build (transaction);
- curNode.AddChildNode (transaction, newNode);
+ // Commit the changes
+ parentNode.Build (transaction);
// Keep iterating to find the leaf
- curNode = newNode;
+ curNode = curNode.GetChildNode (part);
} else
return null;
}
return curNode;
}
- void BuildNodePath (TreeNodeBuilder nodeBuilder, string[] parts, int partIndex)
+ void BuildNodeBranch (TreeNodeBuilder parent, string [] parts, int partIndex)
{
- for (int n=partIndex; n<parts.Length; n++) {
+ for (int n = partIndex; n < parts.Length; n++) {
var id = parts [n];
- var newNode = new TreeNodeBuilder (addinEngine, id);
- nodeBuilder.AddChild (newNode);
- nodeBuilder = newNode;
+ var newNode = TreeNodeBuilder.CreateNew (addinEngine, id, parent);
+ parent.AddChild (newNode);
+ parent = newNode;
}
}
public TreeNode GetChildNode (string id)
{
var childrenList = Children;
- foreach (var node in Children) {
+ foreach (var node in childrenList) {
if (node.Id == id)
return node;
}
@@ -268,7 +282,7 @@ namespace Mono.Addins
// Check again after taking the lock
if (!childrenLoaded) {
if (extensionPoint != null) {
- var builder = new TreeNodeBuilder (this);
+ var builder = TreeNodeBuilder.FromNode (this);
Context.LoadExtensions (transaction, extensionPoint, builder);
builder.Build (transaction);
}
@@ -281,6 +295,17 @@ namespace Mono.Addins
}
}
+ internal void LoadChildrenIntoBuilder (TreeNodeBuilder builder)
+ {
+ if (childrenLoaded) {
+ foreach (var child in children)
+ builder.AddChild (TreeNodeBuilder.FromNode (child));
+ } else if (extensionPoint != null) {
+ using var transaction = Context.BeginTransaction ();
+ Context.LoadExtensions (transaction, extensionPoint, builder);
+ }
+ }
+
public TreeNode Clone (AddinEngine engine)
{
return Clone (engine, extensionPoint != null);
@@ -428,7 +453,8 @@ namespace Mono.Addins
public void ResetCachedData (ExtensionContextTransaction transaction)
{
- if (extensionPoint != null) {
+ // Check IsInitialized since ResetCachedData is called while shutting down
+ if (extensionPoint != null && addinEngine.IsInitialized) {
string aid = Addin.GetIdName (extensionPoint.ParentAddinDescription.AddinId);
RuntimeAddin ad = addinEngine.GetAddin (aid);
if (ad != null)
diff --git a/Mono.Addins/Mono.Addins/TreeNodeBuilder.cs b/Mono.Addins/Mono.Addins/TreeNodeBuilder.cs
index df72fa4..29cf2f4 100644
--- a/Mono.Addins/Mono.Addins/TreeNodeBuilder.cs
+++ b/Mono.Addins/Mono.Addins/TreeNodeBuilder.cs
@@ -43,18 +43,35 @@ namespace Mono.Addins
ExtensionNode extensionNode;
string path;
TreeNode existingNode;
+ TreeNode builtNode;
+ TreeNodeBuilder parentNode;
+ bool built;
- public TreeNodeBuilder (TreeNode existingNode)
+ private TreeNodeBuilder ()
{
- this.existingNode = existingNode;
+ }
+
+ private TreeNodeBuilder (TreeNode existingNode)
+ {
+ this.existingNode = builtNode = existingNode;
this.id = existingNode.Id;
+ ExtensionNodeSet = existingNode.ExtensionNodeSet;
}
- public TreeNodeBuilder (AddinEngine addinEngine, string id)
- {
- this.addinEngine = addinEngine;
- this.id = id;
- }
+ public static TreeNodeBuilder FromNode (TreeNode existingNode)
+ {
+ return new TreeNodeBuilder (existingNode);
+ }
+
+ public static TreeNodeBuilder CreateNew (AddinEngine addinEngine, string id, TreeNodeBuilder parentNode)
+ {
+ return new TreeNodeBuilder {
+ addinEngine = addinEngine,
+ id = id,
+ Parent = parentNode,
+ builtNode = new TreeNode (addinEngine, id, parentNode.builtNode)
+ };
+ }
public string Id => id;
@@ -67,33 +84,45 @@ namespace Mono.Addins
return null;
}
- public TreeNodeBuilder Parent { get; set; }
-
- public IReadOnlyList<TreeNodeBuilder> Children => children;
+ public TreeNodeBuilder Parent { get; private set; }
public BaseCondition Condition { get; set; }
- public ExtensionNodeType ExtensionNodeSet { get; set; }
- public ExtensionPoint ExtensionPoint { get; internal set; }
+ public ExtensionNodeSet ExtensionNodeSet { get; set; }
+
+ void LoadChildren ()
+ {
+ if (children == null) {
+ children = new List<TreeNodeBuilder> ();
+ builtNode.LoadChildrenIntoBuilder (this);
+ }
+ }
public void AddChild (TreeNodeBuilder childBuilder)
{
- childBuilder.Parent = this;
- if (children == null)
- children = new List<TreeNodeBuilder>();
+ LoadChildren ();
+
+ // The parent is specified in CreateNew
+ if (childBuilder.existingNode == null && childBuilder.Parent != this)
+ throw new InvalidOperationException ();
+
children.Add (childBuilder);
}
public void InsertChild (int curPos, TreeNodeBuilder childBuilder)
{
- childBuilder.Parent = this;
- if (children == null)
- children = new List<TreeNodeBuilder>();
+ LoadChildren ();
+
+ // The parent is specified in CreateNew
+ if (childBuilder.Parent != this)
+ throw new InvalidOperationException ();
+
children.Insert (curPos, childBuilder);
}
public int IndexOfChild (string id)
{
+ LoadChildren ();
for (int n = 0; n < children.Count; n++) {
if (children[n].Id == id)
return n;
@@ -101,27 +130,42 @@ namespace Mono.Addins
return -1;
}
+ public int ChildrenCount {
+ get {
+ LoadChildren ();
+ return children.Count;
+ }
+ }
+
public TreeNode Build (ExtensionContextTransaction transaction)
{
- var childNodes = ImmutableArray.CreateRange (children.Select (builder => builder.Build (transaction)));
+ if (built)
+ return builtNode;
+
+ built = true;
+
+ var childNodes = children != null ? ImmutableArray.CreateRange (children.Select (builder => builder.Build (transaction))) : ImmutableArray<TreeNode>.Empty;
+
if (existingNode != null) {
- existingNode.SetChildren (transaction, childNodes);
+ if (children != null)
+ existingNode.SetChildren (transaction, childNodes);
return existingNode;
} else {
- TreeNode cnode = new TreeNode (addinEngine, id);
if (Condition != null)
- cnode.Condition = Condition;
+ builtNode.Condition = Condition;
if (ExtensionNodeSet != null)
- cnode.ExtensionNodeSet = ExtensionNodeSet;
+ builtNode.ExtensionNodeSet = ExtensionNodeSet;
if (extensionNode != null)
- cnode.AttachExtensionNode (extensionNode);
- cnode.SetChildren (transaction, childNodes);
+ builtNode.AttachExtensionNode (extensionNode);
+
+ if (children != null)
+ builtNode.SetChildren (transaction, childNodes);
- if (cnode.Condition != null)
- transaction.RegisterNodeCondition (cnode, cnode.Condition);
+ if (builtNode.Condition != null)
+ transaction.RegisterNodeCondition (builtNode, builtNode.Condition);
- transaction.ReportLoadedNode (cnode);
- return cnode;
+ transaction.ReportLoadedNode (builtNode);
+ return builtNode;
}
}
@@ -163,13 +207,13 @@ namespace Mono.Addins
foreach (var part in parts) {
if (string.IsNullOrEmpty (part))
continue;
- int i = IndexOfChild (part);
+ int i = node.IndexOfChild (part);
if (i == -1) {
- var child = new TreeNodeBuilder (addinEngine, part);
+ var child = TreeNodeBuilder.CreateNew (addinEngine, part, node);
node.AddChild (child);
node = child;
} else
- node = children [i];
+ node = node.children [i];
}
return node;
}
diff --git a/Test/CommandExtension/CommandExtension.csproj b/Test/CommandExtension/CommandExtension.csproj
index b05b551..bbfb9ef 100644
--- a/Test/CommandExtension/CommandExtension.csproj
+++ b/Test/CommandExtension/CommandExtension.csproj
@@ -11,6 +11,8 @@
<SchemaVersion>2.0</SchemaVersion>
<RootNamespace>CommandExtension</RootNamespace>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
+ <TargetFrameworks>$(DotNetCoreTarget)</TargetFrameworks>
+ <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
diff --git a/Test/FileContentExtension/FileContentExtension.csproj b/Test/FileContentExtension/FileContentExtension.csproj
index bd9e1a6..355eb9c 100644
--- a/Test/FileContentExtension/FileContentExtension.csproj
+++ b/Test/FileContentExtension/FileContentExtension.csproj
@@ -11,6 +11,8 @@
<SchemaVersion>2.0</SchemaVersion>
<RootNamespace>FileContentExtension</RootNamespace>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
+ <TargetFrameworks>$(DotNetCoreTarget)</TargetFrameworks>
+ <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
diff --git a/Test/HelloWorldExtension/HelloWorldExtension.csproj b/Test/HelloWorldExtension/HelloWorldExtension.csproj
index fa8173d..726fc88 100644
--- a/Test/HelloWorldExtension/HelloWorldExtension.csproj
+++ b/Test/HelloWorldExtension/HelloWorldExtension.csproj
@@ -11,6 +11,8 @@
<SchemaVersion>2.0</SchemaVersion>
<RootNamespace>HelloWorldExtension</RootNamespace>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
+ <TargetFrameworks>$(DotNetCoreTarget)</TargetFrameworks>
+ <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
diff --git a/Test/MultiAssemblyAddin/MultiAssemblyAddin.csproj b/Test/MultiAssemblyAddin/MultiAssemblyAddin.csproj
index ca110a9..ba75db4 100644
--- a/Test/MultiAssemblyAddin/MultiAssemblyAddin.csproj
+++ b/Test/MultiAssemblyAddin/MultiAssemblyAddin.csproj
@@ -11,6 +11,8 @@
<RootNamespace>MultiAssemblyAddin</RootNamespace>
<AssemblyName>MultiAssemblyAddin</AssemblyName>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
+ <TargetFrameworks>$(DotNetCoreTarget)</TargetFrameworks>
+ <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
diff --git a/Test/MultiAssemblyAddin/OptionalModule/OptionalModule.csproj b/Test/MultiAssemblyAddin/OptionalModule/OptionalModule.csproj
index 545018f..5ff431d 100644
--- a/Test/MultiAssemblyAddin/OptionalModule/OptionalModule.csproj
+++ b/Test/MultiAssemblyAddin/OptionalModule/OptionalModule.csproj
@@ -11,6 +11,8 @@
<RootNamespace>OptionalModule</RootNamespace>
<AssemblyName>OptionalModule</AssemblyName>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
+ <TargetFrameworks>$(DotNetCoreTarget)</TargetFrameworks>
+ <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
diff --git a/Test/MultiAssemblyAddin/SecondAssembly/SecondAssembly.csproj b/Test/MultiAssemblyAddin/SecondAssembly/SecondAssembly.csproj
index 31422ce..4c32a31 100644
--- a/Test/MultiAssemblyAddin/SecondAssembly/SecondAssembly.csproj
+++ b/Test/MultiAssemblyAddin/SecondAssembly/SecondAssembly.csproj
@@ -11,6 +11,8 @@
<RootNamespace>SecondAssembly</RootNamespace>
<AssemblyName>SecondAssembly</AssemblyName>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
+ <TargetFrameworks>$(DotNetCoreTarget)</TargetFrameworks>
+ <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
diff --git a/Test/SystemInfoExtension/SystemInfoExtension.csproj b/Test/SystemInfoExtension/SystemInfoExtension.csproj
index b5c47f3..9231588 100644
--- a/Test/SystemInfoExtension/SystemInfoExtension.csproj
+++ b/Test/SystemInfoExtension/SystemInfoExtension.csproj
@@ -11,6 +11,8 @@
<SchemaVersion>2.0</SchemaVersion>
<RootNamespace>SystemInfoExtension</RootNamespace>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
+ <TargetFrameworks>$(DotNetCoreTarget)</TargetFrameworks>
+ <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
diff --git a/Test/UnitTests/UnitTests.csproj b/Test/UnitTests/UnitTests.csproj
index f9ff798..28d5659 100644
--- a/Test/UnitTests/UnitTests.csproj
+++ b/Test/UnitTests/UnitTests.csproj
@@ -12,6 +12,7 @@
<RootNamespace>UnitTests</RootNamespace>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\mono-addins.snk</AssemblyOriginatorKeyFile>
+ <TargetFrameworks>net472;net6.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
diff --git a/Test/UnitTests/Util.cs b/Test/UnitTests/Util.cs
index 9c4cecd..0187eaf 100644
--- a/Test/UnitTests/Util.cs
+++ b/Test/UnitTests/Util.cs
@@ -40,7 +40,7 @@ namespace UnitTests
public static string TestsRootDir {
get {
if (rootDir == null)
- rootDir = Path.GetFullPath (Path.Combine (Path.GetDirectoryName (typeof(Util).Assembly.Location), "..", "..", ".."));
+ rootDir = Path.GetFullPath (Path.Combine (Path.GetDirectoryName (typeof(Util).Assembly.Location), "..", "..", "..", ".."));
return rootDir;
}
}
diff --git a/Test/UnitTests/test.addins b/Test/UnitTests/test.addins
index ebd1db7..df2ae14 100644
--- a/Test/UnitTests/test.addins
+++ b/Test/UnitTests/test.addins
@@ -1,5 +1,5 @@
<Addins>
- <Directory>../../../lib</Directory>
- <Directory>../../../lib/extras</Directory>
+ <Directory>../../../../lib</Directory>
+ <Directory>../../../../lib/extras</Directory>
<Directory>SampleAddins</Directory>
</Addins>