implement GetLoadedProject(), ProjectAdded and adjust relevant methods.
authorAtsushi Eno <atsushieno@veritas-vos-liberabit.com>
Fri, 25 Oct 2013 11:30:36 +0000 (20:30 +0900)
committerAtsushi Eno <atsushieno@veritas-vos-liberabit.com>
Tue, 3 Dec 2013 07:50:33 +0000 (16:50 +0900)
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/Project.cs
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectCollection.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectInstance.cs
mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectCollectionTest.cs

index b3fa89bbaef9012f7f09f0b442dfd577b106589e..9c26df0e332bc28c816032b7241baf1cb492e2ef 100644 (file)
@@ -186,6 +186,8 @@ namespace Microsoft.Build.Evaluation
                        }
 
                        ProcessXml (parent);
+                       
+                       ProjectCollection.AddProject (this);
                }
                
                static readonly char [] item_sep = {';'};
index 7b83937c3517e9848290f2a5761cab08726d48c3..4ce0b0021df63202542b2ca0334f77937f95c298 100644 (file)
@@ -39,6 +39,7 @@ using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.IO;
 using System.Linq;
+using System.Xml;
 
 namespace Microsoft.Build.Evaluation
 {
@@ -133,6 +134,13 @@ namespace Microsoft.Build.Evaluation
 
                readonly int max_node_count;
 
+               public void AddProject (Project project)
+               {
+                       this.loaded_projects.Add (project);
+                       if (ProjectAdded != null)
+                               ProjectAdded (this, new ProjectAddedToProjectCollectionEventArgs (project.Xml));
+               }
+
                [MonoTODO]
                public int Count {
                        get { return loaded_projects.Count; }
@@ -157,7 +165,7 @@ namespace Microsoft.Build.Evaluation
 
                public ICollection<Project> GetLoadedProjects (string fullPath)
                {
-                       return LoadedProjects.Where (p => Path.GetFullPath (p.FullPath) == Path.GetFullPath (fullPath)).ToList ();
+                       return LoadedProjects.Where (p => p.FullPath != null && Path.GetFullPath (p.FullPath) == Path.GetFullPath (fullPath)).ToList ();
                }
 
                readonly IDictionary<string, string> global_properties;
@@ -167,7 +175,38 @@ namespace Microsoft.Build.Evaluation
                }
 
                readonly List<Project> loaded_projects = new List<Project> ();
-
+               
+               public Project LoadProject (string fileName)
+               {
+                       return LoadProject (fileName, DefaultToolsVersion);
+               }
+               
+               public Project LoadProject (string fileName, string toolsVersion)
+               {
+                       return LoadProject (fileName, toolsVersion);
+               }
+               
+               public Project LoadProject (string fileName, IDictionary<string,string> globalProperties, string toolsVersion)
+               {
+                       return new Project (fileName, globalProperties, toolsVersion);
+               }
+               
+               // These methods somehow don't add the project to ProjectCollection...
+               public Project LoadProject (XmlReader xmlReader)
+               {
+                       return LoadProject (xmlReader, DefaultToolsVersion);
+               }
+               
+               public Project LoadProject (XmlReader xmlReader, string toolsVersion)
+               {
+                       return LoadProject (xmlReader, null, toolsVersion);
+               }
+               
+               public Project LoadProject (XmlReader xmlReader, IDictionary<string,string> globalProperties, string toolsVersion)
+               {
+                       return new Project (xmlReader, globalProperties, toolsVersion);
+               }
+               
                [MonoTODO]
                public ICollection<Project> LoadedProjects {
                        get { return loaded_projects; }
index 64995b01ad782c9cdcde59e972f22687df2862e1..cbf3a0924fb2279edfe9f665e812cb018b1e5e18 100644 (file)
@@ -35,6 +35,16 @@ using Microsoft.Build.Evaluation;
 using Microsoft.Build.Framework;
 using Microsoft.Build.Logging;
 
+//
+// It is not always consistent to reuse Project and its evaluation stuff mostly because
+// both BuildParameters.ctor() and Project.ctor() takes arbitrary ProjectCollection, which are not very likely eqivalent
+// (as BuildParameters.ctor(), unlike Project.ctor(...), is known to create a new ProjectCollection instance).
+//
+// However, that inconsistency could happen even if you only use ProjectInstance and BuildParameters.
+// They both have constructors that take ProjectCollection and there is no guarantee that the arguments are the same.
+// BuildManager.Build() does not fail because of inconsistent ProjectCollection instance on .NET. So we can ignore that.
+//
+
 namespace Microsoft.Build.Execution
 {
        public class ProjectInstance
index 504ccaffdfb372b9bb9cfe3d349704b807cf00ab..f9aacea07558f9e86b3ffaecbc5dad6979af10a2 100644 (file)
@@ -51,6 +51,39 @@ namespace MonoTests.Microsoft.Build.Evaluation
             inst.Build ();
             Assert.AreEqual (0, coll.Count, "#2");
                }
+               
+               [Test]
+               public void GetLoadedProjectsWithoutFullPath ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       string path = Path.GetFullPath ("foo.xml");
+                       var pc = new ProjectCollection ();
+                       
+                       pc.LoadProject (XmlReader.Create (new StringReader (project_xml), null, path));
+                       Assert.AreEqual (0, pc.GetLoadedProjects (path).Count, "#1"); // huh?
+                       
+                       new Project (root, null, null, pc);
+                       Assert.AreEqual (0, pc.GetLoadedProjects (path).Count, "#2"); // huh?
+               }
+                       
+               [Test]
+               public void GetLoadedProjectsSuccess ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       string path = Path.GetFullPath ("foo.xml");
+                       var pc = new ProjectCollection ();
+                       
+                       var proj = new Project (root, null, null, pc);
+                       // this order also matters for test; It sets FullPath after Project.ctor(), and should still work.
+                       root.FullPath = "foo.xml";
+                       
+                       Assert.AreEqual (1, pc.GetLoadedProjects (path).Count, "#1"); // wow ok...
+                       Assert.AreEqual (proj, pc.GetLoadedProjects (path).First (), "#2");
+               }
        }
 }