diff options
author | Lluis Sanchez Gual <lluis@xamarin.com> | 2015-02-13 15:29:34 +0300 |
---|---|---|
committer | Lluis Sanchez Gual <lluis@xamarin.com> | 2015-02-13 15:29:34 +0300 |
commit | 77d2fea840207bea0f825f6d9686bdd14c8f4caf (patch) | |
tree | a29e676fdcd4f027c60e251cb3cbfa6c3782b154 /main/src/core | |
parent | 511e02e74d16d68db95988c29a9330dc43604cc6 (diff) |
Automatically serialize project and flavor data
Diffstat (limited to 'main/src/core')
13 files changed, 114 insertions, 33 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/XmlDataSerializer.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/XmlDataSerializer.cs index 2e4a6effff..e478be8634 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/XmlDataSerializer.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/XmlDataSerializer.cs @@ -115,6 +115,8 @@ namespace MonoDevelop.Core.Serialization public bool StoreAllInElements = false; public string[] StoreInElementExceptions { get; set; } + + public string Namespace { get; set; } public void Write (XmlWriter writer, DataNode data) { @@ -130,7 +132,7 @@ namespace MonoDevelop.Core.Serialization public XmlElement Write (XmlDocument doc, DataNode data) { - XmlElement elem = doc.CreateElement (data.Name); + XmlElement elem = doc.CreateElement (data.Name, Namespace); if (data is DataValue) { elem.InnerText = ((DataValue)data).Value; } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/Runtime.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/Runtime.cs index e0c516fe22..83d9e978bc 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/Runtime.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/Runtime.cs @@ -83,11 +83,13 @@ namespace MonoDevelop.Core Platform.Initialize (); - defaultSynchronizationContext = new SynchronizationContext (); - // Set a default sync context - if (SynchronizationContext.Current == null) + if (SynchronizationContext.Current == null) { + defaultSynchronizationContext = new SynchronizationContext (); SynchronizationContext.SetSynchronizationContext (defaultSynchronizationContext); + } else + defaultSynchronizationContext = SynchronizationContext.Current; + // Hook up the SSL certificate validation codepath ServicePointManager.ServerCertificateValidationCallback += delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs index 8137ebf730..fd90b03600 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs @@ -52,38 +52,38 @@ namespace MonoDevelop.Projects.Extensions [NodeAttribute] string type = null; - [NodeAttribute ("tag")] - public string TypeTag { get; protected set; } - - public SolutionItemTypeNode () + protected SolutionItemTypeNode () { } - public SolutionItemTypeNode (string guid, string extension, string import) + protected SolutionItemTypeNode (string guid, string extension, string import) { this.guid = guid; this.extension = extension; this.import = import; } + [NodeAttribute ("tag")] + public string TypeTag { get; set; } + public string Guid { get { return guid; } + set { guid = value; } } public string Extension { - get { - return extension; - } + get { return extension; } + set { extension = value; } } public string Import { - get { - return import; - } + get { return import; } + set { import = value; } } internal string ItemTypeName { get { return type; } + set { type = value; } } public virtual Type ItemType { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/IMSBuildPropertySet.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/IMSBuildPropertySet.cs index f31d158743..c005edddbb 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/IMSBuildPropertySet.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/IMSBuildPropertySet.cs @@ -82,7 +82,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild static Dictionary<Type,PropInfo[]> types = new Dictionary<Type, PropInfo[]> (); - static PropInfo[] GetMembers (Type type) + static PropInfo[] GetMembers (Type type, bool includeBaseMembers) { PropInfo[] pinfo; if (types.TryGetValue (type, out pinfo)) @@ -91,7 +91,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild List<PropInfo> list = new List<PropInfo> (); foreach (var m in type.GetMembers (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { - if (m.DeclaringType != type) + if (!includeBaseMembers && m.DeclaringType != type) continue; if (!(m is FieldInfo) && !(m is PropertyInfo)) continue; @@ -109,17 +109,19 @@ namespace MonoDevelop.Projects.Formats.MSBuild return types [type] = list.ToArray (); } - public static void WriteObjectProperties (this IPropertySet pset, object ob, Type typeToScan) + public static void WriteObjectProperties (this IPropertySet pset, object ob, Type typeToScan, bool includeBaseMembers = false) { - var props = GetMembers (typeToScan); + var props = GetMembers (typeToScan, includeBaseMembers); foreach (var prop in props) { + if (prop.Attribute.IsExternal) + continue; if (prop.ReturnType == typeof(FilePath)) { var val = (FilePath)prop.GetValue (ob); - FilePath def = prop.Attribute.DefaultValue != null ? (string)prop.Attribute.DefaultValue : (string)null; + FilePath def = (string)prop.Attribute.DefaultValue; pset.SetValue (prop.Name, val, def, mergeToMainGroup: prop.MergeToMainGroup); } else if (prop.Attribute is ProjectPathItemProperty && prop.ReturnType == typeof(string)) { FilePath val = (string)prop.GetValue (ob); - FilePath def = prop.Attribute.DefaultValue != null ? (string)prop.Attribute.DefaultValue : (string)null; + FilePath def = (string)prop.Attribute.DefaultValue; pset.SetValue (prop.Name, val, def, mergeToMainGroup: prop.MergeToMainGroup); } else if (prop.ReturnType == typeof(string)) { pset.SetValue (prop.Name, (string)prop.GetValue (ob), (string)prop.Attribute.DefaultValue, prop.MergeToMainGroup); @@ -129,10 +131,12 @@ namespace MonoDevelop.Projects.Formats.MSBuild } } - public static void ReadObjectProperties (this IPropertySet pset, object ob, Type typeToScan) + public static void ReadObjectProperties (this IPropertySet pset, object ob, Type typeToScan, bool includeBaseMembers = false) { - var props = GetMembers (typeToScan); + var props = GetMembers (typeToScan, includeBaseMembers); foreach (var prop in props) { + if (prop.Attribute.IsExternal) + continue; object readVal = null; if (prop.ReturnType == typeof(FilePath)) { FilePath def = prop.Attribute.DefaultValue != null ? (string)prop.Attribute.DefaultValue : (string)null; @@ -149,5 +153,45 @@ namespace MonoDevelop.Projects.Formats.MSBuild prop.SetValue (ob, readVal); } } + + internal static void WriteExternalProjectProperties (this MSBuildProject project, object ob, Type typeToScan, bool includeBaseMembers = false) + { + var props = GetMembers (typeToScan, includeBaseMembers); + XmlConfigurationWriter writer = null; + foreach (var prop in props) { + if (!prop.Attribute.IsExternal) + continue; + var val = prop.GetValue (ob); + if (val != null) { + DataSerializer ser = new DataSerializer (Services.ProjectService.DataContext); + var data = ser.Serialize (val, prop.ReturnType); + if (data != null) { + data.Name = prop.Name; + if (writer == null) + writer = new XmlConfigurationWriter { Namespace = MSBuildProject.Schema }; + var elem = writer.Write (project.Document, data); + project.SetMonoDevelopProjectExtension (prop.Name, elem); + continue; + } + } + project.RemoveMonoDevelopProjectExtension (prop.Name); + } + } + + internal static void ReadExternalProjectProperties (this MSBuildProject project, object ob, Type typeToScan, bool includeBaseMembers = false) + { + var props = GetMembers (typeToScan, includeBaseMembers); + foreach (var prop in props) { + if (!prop.Attribute.IsExternal) + continue; + var sec = project.GetMonoDevelopProjectExtension (prop.Name); + if (sec != null) { + var data = XmlConfigurationReader.DefaultReader.Read (sec); + DataSerializer ser = new DataSerializer (Services.ProjectService.DataContext); + var val = ser.Deserialize (prop.ReturnType, data); + prop.SetValue (ob, val); + } + } + } } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectService.cs index 32463f53c0..783515a501 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectService.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectService.cs @@ -324,12 +324,12 @@ namespace MonoDevelop.Projects.Formats.MSBuild static List<SolutionItemTypeNode> customNodes = new List<SolutionItemTypeNode> (); - internal static void RegisterCustomItemExtension (SolutionItemTypeNode node) + internal static void RegisterCustomItemType (SolutionItemTypeNode node) { customNodes.Add (node); } - internal static void UnregisterCustomItemExtension (SolutionItemTypeNode node) + internal static void UnregisterCustomItemType (SolutionItemTypeNode node) { customNodes.Remove (node); } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/SlnFileFormat.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/SlnFileFormat.cs index 75fbc0786d..8f3a32a7e5 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/SlnFileFormat.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/SlnFileFormat.cs @@ -652,11 +652,8 @@ namespace MonoDevelop.Projects.Formats.MSBuild item = ta.Result; if (item == null) throw new UnknownSolutionItemTypeException (projTypeGuid); - } catch (Exception e) { - // If we get a TargetInvocationException from using Activator.CreateInstance we - // need to unwrap the real exception - while (e is TargetInvocationException) - e = e.InnerException; + } catch (Exception cex) { + var e = UnwrapException (cex).First (); bool loadAsProject = false; @@ -769,6 +766,25 @@ namespace MonoDevelop.Projects.Formats.MSBuild monitor.EndTask (); } + IEnumerable<Exception> UnwrapException (Exception ex) + { + var a = ex as AggregateException; + if (a != null) { + foreach (var e in a.InnerExceptions) { + foreach (var u in UnwrapException (e)) + yield return u; + } + } else if (ex is TargetInvocationException) { + // If we get a TargetInvocationException from using Activator.CreateInstance we + // need to unwrap the real exception + ex = ex.InnerException; + foreach (var e in UnwrapException (ex)) + yield return e; + } + else + yield return ex; + } + void LoadProjectConfigurationMappings (SlnPropertySetCollection sets, Solution sln, Dictionary<string, SolutionFolderItem> items, ProgressMonitor monitor) { if (sets == null) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ChainedExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ChainedExtension.cs index a657d422f6..eabec7455b 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ChainedExtension.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ChainedExtension.cs @@ -74,6 +74,10 @@ namespace MonoDevelop.Projects } } + // Serializable fields and properties + if (next.GetType ().GetMembers (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Any (m => m.IsDefined (typeof(MonoDevelop.Core.Serialization.ItemPropertyAttribute)))) + return next; + return FindNextImplementation (type, next.nextInChain); } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs index 54f67820a9..9206b5cb30 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs @@ -1649,6 +1649,8 @@ namespace MonoDevelop.Projects baseIntermediateOutputPath = msproject.EvaluatedProperties.GetPathValue ("BaseIntermediateOutputPath", defaultValue:BaseDirectory.Combine ("obj"), relativeToProject:true); disableFastUpToDateCheck = msproject.EvaluatedProperties.GetValue ("DisableFastUpToDateCheck", false); + globalGroup.ReadObjectProperties (this, GetType (), true); + RemoveDuplicateItems (msproject); } @@ -1734,6 +1736,8 @@ namespace MonoDevelop.Projects // Read extended properties timer.Trace ("Read extended properties"); + + msproject.ReadExternalProjectProperties (this, GetType (), true); } List<ConfigData> GetConfigData (MSBuildProject msproject, bool includeGlobalGroups) @@ -2042,6 +2046,8 @@ namespace MonoDevelop.Projects msproject.GetGlobalPropertyGroup ().SetValue ("Description", Description, ""); msproject.GetGlobalPropertyGroup ().SetValue ("BaseIntermediateOutputPath", BaseIntermediateOutputPath, defaultValue:BaseDirectory.Combine ("obj"), relativeToProject:true); msproject.GetGlobalPropertyGroup ().SetValue ("DisableFastUpToDateCheck", disableFastUpToDateCheck, false); + + globalGroup.WriteObjectProperties (this, GetType (), true); } protected virtual void OnWriteProject (ProgressMonitor monitor, MSBuildProject msproject) @@ -2128,6 +2134,7 @@ namespace MonoDevelop.Projects if (i != null) msproject.RemoveImport (i); } + msproject.WriteExternalProjectProperties (this, GetType (), true); } void WriteConfiguration (ProgressMonitor monitor, List<ConfigData> configData, string conf, string platform) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs index 729c1e6042..fcc5a4839c 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs @@ -81,6 +81,7 @@ namespace MonoDevelop.Projects environmentVariables [name] = (string)val.Attribute ("value"); } } + pset.ReadObjectProperties (this, GetType (), true); } internal protected virtual void Write (IPropertySet pset, string toolsVersion) @@ -104,6 +105,8 @@ namespace MonoDevelop.Projects pset.SetValue ("EnvironmentVariables", e.ToString ()); } else pset.RemoveProperty ("EnvironmentVariables"); + + pset.WriteObjectProperties (this, GetType (), true); } FilePath intermediateOutputDirectory = FilePath.Empty; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs index 4f3b579b45..92b1798d91 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs @@ -99,6 +99,8 @@ namespace MonoDevelop.Projects internal protected virtual void OnReadProject (ProgressMonitor monitor, MSBuildProject msproject) { next.OnReadProject (monitor, msproject); + msproject.GetGlobalPropertyGroup ().ReadObjectProperties (this, GetType (), true); + msproject.ReadExternalProjectProperties (this, GetType (), true); } internal protected virtual void OnReadConfiguration (ProgressMonitor monitor, ProjectConfiguration config, IMSBuildPropertySet pset) @@ -109,6 +111,8 @@ namespace MonoDevelop.Projects internal protected virtual void OnWriteProject (ProgressMonitor monitor, MSBuildProject msproject) { next.OnWriteProject (monitor, msproject); + msproject.GetGlobalPropertyGroup ().WriteObjectProperties (this, GetType (), true); + msproject.WriteExternalProjectProperties (this, GetType (), true); } internal protected virtual void OnWriteConfiguration (ProgressMonitor monitor, ProjectConfiguration config, IMSBuildPropertySet pset) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectParameters.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectParameters.cs index 433eac18fb..374e753bd7 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectParameters.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectParameters.cs @@ -62,10 +62,12 @@ namespace MonoDevelop.Projects protected virtual void Read (IPropertySet pset, string toolsVersion) { + pset.ReadObjectProperties (this, GetType (), true); } protected virtual void Write (IPropertySet pset, string toolsVersion) { + pset.WriteObjectProperties (this, GetType (), true); } } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItem.cs index 4dfc3aa53a..46c9baa877 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItem.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItem.cs @@ -58,7 +58,6 @@ namespace MonoDevelop.Projects internal List<string> UnresolvedProjectDependencies { get; set; } - [ItemProperty ("name")] public new string Name { get { return base.Name; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs index afe76ce2df..a152a7fa37 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs @@ -1009,8 +1009,6 @@ namespace MonoDevelop.Projects return configs.AsReadOnly (); } - [ItemProperty ("Configurations")] - [ItemProperty ("Configuration", ValueType=typeof(SolutionItemConfiguration), Scope="*")] public SolutionItemConfigurationCollection Configurations { get { return configurations; |