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

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLluis Sanchez <lluis@xamarin.com>2014-04-01 15:00:09 +0400
committerLluis Sanchez <lluis@xamarin.com>2014-04-01 15:00:09 +0400
commite57b52f673ef75ef7597ce195af6d89dc2761950 (patch)
tree2d0f0a01ce8b515edcd9f1040e1d9f2980a2e58c /main/src/core/MonoDevelop.Core
parent2fb79caf515824360412632b9f69d6f4e4820374 (diff)
[Core] MSBuild improvements
Improved handling of imports in MSBuildProject. Made MSBuildProjectHandler more extensible.
Diffstat (limited to 'main/src/core/MonoDevelop.Core')
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildExtension.cs12
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProject.cs57
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectHandler.cs140
3 files changed, 137 insertions, 72 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildExtension.cs
index 6b1abcd4e8..adb9f0a0c4 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildExtension.cs
@@ -24,17 +24,25 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
+using MonoDevelop.Core;
namespace MonoDevelop.Projects.Formats.MSBuild
{
public class MSBuildExtension
{
- public virtual void LoadProject (SolutionEntityItem item, MSBuildProject project)
+ public MSBuildProjectHandler Handler { get; set; }
+
+ public virtual void LoadProject (IProgressMonitor monitor, SolutionEntityItem item, MSBuildProject project)
+ {
+ }
+
+ public virtual void SaveProject (IProgressMonitor monitor, SolutionEntityItem item, MSBuildProject project)
{
}
- public virtual void SaveProject (SolutionEntityItem item, MSBuildProject project)
+ public virtual object GetService (Type t)
{
+ return null;
}
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProject.cs
index b5cb33b05b..057e5db5e5 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProject.cs
@@ -40,7 +40,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
{
public class MSBuildProject
{
- public XmlDocument doc;
+ XmlDocument doc;
string file;
Dictionary<XmlElement,MSBuildObject> elemCache = new Dictionary<XmlElement,MSBuildObject> ();
Dictionary<string, MSBuildItemGroup> bestGroups;
@@ -66,6 +66,10 @@ namespace MonoDevelop.Projects.Formats.MSBuild
get { return file; }
}
+ public XmlDocument Document {
+ get { return doc; }
+ }
+
public MSBuildProject ()
{
doc = new XmlDocument ();
@@ -170,7 +174,12 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void Evaluate ()
{
- MSBuildEvaluationContext context = new MSBuildEvaluationContext (this);
+ Evaluate (new MSBuildEvaluationContext ());
+ }
+
+ public void Evaluate (MSBuildEvaluationContext context)
+ {
+ context.InitEvaluation (this);
foreach (var pg in PropertyGroups)
pg.Evaluate (context);
foreach (var pg in ItemGroups)
@@ -192,7 +201,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
}
- public void AddNewImport (string name, string condition)
+ public MSBuildImport AddNewImport (string name)
{
XmlElement elem = doc.CreateElement (null, "Import", MSBuildProject.Schema);
elem.SetAttribute ("Project", name);
@@ -202,6 +211,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
doc.DocumentElement.InsertAfter (elem, last);
else
doc.DocumentElement.AppendChild (elem);
+ return new MSBuildImport (elem);
}
public void RemoveImport (string name)
@@ -214,13 +224,10 @@ namespace MonoDevelop.Projects.Formats.MSBuild
Console.WriteLine ("ppnf:");
}
- public List<string> Imports {
+ public IEnumerable<MSBuildImport> Imports {
get {
- List<string> ims = new List<string> ();
- foreach (XmlElement elem in doc.DocumentElement.SelectNodes ("tns:Import", XmlNamespaceManager)) {
- ims.Add (elem.GetAttribute ("Project"));
- }
- return ims;
+ foreach (XmlElement elem in doc.DocumentElement.SelectNodes ("tns:Import", XmlNamespaceManager))
+ yield return new MSBuildImport (elem);
}
}
@@ -438,7 +445,12 @@ namespace MonoDevelop.Projects.Formats.MSBuild
elem.AppendChild (e);
return e;
}
-
+
+ public string Label {
+ get { return EvaluatedElement.GetAttribute ("Label"); }
+ set { Element.SetAttribute ("Label", value); }
+ }
+
public string Condition {
get {
return Element.GetAttribute ("Condition");
@@ -455,6 +467,18 @@ namespace MonoDevelop.Projects.Formats.MSBuild
{
}
}
+
+ public class MSBuildImport: MSBuildObject
+ {
+ public MSBuildImport (XmlElement elem): base (elem)
+ {
+ }
+
+ public string Project {
+ get { return EvaluatedElement.GetAttribute ("Project"); }
+ set { Element.SetAttribute ("Project", value); }
+ }
+ }
public class MSBuildProperty: MSBuildObject
{
@@ -878,15 +902,24 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
}
- internal class MSBuildEvaluationContext: IExpressionContext
+ public class MSBuildEvaluationContext: IExpressionContext
{
Dictionary<string,string> properties = new Dictionary<string, string> ();
bool allResolved;
MSBuildProject project;
- public MSBuildEvaluationContext (MSBuildProject project)
+ public MSBuildEvaluationContext ()
+ {
+ }
+
+ internal void InitEvaluation (MSBuildProject project)
{
this.project = project;
+ SetPropertyValue ("MSBuildThisFile", Path.GetFileName (project.FileName));
+ SetPropertyValue ("MSBuildThisFileName", Path.GetFileNameWithoutExtension (project.FileName));
+ SetPropertyValue ("MSBuildThisFileDirectory", Path.GetDirectoryName (project.FileName) + Path.DirectorySeparatorChar);
+ SetPropertyValue ("MSBuildThisFileExtension", Path.GetExtension (project.FileName));
+ SetPropertyValue ("MSBuildThisFileFullPath", Path.GetFullPath (project.FileName));
}
public string GetPropertyValue (string name)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectHandler.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectHandler.cs
index 0b2b77cd31..4a7080b9ac 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectHandler.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectHandler.cs
@@ -152,6 +152,16 @@ namespace MonoDevelop.Projects.Formats.MSBuild
Runtime.SystemAssemblyService.DefaultRuntimeChanged += OnDefaultRuntimeChanged;
}
+
+ public override object GetService (Type t)
+ {
+ foreach (var ex in GetMSBuildExtensions ()) {
+ var s = ex.GetService (t);
+ if (s != null)
+ return s;
+ }
+ return null;
+ }
void OnDefaultRuntimeChanged (object o, EventArgs args)
{
@@ -372,7 +382,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
RemoveDuplicateItems (p, fileName);
- Load (monitor, p);
+ LoadProject (monitor, p);
return it;
} finally {
@@ -597,7 +607,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
}
- void Load (IProgressMonitor monitor, MSBuildProject msproject)
+ protected virtual void LoadProject (IProgressMonitor monitor, MSBuildProject msproject)
{
timer.Trace ("Initialize serialization");
@@ -615,31 +625,8 @@ namespace MonoDevelop.Projects.Formats.MSBuild
timer.Trace ("Read project items");
- foreach (MSBuildItem buildItem in msproject.GetAllItems ()) {
- ProjectItem it = ReadItem (ser, buildItem);
-
- if (it == null) continue;
+ LoadProjectItems (msproject, ser, ProjectItemFlags.None);
- if (it is ProjectFile) {
- var file = (ProjectFile)it;
-
- if (file.Name.IndexOf ('*') > -1) {
- // Thanks to IsOriginatedFromWildcard, these expanded items will not be saved back to disk.
- foreach (var expandedItem in ResolveWildcardItems (file))
- EntityItem.Items.Add (expandedItem);
-
- // Add to wildcard items (so it can be re-saved) instead of Items (where tools will
- // try to compile and display these nonstandard items
- EntityItem.WildcardItems.Add (it);
- continue;
- }
- if (ProjectTypeIsUnsupported && !File.Exists (file.FilePath))
- continue;
- }
-
- EntityItem.Items.Add (it);
- }
-
timer.Trace ("Read configurations");
TargetFrameworkMoniker targetFx = null;
@@ -766,15 +753,41 @@ namespace MonoDevelop.Projects.Formats.MSBuild
dotNetProject.TargetFramework = Runtime.SystemAssemblyService.GetTargetFramework (targetFx);
}
- LoadFromMSBuildProject (msproject);
+ LoadFromMSBuildProject (monitor, msproject);
Item.NeedsReload = false;
}
- protected virtual void LoadFromMSBuildProject (MSBuildProject msproject)
+ internal void LoadProjectItems (MSBuildProject msproject, MSBuildSerializer ser, ProjectItemFlags flags)
+ {
+ foreach (MSBuildItem buildItem in msproject.GetAllItems ()) {
+ ProjectItem it = ReadItem (ser, buildItem);
+ if (it == null)
+ continue;
+ it.Flags = flags;
+ if (it is ProjectFile) {
+ var file = (ProjectFile)it;
+ if (file.Name.IndexOf ('*') > -1) {
+ // Thanks to IsOriginatedFromWildcard, these expanded items will not be saved back to disk.
+ foreach (var expandedItem in ResolveWildcardItems (file))
+ EntityItem.Items.Add (expandedItem);
+ // Add to wildcard items (so it can be re-saved) instead of Items (where tools will
+ // try to compile and display these nonstandard items
+ EntityItem.WildcardItems.Add (it);
+ continue;
+ }
+ if (ProjectTypeIsUnsupported && !File.Exists (file.FilePath))
+ continue;
+ }
+ EntityItem.Items.Add (it);
+ it.ExtendedProperties ["MSBuild.SourceProject"] = msproject.FileName;
+ }
+ }
+
+ protected virtual void LoadFromMSBuildProject (IProgressMonitor monitor, MSBuildProject msproject)
{
foreach (var ext in GetMSBuildExtensions ())
- ext.LoadProject (EntityItem, msproject);
+ ext.LoadProject (monitor, EntityItem, msproject);
}
const string RecursiveDirectoryWildcard = "**";
@@ -889,7 +902,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
}
- ProjectItem ReadItem (MSBuildSerializer ser, MSBuildItem buildItem)
+ internal ProjectItem ReadItem (MSBuildSerializer ser, MSBuildItem buildItem)
{
Project project = Item as Project;
DotNetProject dotNetProject = Item as DotNetProject;
@@ -988,12 +1001,15 @@ namespace MonoDevelop.Projects.Formats.MSBuild
{
// If it is an absolute uri, it's not a valid file
try {
- return !Uri.IsWellFormedUriString (path, UriKind.Absolute);
+ if (Uri.IsWellFormedUriString (path, UriKind.Absolute)) {
+ var f = new Uri (path);
+ return f.Scheme == "file";
+ }
} catch {
// Old mono versions may crash in IsWellFormedUriString if the path
// is not an uri.
- return true;
}
+ return true;
}
class ConfigData
@@ -1069,7 +1085,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
projectBuilder.Refresh ();
}
- MSBuildProject SaveProject (IProgressMonitor monitor)
+ protected virtual MSBuildProject SaveProject (IProgressMonitor monitor)
{
if (Item is UnknownSolutionItem)
return null;
@@ -1255,19 +1271,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
}
- // Remove old items
- Dictionary<string,ItemInfo> oldItems = new Dictionary<string, ItemInfo> ();
- foreach (MSBuildItem item in msproject.GetAllItems ())
- oldItems [item.Name + "<" + item.Include + "<" + item.Condition] = new ItemInfo () { Item=item };
-
- // Add the new items
- foreach (object ob in ((SolutionEntityItem)Item).Items.Concat (((SolutionEntityItem)Item).WildcardItems))
- SaveItem (monitor, toolsFormat, ser, msproject, ob, oldItems);
-
- foreach (ItemInfo itemInfo in oldItems.Values) {
- if (!itemInfo.Added)
- msproject.RemoveItem (itemInfo.Item);
- }
+ SaveProjectItems (monitor, toolsFormat, ser, msproject);
if (dotNetProject != null) {
var moniker = dotNetProject.TargetFramework.Id;
@@ -1288,7 +1292,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
// Impdate the imports section
- List<string> currentImports = msproject.Imports;
+ List<string> currentImports = msproject.Imports.Select (i => i.Project).ToList ();
List<string> imports = new List<string> (currentImports);
// If the project is not new, don't add the default project imports,
@@ -1296,7 +1300,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
UpdateImports (imports, dotNetProject, newProject);
foreach (string imp in imports) {
if (!currentImports.Contains (imp)) {
- msproject.AddNewImport (imp, null);
+ msproject.AddNewImport (imp);
currentImports.Add (imp);
}
}
@@ -1314,15 +1318,32 @@ namespace MonoDevelop.Projects.Formats.MSBuild
} else
msproject.RemoveProjectExtensions ("MonoDevelop");
- SaveToMSBuildProject (msproject);
+ SaveToMSBuildProject (monitor, msproject);
return msproject;
}
- protected void SaveToMSBuildProject (MSBuildProject msproject)
+ internal void SaveProjectItems (IProgressMonitor monitor, MSBuildFileFormat toolsFormat, MSBuildSerializer ser, MSBuildProject msproject, string pathPrefix = null)
+ {
+ // Remove old items
+ Dictionary<string, ItemInfo> oldItems = new Dictionary<string, ItemInfo> ();
+ foreach (MSBuildItem item in msproject.GetAllItems ())
+ oldItems [item.Name + "<" + item.Include + "<" + item.Condition] = new ItemInfo () {
+ Item = item
+ };
+ // Add the new items
+ foreach (object ob in ((SolutionEntityItem)Item).Items.Concat (((SolutionEntityItem)Item).WildcardItems).Where (it => !it.Flags.HasFlag (ProjectItemFlags.DontPersist)))
+ SaveItem (monitor, toolsFormat, ser, msproject, ob, oldItems, pathPrefix);
+ foreach (ItemInfo itemInfo in oldItems.Values) {
+ if (!itemInfo.Added)
+ msproject.RemoveItem (itemInfo.Item);
+ }
+ }
+
+ protected void SaveToMSBuildProject (IProgressMonitor monitor, MSBuildProject msproject)
{
foreach (var ext in GetMSBuildExtensions ())
- ext.SaveProject (EntityItem, msproject);
+ ext.SaveProject (monitor, EntityItem, msproject);
}
void SetIfPresentOrNotDefaultValue (MSBuildPropertySet propGroup, string name, string value, string defaultValue, bool isXml = false)
@@ -1395,13 +1416,13 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
}
- void SaveItem (IProgressMonitor monitor, MSBuildFileFormat fmt, MSBuildSerializer ser, MSBuildProject msproject, object ob, Dictionary<string,ItemInfo> oldItems)
+ void SaveItem (IProgressMonitor monitor, MSBuildFileFormat fmt, MSBuildSerializer ser, MSBuildProject msproject, object ob, Dictionary<string,ItemInfo> oldItems, string pathPrefix = null)
{
if (ob is ProjectReference) {
SaveReference (monitor, fmt, ser, msproject, (ProjectReference) ob, oldItems);
}
else if (ob is ProjectFile) {
- SaveProjectFile (ser, msproject, (ProjectFile) ob, oldItems);
+ SaveProjectFile (ser, msproject, (ProjectFile) ob, oldItems, pathPrefix);
}
else {
string itemName;
@@ -1416,13 +1437,13 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
}
- void SaveProjectFile (MSBuildSerializer ser, MSBuildProject msproject, ProjectFile file, Dictionary<string,ItemInfo> oldItems)
+ void SaveProjectFile (MSBuildSerializer ser, MSBuildProject msproject, ProjectFile file, Dictionary<string,ItemInfo> oldItems, string pathPrefix = null)
{
if (file.IsOriginatedFromWildcard) return;
string itemName = (file.Subtype == Subtype.Directory)? "Folder" : file.BuildAction;
- string path = MSBuildProjectService.ToMSBuildPath (Item.ItemDirectory, file.FilePath);
+ string path = pathPrefix + MSBuildProjectService.ToMSBuildPath (Item.ItemDirectory, file.FilePath);
if (path.Length == 0)
return;
@@ -1434,7 +1455,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
WriteBuildItemMetadata (ser, buildItem, file, oldItems);
if (!string.IsNullOrEmpty (file.DependsOn))
- buildItem.SetMetadata ("DependentUpon", MSBuildProjectService.ToMSBuildPath (Path.GetDirectoryName (file.FilePath), file.DependsOn));
+ buildItem.SetMetadata ("DependentUpon", pathPrefix + MSBuildProjectService.ToMSBuildPath (Path.GetDirectoryName (file.FilePath), file.DependsOn));
else
buildItem.UnsetMetadata ("DependentUpon");
@@ -1457,7 +1478,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
buildItem.UnsetMetadata ("LastGenOutput");
if (!string.IsNullOrEmpty (file.Link))
- buildItem.SetMetadata ("Link", MSBuildProjectService.ToMSBuildPathRelative (Item.ItemDirectory, file.Link));
+ buildItem.SetMetadata ("Link", pathPrefix + MSBuildProjectService.ToMSBuildPathRelative (Item.ItemDirectory, file.Link));
else
buildItem.UnsetMetadata ("Link");
@@ -1620,7 +1641,10 @@ namespace MonoDevelop.Projects.Formats.MSBuild
IEnumerable<MSBuildExtension> GetMSBuildExtensions ()
{
- return AddinManager.GetExtensionObjects<MSBuildExtension> ("/MonoDevelop/ProjectModel/MSBuildExtensions");
+ foreach (var e in AddinManager.GetExtensionObjects<MSBuildExtension> ("/MonoDevelop/ProjectModel/MSBuildExtensions")) {
+ e.Handler = this;
+ yield return e;
+ }
}
void ReadBuildItemMetadata (DataSerializer ser, MSBuildItem buildItem, object dataItem, Type extendedType)