diff options
author | Matt Ward <ward.matt@gmail.com> | 2014-06-17 16:50:11 +0400 |
---|---|---|
committer | Matt Ward <ward.matt@gmail.com> | 2014-06-17 16:50:11 +0400 |
commit | 5ac097efad7b10142cff27c5e30d56d76c91724f (patch) | |
tree | 39c35854d8d2d7186a63e3e4d53449216ef89b62 /main | |
parent | 34be5c15de5098d6ea9ceccb7364fae97f39f2e8 (diff) | |
parent | ea577f4a208954bb52f99abfea0db1f73f321420 (diff) |
Merge branch 'master' into msbuild-import-conditions
Conflicts:
main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
Diffstat (limited to 'main')
28 files changed, 577 insertions, 324 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/AssemblyContext.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/AssemblyContext.cs index a4b9ac2100..03c844c227 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/AssemblyContext.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/AssemblyContext.cs @@ -132,9 +132,15 @@ namespace MonoDevelop.Core.Assemblies { return packages; } - + + [Obsolete ("Cannot de-duplicate framework assemblies")] public IEnumerable<SystemPackage> GetPackages (TargetFramework fx) { + return GetPackagesInternal (fx); + } + + IEnumerable<SystemPackage> GetPackagesInternal (TargetFramework fx) + { foreach (SystemPackage pkg in packages) { if (pkg.IsFrameworkPackage) { if (fx.IncludesFramework (pkg.TargetFramework)) @@ -192,31 +198,39 @@ namespace MonoDevelop.Core.Assemblies foreach (SystemAssembly asm in pkg.Assemblies) yield return asm; } - } else { - foreach (SystemPackage pkg in GetPackages (fx)) { - foreach (SystemAssembly asm in pkg.Assemblies) + yield break; + } + + var fxGroups = new Dictionary<string, List<SystemAssembly>> (); + + foreach (SystemPackage pkg in GetPackagesInternal (fx)) { + if (pkg.IsFrameworkPackage) { + foreach (var asm in pkg.Assemblies) { + List<SystemAssembly> list; + if (!fxGroups.TryGetValue (asm.FullName, out list)) + fxGroups [asm.FullName] = list = new List<SystemAssembly> (); + list.Add (asm); + } + } else { + foreach (var asm in pkg.Assemblies) yield return asm; } } + + foreach (var g in fxGroups) { + var a = BestFrameworkAssembly (g.Value); + if (a != null) + yield return a; + } } public SystemAssembly GetAssemblyFromFullName (string fullname, string package, TargetFramework fx) { if (package == null) { - SystemAssembly found = null; - SystemAssembly gacFound = null; - foreach (SystemAssembly asm in GetAssembliesFromFullNameInternal (fullname)) { - if (asm.Package.IsFrameworkPackage && fx != null) { - if (fx.IncludesFramework (asm.Package.TargetFramework)) - return asm; - else - continue; - } - found = asm; - if (asm.Package.IsGacPackage) - gacFound = asm; - } - return gacFound ?? found; + var asms = GetAssembliesFromFullNameInternal (fullname).ToList (); + return BestFrameworkAssembly (asms, fx) + ?? asms.FirstOrDefault (a => a.Package.IsGacPackage) + ?? asms.FirstOrDefault (); } foreach (SystemAssembly asm in GetAssembliesFromFullNameInternal (fullname)) { @@ -270,10 +284,10 @@ namespace MonoDevelop.Core.Assemblies public static string NormalizeAsmName (string name) { - int i = name.ToLower ().IndexOf (", publickeytoken=null"); + int i = name.ToLower ().IndexOf (", publickeytoken=null", StringComparison.Ordinal); if (i != -1) name = name.Substring (0, i).Trim (); - i = name.ToLower ().IndexOf (", processorarchitecture="); + i = name.ToLower ().IndexOf (", processorarchitecture=", StringComparison.Ordinal); if (i != -1) name = name.Substring (0, i).Trim (); return name; @@ -304,13 +318,18 @@ namespace MonoDevelop.Core.Assemblies return best; } + + var asms = FindNewerAssembliesSameName (fullname).ToList (); + + if (fx != null) { + var fxAsm = BestFrameworkAssembly (asms, fx); + if (fxAsm != null) + return fxAsm.FullName; + } + string bestMatch = null; - foreach (SystemAssembly asm in FindNewerAssembliesSameName (fullname)) { - if (asm.Package.IsFrameworkPackage) { - if (fx.IncludesFramework (asm.Package.TargetFramework)) - if (package == null || asm.Package.Name == package) - return asm.FullName; - } else if (fx.CanReferenceAssembliesTargetingFramework (asm.Package.TargetFramework)) { + foreach (SystemAssembly asm in asms) { + if (fx.CanReferenceAssembliesTargetingFramework (asm.Package.TargetFramework)) { if (package != null && asm.Package.Name == package) return asm.FullName; bestMatch = asm.FullName; @@ -318,6 +337,36 @@ namespace MonoDevelop.Core.Assemblies } return bestMatch; } + + static SystemAssembly BestFrameworkAssembly (IEnumerable<SystemAssembly> assemblies, TargetFramework fx) + { + if (fx == null) + return null; + return BestFrameworkAssembly ( + assemblies + .Where (a => a.Package != null && a.Package.IsFrameworkPackage && fx.IncludesFramework (a.Package.TargetFramework)) + .ToList () + ); + } + + static SystemAssembly BestFrameworkAssembly (List<SystemAssembly> list) + { + if (list.Count == 0) + return null; + + if (list.Count == 1) + return list [0]; + + SystemAssembly best = list [0]; + + for (int i = 1; i < list.Count; i++) { + var a = list[i]; + var f = Runtime.SystemAssemblyService.GetTargetFramework (a.Package.TargetFramework); + if (f.IncludesFramework (best.Package.TargetFramework)) + best = a; + } + return best; + } IEnumerable<SystemAssembly> FindNewerAssembliesSameName (string fullname) { @@ -419,7 +468,7 @@ namespace MonoDevelop.Core.Assemblies if (asm == null) return null; - var fxAsms = asm.AllSameName ().Where (a => a.Package.IsFrameworkPackage); + var fxAsms = asm.AllSameName ().Where (a => a.Package.IsFrameworkPackage).ToList (); //if the asm is not a framework asm, we don't upgrade it automatically if (!fxAsms.Any ()) { @@ -430,22 +479,19 @@ namespace MonoDevelop.Core.Assemblies return null; } - foreach (var fxAsm in fxAsms) { - if (fx.IncludesFramework (fxAsm.Package.TargetFramework)) - return fxAsm; - } + var bestFx = BestFrameworkAssembly (fxAsms, fx); + if (bestFx != null) + return bestFx; // We have to find the assembly with the same name in the target fx - string fname = Path.GetFileName ((string) fxAsms.First ().Location); - - foreach (var pair in assemblyFullNameToAsm) { - foreach (var fxAsm in pair.Value.AllSameName ()) { - var rpack = fxAsm.Package; - if (rpack.IsFrameworkPackage && fx.IncludesFramework (rpack.TargetFramework) && Path.GetFileName (fxAsm.Location) == fname) - return fxAsm; - } - } - return null; + string fname = Path.GetFileName (fxAsms.First ().Location); + + var possible = packages.Where (p => p.IsFrameworkPackage && fx.IncludesFramework (p.TargetFramework)) + .SelectMany (p => p.Assemblies) + .Where (a => Path.GetFileName (a.Location) == fname) + .ToList (); + + return BestFrameworkAssembly (possible); } public string GetAssemblyFullName (string assemblyName, TargetFramework fx) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/IAssemblyContext.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/IAssemblyContext.cs index 179c999622..dc0a28c829 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/IAssemblyContext.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/IAssemblyContext.cs @@ -31,8 +31,12 @@ namespace MonoDevelop.Core.Assemblies { public interface IAssemblyContext { + [Obsolete ("Avoid use of SystemPackage")] IEnumerable<SystemPackage> GetPackages (); + + [Obsolete ("Avoid use of SystemPackage")] IEnumerable<SystemPackage> GetPackages (TargetFramework fx); + SystemPackage GetPackage (string name); SystemPackage GetPackage (string name, string version); SystemPackage GetPackageFromPath (string path); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFramework.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFramework.cs index cfdd618d69..d3be657e8e 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFramework.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFramework.cs @@ -263,11 +263,6 @@ namespace MonoDevelop.Core.Assemblies set; } - internal AssemblyInfo[] AssembliesExpanded { - get; - set; - } - public override string ToString () { return string.Format ("[TargetFramework: Hidden={0}, Name={1}, Id={2}, ClrVersion={3}]", @@ -335,9 +330,8 @@ namespace MonoDevelop.Core.Assemblies if (reader.MoveToAttribute ("IncludeFramework") && reader.ReadAttributeValue ()) { string include = reader.ReadContentAsString (); - if (!string.IsNullOrEmpty (include)) { - fx.IncludedFrameworks.Add (new TargetFrameworkMoniker (fx.Id.Identifier, include)); - } + if (!string.IsNullOrEmpty (include)) + fx.includesFramework = include; } //this is a Mono-specific extension @@ -374,7 +368,7 @@ namespace MonoDevelop.Core.Assemblies // HACK: we were using EnumerateFiles but it's broken in some Mono releases // https://bugzilla.xamarin.com/show_bug.cgi?id=2975 - var files = System.IO.Directory.GetFiles (dir, "*.dll"); + var files = Directory.GetFiles (dir, "*.dll"); foreach (var f in files) { try { var an = SystemAssemblyService.GetAssemblyNameObj (dir.Combine (f)); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.addin.xml b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.addin.xml index ccab54f5a6..f91a6b60eb 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.addin.xml +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.addin.xml @@ -144,6 +144,10 @@ <ExtensionPoint path = "/MonoDevelop/ProjectModel/MSBuildImportProviders" name = "MSBuild Import Providers"> <ExtensionNode objectType="MonoDevelop.Projects.Formats.MSBuild.IMSBuildImportProvider"/> </ExtensionPoint> + + <ExtensionPoint path = "/MonoDevelop/ProjectModel/MSBuildGlobalPropertyProviders" name = "MSBuild Global Property Providers"> + <ExtensionNode objectType="MonoDevelop.Projects.Formats.MSBuild.IMSBuildGlobalPropertyProvider"/> + </ExtensionPoint> <ExtensionPoint path = "/MonoDevelop/ProjectModel/MSBuildExtensions" name = "MSBuild Extensions"> <ExtensionNode name="Class" objectType="MonoDevelop.Projects.Formats.MSBuild.MSBuildExtension"/> diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj index a65dd1e7e4..a0763f2766 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj @@ -470,6 +470,7 @@ <Compile Include="MonoDevelop.Core.Web\CredentialProviderExtensions.cs" /> <Compile Include="MonoDevelop.Core.Execution\IDebugConsole.cs" /> <Compile Include="MonoDevelop.Projects\IDotNetFileContainer.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\IMSBuildGlobalPropertyProvider.cs" /> <Compile Include="MonoDevelop.Projects\DotNetProjectImport.cs" /> </ItemGroup> <ItemGroup> diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/IMSBuildGlobalPropertyProvider.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/IMSBuildGlobalPropertyProvider.cs new file mode 100644 index 0000000000..df7c76e443 --- /dev/null +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/IMSBuildGlobalPropertyProvider.cs @@ -0,0 +1,36 @@ +// +// IMSBuildGlobalPropertyProvider.cs +// +// Author: +// Michael Hutchinson <m.j.hutchinson@gmail.com> +// +// Copyright (c) 2014 Xamarin Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Collections.Generic; + +namespace MonoDevelop.Projects.Formats.MSBuild +{ + public interface IMSBuildGlobalPropertyProvider + { + event EventHandler GlobalPropertiesChanged; + IDictionary<string,string> GetGlobalProperties (); + } +} 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 2f5117e387..96e68d4cef 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 @@ -259,8 +259,17 @@ namespace MonoDevelop.Projects.Formats.MSBuild SolutionEntityItem item = (SolutionEntityItem) Item; RemoteProjectBuilder builder = GetProjectBuilder (); var configs = GetConfigurations (item, configuration); - foreach (string s in builder.GetAssemblyReferences (configs)) - yield return s; + + var result = builder.Run ( + configs, null, MSBuildVerbosity.Normal, + new[] { "ResolveAssemblyReferences" }, new [] { "ReferencePath" }, null + ); + + List<MSBuildEvaluatedItem> items; + if (result.Items.TryGetValue ("ReferencePath", out items) && items != null) { + foreach (var i in items) + yield return i.ItemSpec; + } } else { CleanupProjectBuilder (); @@ -282,19 +291,19 @@ namespace MonoDevelop.Projects.Formats.MSBuild LogWriter logWriter = new LogWriter (monitor.Log); RemoteProjectBuilder builder = GetProjectBuilder (); var configs = GetConfigurations (item, configuration); - MSBuildResult[] results = builder.RunTarget (target, configs, logWriter, MSBuildProjectService.DefaultMSBuildVerbosity); + var result = builder.Run (configs, logWriter, MSBuildProjectService.DefaultMSBuildVerbosity, new[] { target }, null, null); System.Runtime.Remoting.RemotingServices.Disconnect (logWriter); var br = new BuildResult (); - foreach (MSBuildResult res in results) { + foreach (var err in result.Errors) { FilePath file = null; - if (res.File != null) - file = Path.Combine (Path.GetDirectoryName (res.ProjectFile), res.File); + if (err.File != null) + file = Path.Combine (Path.GetDirectoryName (err.ProjectFile), err.File); - if (res.IsWarning) - br.AddWarning (file, res.LineNumber, res.ColumnNumber, res.Code, res.Message); + if (err.IsWarning) + br.AddWarning (file, err.LineNumber, err.ColumnNumber, err.Code, err.Message); else - br.AddError (file, res.LineNumber, res.ColumnNumber, res.Code, res.Message); + br.AddError (file, err.LineNumber, err.ColumnNumber, err.Code, err.Message); } return br; } @@ -360,7 +369,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild // Workaround for a VS issue. VS doesn't include the curly braces in the ProjectGuid // of shared projects. - if (!itemGuid.StartsWith ("{") && fileName.EndsWith (".shproj")) + if (!itemGuid.StartsWith ("{")) itemGuid = "{" + itemGuid + "}"; itemGuid = itemGuid.ToUpper (); 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 217124a284..ac766786b6 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 @@ -56,6 +56,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild static DataContext dataContext; + static IMSBuildGlobalPropertyProvider[] globalPropertyProviders; static Dictionary<string,RemoteBuildEngine> builders = new Dictionary<string, RemoteBuildEngine> (); static GenericItemTypeNode genericItemTypeNode = new GenericItemTypeNode (); @@ -91,6 +92,21 @@ namespace MonoDevelop.Projects.Formats.MSBuild ShutDown = true; CleanProjectBuilders (); }; + + const string gppPath = "/MonoDevelop/ProjectModel/MSBuildGlobalPropertyProviders"; + globalPropertyProviders = AddinManager.GetExtensionObjects<IMSBuildGlobalPropertyProvider> (gppPath); + foreach (var gpp in globalPropertyProviders) { + gpp.GlobalPropertiesChanged += HandleGlobalPropertyProviderChanged; + } + } + + static void HandleGlobalPropertyProviderChanged (object sender, EventArgs e) + { + lock (builders) { + var gpp = (IMSBuildGlobalPropertyProvider) sender; + foreach (var builder in builders.Values) + builder.SetGlobalProperties (gpp.GetGlobalProperties ()); + } } static void HandlePropertyChanged (object sender, PropertyChangedEventArgs e) @@ -486,7 +502,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild return true; } - public static RemoteProjectBuilder GetProjectBuilder (TargetRuntime runtime, string minToolsVersion, string file, string solutionFile) + internal static RemoteProjectBuilder GetProjectBuilder (TargetRuntime runtime, string minToolsVersion, string file, string solutionFile) { lock (builders) { //attempt to use 12.0 builder first if available @@ -538,7 +554,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild string sref; while (true) { sref = p.StandardError.ReadLine (); - if (sref.StartsWith (responseKey)) { + if (sref.StartsWith (responseKey, StringComparison.Ordinal)) { sref = sref.Substring (responseKey.Length); break; } @@ -547,7 +563,10 @@ namespace MonoDevelop.Projects.Formats.MSBuild MemoryStream ms = new MemoryStream (data); BinaryFormatter bf = new BinaryFormatter (); var engine = (IBuildEngine)bf.Deserialize (ms); - engine.Initialize (solutionFile, GettextCatalog.UICulture); + engine.SetCulture (GettextCatalog.UICulture); + engine.SetGlobalProperties (GetCoreGlobalProperties (solutionFile)); + foreach (var gpp in globalPropertyProviders) + builder.SetGlobalProperties (gpp.GetGlobalProperties ()); builder = new RemoteBuildEngine (p, engine); } catch { if (p != null) { @@ -563,6 +582,29 @@ namespace MonoDevelop.Projects.Formats.MSBuild return new RemoteProjectBuilder (file, builder); } } + + static IDictionary<string,string> GetCoreGlobalProperties (string slnFile) + { + var dictionary = new Dictionary<string,string> (); + + //this causes build targets to behave how they should inside an IDE, instead of in a command-line process + dictionary.Add ("BuildingInsideVisualStudio", "true"); + + //we don't have host compilers in MD, and this is set to true by some of the MS targets + //which causes it to always run the CoreCompile task if BuildingInsideVisualStudio is also + //true, because the VS in-process compiler would take care of the deps tracking + dictionary.Add ("UseHostCompilerIfAvailable", "false" ); + + if (string.IsNullOrEmpty (slnFile)) + return dictionary; + + dictionary.Add ("SolutionPath", Path.GetFullPath (slnFile)); + dictionary.Add ("SolutionName", Path.GetFileNameWithoutExtension (slnFile)); + dictionary.Add ("SolutionFilename", Path.GetFileName (slnFile)); + dictionary.Add ("SolutionDir", Path.GetDirectoryName (slnFile) + Path.DirectorySeparatorChar); + + return dictionary;; + } static string GetExeLocation (TargetRuntime runtime, string toolsVersion) { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/RemoteProjectBuilder.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/RemoteProjectBuilder.cs index a033d83d0c..e5d99fb724 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/RemoteProjectBuilder.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/RemoteProjectBuilder.cs @@ -27,6 +27,9 @@ using System; using System.Diagnostics; using System.Globalization; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace MonoDevelop.Projects.Formats.MSBuild { @@ -54,9 +57,14 @@ namespace MonoDevelop.Projects.Formats.MSBuild engine.UnloadProject (pb); } - public void Initialize (string slnFile, CultureInfo uiCulture) + public void SetCulture (CultureInfo uiCulture) { - engine.Initialize (slnFile, uiCulture); + engine.SetCulture (uiCulture); + } + + public void SetGlobalProperties (IDictionary<string, string> properties) + { + engine.SetGlobalProperties (properties); } public void Dispose () @@ -82,19 +90,16 @@ namespace MonoDevelop.Projects.Formats.MSBuild this.engine = engine; builder = engine.LoadProject (file); } - - public MSBuildResult[] RunTarget (string target, ProjectConfigurationInfo[] configurations, ILogWriter logWriter, - MSBuildVerbosity verbosity) - { - if (target == null) - throw new ArgumentNullException ("target"); - return builder.RunTarget (target, configurations, logWriter, verbosity); - } - - public string[] GetAssemblyReferences (ProjectConfigurationInfo[] configurations) + public MSBuildResult Run ( + ProjectConfigurationInfo[] configurations, + ILogWriter logWriter, + MSBuildVerbosity verbosity, + string[] runTargets, + string[] evaluateItems, + string[] evaluateProperties) { - return builder.GetAssemblyReferences (configurations); + return builder.Run (configurations, logWriter, verbosity, runTargets, evaluateItems, evaluateProperties); } public void Refresh () diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs index 62b74b91b7..d6a7a8c7f0 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs @@ -1061,12 +1061,17 @@ namespace MonoDevelop.Projects { foreach (ProjectReference pref in References) { if (pref.ReferenceType == ReferenceType.Package) { - string newRef = AssemblyContext.GetAssemblyNameForVersion (pref.Reference, pref.Package != null ? pref.Package.Name : null, this.TargetFramework); - if (newRef == null) { + // package name is only relevant if it's not a framework package + var pkg = pref.Package; + string packageName = pkg != null && !pkg.IsFrameworkPackage? pkg.Name : null; + // find the version of the assembly that's valid for the new framework + var newAsm = AssemblyContext.GetAssemblyForVersion (pref.Reference, packageName, TargetFramework); + // if it changed, clear assembly resolution caches and update reference + if (newAsm == null) { pref.ResetReference (); - } else if (newRef != pref.Reference) { - pref.Reference = newRef; - } else if (!pref.IsValid) { + } else if (newAsm.FullName != pref.Reference) { + pref.Reference = newAsm.FullName; + } else if (!pref.IsValid || newAsm.Package != pref.Package) { pref.ResetReference (); } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectReference.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectReference.cs index e00466ac05..74e56794d8 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectReference.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectReference.cs @@ -466,20 +466,8 @@ namespace MonoDevelop.Projects // No package is specified, get any of the registered assemblies, giving priority to gaced assemblies // (because non-gac assemblies should have a package name set) - SystemAssembly best = null; - foreach (SystemAssembly asm in AssemblyContext.GetAssembliesFromFullName (reference)) { - //highest priority to framework packages - if (ownerProject != null && asm.Package.IsFrameworkPackage) { - var targetFx = ownerProject.TargetFramework; - var packageFxId = asm.Package.TargetFramework; - if (targetFx.IncludesFramework (packageFxId)) - return cachedPackage = asm.Package; - } - if (asm.Package.IsGacPackage) - best = asm; - else if (best == null) - best = asm; - } + TargetFramework fx = ownerProject == null? null : ownerProject.TargetFramework; + var best = AssemblyContext.GetAssemblyFromFullName (reference, null, fx); if (best != null) return cachedPackage = best.Package; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionFolderFileNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionFolderFileNodeBuilder.cs index 16806831fe..a324c03715 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionFolderFileNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/SolutionFolderFileNodeBuilder.cs @@ -25,6 +25,7 @@ // THE SOFTWARE. using System; +using System.Collections.Generic; using MonoDevelop.Projects; using MonoDevelop.Ide.Gui.Components; using MonoDevelop.Core; @@ -82,6 +83,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad { public override void DeleteMultipleItems () { + var modifiedSolutionsToSave = new HashSet<Solution> (); QuestionMessage msg = new QuestionMessage (); msg.SecondaryText = GettextCatalog.GetString ("The Delete option permanently removes the file from your hard disk. Click Remove from Solution if you only want to remove it from your current solution."); AlertButton removeFromSolution = new AlertButton (GettextCatalog.GetString ("_Remove from Solution"), Gtk.Stock.Remove); @@ -105,7 +107,13 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad if (result == AlertButton.Delete) { FileService.DeleteFile (file.FileName); } + + if (file.Parent != null && file.Parent.ParentSolution != null) { + modifiedSolutionsToSave.Add (file.Parent.ParentSolution); + } } + + IdeApp.ProjectOperations.Save (modifiedSolutionsToSave); } public override void ActivateItem () diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/DefaultWorkbench.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/DefaultWorkbench.cs index 846027b6f9..3ce0d1e9ed 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/DefaultWorkbench.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/DefaultWorkbench.cs @@ -422,7 +422,7 @@ namespace MonoDevelop.Ide.Gui { if (node is PadCodon) { PadCodon pad = (PadCodon) node; - RegisterPad (pad); + AddPad (pad, pad.DefaultPlacement, pad.DefaultStatus); } else if (node is CategoryNode) { foreach (ExtensionNode cn in node.ChildNodes) @@ -784,10 +784,6 @@ namespace MonoDevelop.Ide.Gui { AddinManager.AddExtensionNodeHandler (stockLayoutsPath, OnLayoutsExtensionChanged); - ExtensionNodeList padCodons = AddinManager.GetExtensionNodes (viewContentPath); - foreach (ExtensionNode node in padCodons) - ShowPadNode (node); - CreateComponents (); // Subscribe to changes in the extension @@ -930,9 +926,10 @@ namespace MonoDevelop.Ide.Gui } // create DockItems for all the pads - foreach (PadCodon content in padContentCollection) - AddPad (content, content.DefaultPlacement, content.DefaultStatus); - + ExtensionNodeList padCodons = AddinManager.GetExtensionNodes (viewContentPath); + foreach (ExtensionNode node in padCodons) + ShowPadNode (node); + try { if (System.IO.File.Exists (configFile)) { dock.LoadLayouts (configFile); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs index a972785b24..e55063ff02 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService.cs @@ -2403,20 +2403,18 @@ namespace MonoDevelop.Ide.TypeSystem static IEnumerable<SystemAssembly> GetFrameworkAssemblies (DotNetProject netProject) { var assemblies = new Dictionary<string, SystemAssembly> (); - foreach (var systemPackage in netProject.AssemblyContext.GetPackages ()) { - foreach (var assembly in systemPackage.Assemblies) { - SystemAssembly existing; - if (assemblies.TryGetValue (assembly.Name, out existing)) { - Version v1, v2; - if (!Version.TryParse (existing.Version, out v1)) - continue; - if (!Version.TryParse (assembly.Version, out v2)) - continue; - if (v1 > v2) - continue; - } - assemblies [assembly.Name] = assembly; + foreach (var assembly in netProject.AssemblyContext.GetAssemblies ()) { + SystemAssembly existing; + if (assemblies.TryGetValue (assembly.Name, out existing)) { + Version v1, v2; + if (!Version.TryParse (existing.Version, out v1)) + continue; + if (!Version.TryParse (assembly.Version, out v2)) + continue; + if (v1 > v2) + continue; } + assemblies [assembly.Name] = assembly; } return assemblies.Values; } diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.csproj b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.csproj index 0dd7cecb4e..76cae3f03b 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.csproj +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.csproj @@ -41,7 +41,6 @@ <ItemGroup> <Compile Include="AssemblyInfo.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ProjectBuilder.cs" /> - <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\LocalLogger.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ILogWriter.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\IProjectBuilder.cs" /> @@ -49,6 +48,9 @@ <Compile Include="MonoDevelop.Projects.Formats.MSBuild\IBuildEngine.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ConsoleLogger.cs" /> <Compile Include="AssemblyInfo.v4.0.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildTargetResult.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildEvaluatedItem.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v12.0.csproj b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v12.0.csproj index ad8f481533..9bbd04268a 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v12.0.csproj +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v12.0.csproj @@ -57,7 +57,6 @@ <ItemGroup> <Compile Include="Main.cs" /> <Compile Include="AssemblyInfo.cs" /> - <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\LocalLogger.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ILogWriter.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\IProjectBuilder.cs" /> @@ -65,6 +64,9 @@ <Compile Include="AssemblyInfo.v12.0.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ProjectBuilder.v4.0.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\BuildEngine.v4.0.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildTargetResult.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildEvaluatedItem.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v4.0.csproj b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v4.0.csproj index f29e31bd76..63a67e8f28 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v4.0.csproj +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.dotnet.v4.0.csproj @@ -45,7 +45,6 @@ <ItemGroup> <Compile Include="Main.cs" /> <Compile Include="AssemblyInfo.cs" /> - <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\LocalLogger.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ILogWriter.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\IProjectBuilder.cs" /> @@ -53,6 +52,9 @@ <Compile Include="AssemblyInfo.v4.0.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ProjectBuilder.v4.0.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\BuildEngine.v4.0.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildTargetResult.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildEvaluatedItem.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.v4.0.csproj b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.v4.0.csproj index d38044660b..cf8930ff78 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.v4.0.csproj +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild.v4.0.csproj @@ -43,7 +43,6 @@ <Compile Include="Main.cs" /> <Compile Include="AssemblyInfo.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ProjectBuilder.cs" /> - <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\LocalLogger.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ILogWriter.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\IProjectBuilder.cs" /> @@ -51,6 +50,9 @@ <Compile Include="MonoDevelop.Projects.Formats.MSBuild\IBuildEngine.cs" /> <Compile Include="MonoDevelop.Projects.Formats.MSBuild\ConsoleLogger.cs" /> <Compile Include="AssemblyInfo.v4.0.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildTargetResult.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildResult.cs" /> + <Compile Include="MonoDevelop.Projects.Formats.MSBuild\MSBuildEvaluatedItem.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.cs index f27b93dd8b..b50b65b1e7 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.cs @@ -49,7 +49,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild readonly ManualResetEvent doneEvent = new ManualResetEvent (false); readonly Dictionary<string,string> unsavedProjects = new Dictionary<string, string> (); - internal Engine Engine { get; private set; } + internal readonly Engine Engine = new Engine { DefaultToolsVersion = MSBuildConsts.Version }; public void Dispose () { @@ -60,10 +60,17 @@ namespace MonoDevelop.Projects.Formats.MSBuild get { return doneEvent; } } - public void Initialize (string slnFile, CultureInfo uiCulture) + public void SetCulture (CultureInfo uiCulture) { BuildEngine.uiCulture = uiCulture; - Engine = InitializeEngine (slnFile); + + } + + public void SetGlobalProperties (IDictionary<string, string> properties) + { + var gp = Engine.GlobalProperties; + foreach (var p in properties) + gp.SetProperty (p.Key, p.Value); } public IProjectBuilder LoadProject (string file) @@ -82,31 +89,6 @@ namespace MonoDevelop.Projects.Formats.MSBuild return null; } - static Engine InitializeEngine (string slnFile) - { - var engine = new Engine (); - engine.DefaultToolsVersion = MSBuildConsts.Version; - var gp = engine.GlobalProperties; - - //this causes build targets to behave how they should inside an IDE, instead of in a command-line process - gp.SetProperty ("BuildingInsideVisualStudio", "true"); - - //we don't have host compilers in MD, and this is set to true by some of the MS targets - //which causes it to always run the CoreCompile task if BuildingInsideVisualStudio is also - //true, because the VS in-process compiler would take care of the deps tracking - gp.SetProperty ("UseHostCompilerIfAvailable", "false"); - - if (string.IsNullOrEmpty (slnFile)) - return engine; - - gp.SetProperty ("SolutionPath", Path.GetFullPath (slnFile)); - gp.SetProperty ("SolutionName", Path.GetFileNameWithoutExtension (slnFile)); - gp.SetProperty ("SolutionFilename", Path.GetFileName (slnFile)); - gp.SetProperty ("SolutionDir", Path.GetDirectoryName (slnFile) + Path.DirectorySeparatorChar); - - return engine; - } - internal void UnloadProject (string file) { lock (unsavedProjects) diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.v4.0.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.v4.0.cs index 03d365b6f0..d184314662 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.v4.0.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/BuildEngine.v4.0.cs @@ -48,7 +48,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild readonly ManualResetEvent doneEvent = new ManualResetEvent (false);
readonly Dictionary<string, string> unsavedProjects = new Dictionary<string, string> ();
- ProjectCollection engine; + readonly ProjectCollection engine = new ProjectCollection { DefaultToolsVersion = MSBuildConsts.Version }; public void Dispose ()
{
@@ -59,13 +59,18 @@ namespace MonoDevelop.Projects.Formats.MSBuild get { return doneEvent; }
}
- public void Initialize (string solutionFile, CultureInfo uiCulture)
+ public void SetCulture (CultureInfo uiCulture) {
BuildEngine.uiCulture = uiCulture;
- engine = InitializeEngine (solutionFile);
- }
-
- public IProjectBuilder LoadProject (string file)
+ } + + public void SetGlobalProperties (IDictionary<string, string> properties) + { + foreach (var p in properties) + engine.SetGlobalProperty (p.Key, p.Value); + } + + public IProjectBuilder LoadProject (string file) {
return new ProjectBuilder (this, engine, file);
}
@@ -96,30 +101,6 @@ namespace MonoDevelop.Projects.Formats.MSBuild return null;
}
- static ProjectCollection InitializeEngine (string slnFile)
- {
- var engine = new ProjectCollection ();
- engine.DefaultToolsVersion = MSBuildConsts.Version;
-
- //this causes build targets to behave how they should inside an IDE, instead of in a command-line process
- engine.SetGlobalProperty ("BuildingInsideVisualStudio", "true");
-
- //we don't have host compilers in MD, and this is set to true by some of the MS targets
- //which causes it to always run the CoreCompile task if BuildingInsideVisualStudio is also
- //true, because the VS in-process compiler would take care of the deps tracking
- engine.SetGlobalProperty ("UseHostCompilerIfAvailable", "false");
-
- if (string.IsNullOrEmpty (slnFile))
- return engine;
-
- engine.SetGlobalProperty ("SolutionPath", Path.GetFullPath (slnFile));
- engine.SetGlobalProperty ("SolutionName", Path.GetFileNameWithoutExtension (slnFile));
- engine.SetGlobalProperty ("SolutionFilename", Path.GetFileName (slnFile));
- engine.SetGlobalProperty ("SolutionDir", Path.GetDirectoryName (slnFile) + Path.DirectorySeparatorChar);
-
- return engine;
- }
-
internal void UnloadProject (string file)
{
lock (unsavedProjects)
diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IBuildEngine.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IBuildEngine.cs index 98b06a6fea..9b25cae19b 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IBuildEngine.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IBuildEngine.cs @@ -26,12 +26,14 @@ using System; using System.Globalization; +using System.Collections.Generic; namespace MonoDevelop.Projects.Formats.MSBuild { public interface IBuildEngine: IDisposable { - void Initialize (string solutionFile, CultureInfo uiCulture); + void SetCulture (CultureInfo uiCulture); + void SetGlobalProperties (IDictionary<string, string> properties); IProjectBuilder LoadProject (string projectFile); void UnloadProject (IProjectBuilder pb); } diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IProjectBuilder.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IProjectBuilder.cs index d85aa365a2..0160085979 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IProjectBuilder.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/IProjectBuilder.cs @@ -30,11 +30,12 @@ namespace MonoDevelop.Projects.Formats.MSBuild { public interface IProjectBuilder : IDisposable { - MSBuildResult[] RunTarget (string target, ProjectConfigurationInfo[] configurations, ILogWriter logWriter, - MSBuildVerbosity verbosity); - string[] GetAssemblyReferences (ProjectConfigurationInfo[] configurations); void Refresh (); void RefreshWithContent (string projectContent); + MSBuildResult Run ( + ProjectConfigurationInfo[] configurations, ILogWriter logWriter, MSBuildVerbosity verbosity, + string[] runTargets, string[] evaluateItems, string[] evaluateProperties + ); } [Serializable] diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/LocalLogger.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/LocalLogger.cs index 4b1771de39..7d08df441e 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/LocalLogger.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/LocalLogger.cs @@ -35,7 +35,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild public class LocalLogger: Logger { IEventSource eventSource; - readonly List<MSBuildResult> results = new List<MSBuildResult> (); + readonly List<MSBuildTargetResult> results = new List<MSBuildTargetResult> (); readonly string projectFile; public LocalLogger (string projectFile) @@ -43,7 +43,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild this.projectFile = projectFile; } - public List<MSBuildResult> BuildResult { + public List<MSBuildTargetResult> BuildResult { get { return results; } } @@ -63,7 +63,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild void EventSourceWarningRaised (object sender, BuildWarningEventArgs e) { //NOTE: as of Mono 3.2.7, e.ProjectFile does not exist, so we use our projectFile variable instead - results.Add (new MSBuildResult ( + results.Add (new MSBuildTargetResult ( projectFile, true, e.Subcategory, e.Code, e.File, e.LineNumber, e.ColumnNumber, e.ColumnNumber, e.EndLineNumber, e.Message, e.HelpKeyword) @@ -73,7 +73,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild void EventSourceErrorRaised (object sender, BuildErrorEventArgs e) { //NOTE: as of Mono 3.2.7, e.ProjectFile does not exist, so we use our projectFile variable instead - results.Add (new MSBuildResult ( + results.Add (new MSBuildTargetResult ( projectFile, false, e.Subcategory, e.Code, e.File, e.LineNumber, e.ColumnNumber, e.ColumnNumber, e.EndLineNumber, e.Message, e.HelpKeyword) diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/MSBuildEvaluatedItem.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/MSBuildEvaluatedItem.cs new file mode 100644 index 0000000000..221eb11b24 --- /dev/null +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/MSBuildEvaluatedItem.cs @@ -0,0 +1,47 @@ +// +// MSBuildEvaluatedItem.cs +// +// Author: +// Michael Hutchinson <m.j.hutchinson@gmail.com> +// +// Copyright (c) 2014 Xamarin Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; + +namespace MonoDevelop.Projects.Formats.MSBuild +{ + + [Serializable] + public class MSBuildEvaluatedItem + { + public MSBuildEvaluatedItem (string name, string itemSpec) + { + Name = name; + ItemSpec = itemSpec; + Metadata = new Dictionary<string, string> (); + } + + public Dictionary<string,string> Metadata { get; private set; } + public string ItemSpec { get; private set; } + public string Name { get; private set; } + } +} diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/MSBuildResult.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/MSBuildResult.cs index 0c9af43e85..358659d42a 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/MSBuildResult.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/MSBuildResult.cs @@ -1,21 +1,21 @@ -// +// // MSBuildResult.cs -// +// // Author: -// Lluis Sanchez Gual <lluis@novell.com> -// -// Copyright (c) 2009 Novell, Inc (http://www.novell.com) -// +// Michael Hutchinson <m.j.hutchinson@gmail.com> +// +// Copyright (c) 2014 Xamarin Inc. +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,90 +25,35 @@ // THE SOFTWARE. using System; -using System.Text; +using System.Collections.Generic; namespace MonoDevelop.Projects.Formats.MSBuild { [Serializable] public class MSBuildResult { - public MSBuildResult ( - string projectFile, bool isWarning, string subcategory, string code, string file, - int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber, - string message, string helpKeyword) + readonly MSBuildTargetResult[] errors; + readonly Dictionary<string,string> properties; + readonly Dictionary<string,List<MSBuildEvaluatedItem>> items; + + public MSBuildResult (MSBuildTargetResult[] errors) { - ProjectFile = projectFile; - IsWarning = isWarning; - Subcategory = subcategory; - Code = code; - File = file; - LineNumber = lineNumber; - ColumnNumber = columnNumber; - EndLineNumber = endLineNumber; - EndColumnNumber = endColumnNumber; - Message = message; - HelpKeyword = helpKeyword; + this.errors = errors; + this.properties = new Dictionary<string,string> (); + this.items = new Dictionary<string,List<MSBuildEvaluatedItem>> (); } - - public string ProjectFile { get; set; } - public bool IsWarning { get; set; } - public string Subcategory { get; set; } - public string Code { get; set; } - public string File { get; set; } - public int LineNumber { get; set; } - public int ColumnNumber { get; set; } - public int EndLineNumber { get; set; } - public int EndColumnNumber { get; set; } - public string Message { get; set; } - public string HelpKeyword { get; set; } - public override string ToString () - { - var sb = new StringBuilder (); - if (!string.IsNullOrEmpty (File)) { - sb.Append (File); - if (LineNumber > 0) { - //(line) - sb.Append ("("); - sb.Append (LineNumber); - if (ColumnNumber > 0) { - //(line,col) - sb.Append (","); - sb.Append (ColumnNumber); - if (EndColumnNumber > 0) { - if (EndLineNumber > 0) { - //(line,col,line,col) - sb.Append (","); - sb.Append (EndLineNumber); - sb.Append (","); - sb.Append (EndColumnNumber); - } else { - //(line,col-col) - sb.Append ("-"); - sb.Append (EndColumnNumber); - } - } - } else if (EndLineNumber > 0) { - //(line-line) - sb.Append ("-"); - sb.Append (EndLineNumber); - } - sb.Append (")"); - } - sb.Append (": "); - } - if (!string.IsNullOrEmpty (Subcategory)) { - sb.Append (Subcategory); - sb.Append (" "); - } - sb.Append (IsWarning ? "warning" : "error"); - if (!string.IsNullOrEmpty (Code)) { - sb.Append (" "); - sb.Append (Code); - } - sb.Append (": "); - sb.Append (Message); - return sb.ToString (); + public MSBuildTargetResult[] Errors { + get { return errors; } + } + + public Dictionary<string,List<MSBuildEvaluatedItem>> Items { + get { return items; } + } + + public Dictionary<string, string> Properties { + get { return properties; } } } + } diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/MSBuildTargetResult.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/MSBuildTargetResult.cs new file mode 100644 index 0000000000..78115749b3 --- /dev/null +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/MSBuildTargetResult.cs @@ -0,0 +1,114 @@ +// +// MSBuildTargetResult.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Text; + +namespace MonoDevelop.Projects.Formats.MSBuild +{ + [Serializable] + public class MSBuildTargetResult + { + public MSBuildTargetResult ( + string projectFile, bool isWarning, string subcategory, string code, string file, + int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber, + string message, string helpKeyword) + { + ProjectFile = projectFile; + IsWarning = isWarning; + Subcategory = subcategory; + Code = code; + File = file; + LineNumber = lineNumber; + ColumnNumber = columnNumber; + EndLineNumber = endLineNumber; + EndColumnNumber = endColumnNumber; + Message = message; + HelpKeyword = helpKeyword; + } + + public string ProjectFile { get; set; } + public bool IsWarning { get; set; } + public string Subcategory { get; set; } + public string Code { get; set; } + public string File { get; set; } + public int LineNumber { get; set; } + public int ColumnNumber { get; set; } + public int EndLineNumber { get; set; } + public int EndColumnNumber { get; set; } + public string Message { get; set; } + public string HelpKeyword { get; set; } + + public override string ToString () + { + var sb = new StringBuilder (); + if (!string.IsNullOrEmpty (File)) { + sb.Append (File); + if (LineNumber > 0) { + //(line) + sb.Append ("("); + sb.Append (LineNumber); + if (ColumnNumber > 0) { + //(line,col) + sb.Append (","); + sb.Append (ColumnNumber); + if (EndColumnNumber > 0) { + if (EndLineNumber > 0) { + //(line,col,line,col) + sb.Append (","); + sb.Append (EndLineNumber); + sb.Append (","); + sb.Append (EndColumnNumber); + } else { + //(line,col-col) + sb.Append ("-"); + sb.Append (EndColumnNumber); + } + } + } else if (EndLineNumber > 0) { + //(line-line) + sb.Append ("-"); + sb.Append (EndLineNumber); + } + sb.Append (")"); + } + sb.Append (": "); + } + if (!string.IsNullOrEmpty (Subcategory)) { + sb.Append (Subcategory); + sb.Append (" "); + } + sb.Append (IsWarning ? "warning" : "error"); + if (!string.IsNullOrEmpty (Code)) { + sb.Append (" "); + sb.Append (Code); + } + sb.Append (": "); + sb.Append (Message); + return sb.ToString (); + } + } +} diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.cs index d35f408d88..f72c2205ce 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.cs @@ -33,6 +33,9 @@ using System.Collections; using System.Reflection; //this is the builder for the deprecated build engine API +using System.Linq; + + #pragma warning disable 618 namespace MonoDevelop.Projects.Formats.MSBuild @@ -72,36 +75,63 @@ namespace MonoDevelop.Projects.Formats.MSBuild if (currentLogWriter != null) currentLogWriter.WriteLine (txt); } - - public MSBuildResult[] RunTarget (string target, ProjectConfigurationInfo[] configurations, ILogWriter logWriter, - MSBuildVerbosity verbosity) + + //HACK: Mono does not implement 3.5 CustomMetadataNames API + FieldInfo evaluatedMetadataField = typeof(BuildItem).GetField ("evaluatedMetadata", BindingFlags.NonPublic | BindingFlags.Instance); + + public MSBuildResult Run ( + ProjectConfigurationInfo[] configurations, ILogWriter logWriter, MSBuildVerbosity verbosity, + string[] runTargets, string[] evaluateItems, string[] evaluateProperties) { - MSBuildResult[] result = null;
- BuildEngine.RunSTA (delegate
- {
+ MSBuildResult result = null; + BuildEngine.RunSTA (delegate { try { var project = SetupProject (configurations);
currentLogWriter = logWriter;
+ buildEngine.Engine.UnregisterAllLoggers (); + var logger = new LocalLogger (file); - buildEngine.Engine.UnregisterAllLoggers ();
buildEngine.Engine.RegisterLogger (logger); - buildEngine.Engine.RegisterLogger (consoleLogger);
+ if (logWriter != null) { + buildEngine.Engine.RegisterLogger (consoleLogger); + consoleLogger.Verbosity = GetVerbosity (verbosity); + } + + if (runTargets != null && runTargets.Length > 0) { + // We are using this BuildProject overload and the BuildSettings.None argument as a workaround to + // an xbuild bug which causes references to not be resolved after the project has been built once. + buildEngine.Engine.BuildProject (project, runTargets, new Hashtable (), BuildSettings.None); + } + + result = new MSBuildResult (logger.BuildResult.ToArray ()); - consoleLogger.Verbosity = GetVerbosity (verbosity); + if (evaluateProperties != null) { + foreach (var name in evaluateProperties) + result.Properties [name] = project.GetEvaluatedProperty (name); + } - // We are using this BuildProject overload and the BuildSettings.None argument as a workaround to - // an xbuild bug which causes references to not be resolved after the project has been built once. - buildEngine.Engine.BuildProject (project, new [] { target }, new Hashtable (), BuildSettings.None); -
- result = logger.BuildResult.ToArray ();
+ if (evaluateItems != null) { + foreach (var name in evaluateItems) { + BuildItemGroup grp = project.GetEvaluatedItemsByName (name); + var list = new List<MSBuildEvaluatedItem> (); + foreach (BuildItem item in grp) { + var evItem = new MSBuildEvaluatedItem (name, UnescapeString (item.FinalItemSpec)); + foreach (DictionaryEntry de in (IDictionary) evaluatedMetadataField.GetValue (item)) { + evItem.Metadata [(string)de.Key] = UnescapeString ((string)de.Value); + } + list.Add (evItem); + } + result.Items[name] = list; + } + } } catch (InvalidProjectFileException ex) { - var r = new MSBuildResult ( + var r = new MSBuildTargetResult ( file, false, ex.ErrorSubcategory, ex.ErrorCode, ex.ProjectFile, ex.LineNumber, ex.ColumnNumber, ex.EndLineNumber, ex.EndColumnNumber, ex.BaseMessage, ex.HelpKeyword); logWriter.WriteLine (r.ToString ()); - result = new [] { r }; + result = new MSBuildResult (new [] { r }); } finally {
currentLogWriter = null;
}
@@ -124,26 +154,6 @@ namespace MonoDevelop.Projects.Formats.MSBuild return LoggerVerbosity.Diagnostic; } } - - public string[] GetAssemblyReferences (ProjectConfigurationInfo[] configurations) - { - string[] refsArray = null; - - BuildEngine.RunSTA (delegate - { - var project = SetupProject (configurations); - - // We are using this BuildProject overload and the BuildSettings.None argument as a workaround to - // an xbuild bug which causes references to not be resolved after the project has been built once. - buildEngine.Engine.BuildProject (project, new [] { "ResolveAssemblyReferences" }, new Hashtable (), BuildSettings.None); - BuildItemGroup grp = project.GetEvaluatedItemsByName ("ReferencePath"); - var refs = new List<string> (); - foreach (BuildItem item in grp) - refs.Add (UnescapeString (item.Include)); - refsArray = refs.ToArray (); - }); - return refsArray; - } Project SetupProject (ProjectConfigurationInfo[] configurations) { diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs index ef907cb758..066574537f 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs @@ -74,34 +74,60 @@ namespace MonoDevelop.Projects.Formats.MSBuild if (currentLogWriter != null)
currentLogWriter.WriteLine (txt);
}
-
- public MSBuildResult[] RunTarget (string target, ProjectConfigurationInfo[] configurations, ILogWriter logWriter,
- MSBuildVerbosity verbosity)
+ + public MSBuildResult Run ( + ProjectConfigurationInfo[] configurations, ILogWriter logWriter, MSBuildVerbosity verbosity, + string[] runTargets, string[] evaluateItems, string[] evaluateProperties) {
- MSBuildResult[] result = null;
- BuildEngine.RunSTA (delegate
- {
+ MSBuildResult result = null; + BuildEngine.RunSTA (delegate { try {
var project = SetupProject (configurations);
currentLogWriter = logWriter;
- var logger = new LocalLogger (file);
engine.UnregisterAllLoggers ();
+ + var logger = new LocalLogger (file); engine.RegisterLogger (logger);
- engine.RegisterLogger (consoleLogger);
+ if (logWriter != null) { + engine.RegisterLogger (consoleLogger); + consoleLogger.Verbosity = GetVerbosity (verbosity); + } + + if (runTargets != null && runTargets.Length > 0) { + project.Build (runTargets); + } + + result = new MSBuildResult (logger.BuildResult.ToArray ()); + + if (evaluateProperties != null) { + foreach (var name in evaluateProperties) { + var prop = project.GetProperty (name); + result.Properties [name] = prop != null? prop.EvaluatedValue : null; + } + } - consoleLogger.Verbosity = GetVerbosity (verbosity);
-
- project.Build (target);
-
- result = logger.BuildResult.ToArray ();
+ if (evaluateItems != null) { + foreach (var name in evaluateItems) { + var grp = project.GetItems (name); + var list = new List<MSBuildEvaluatedItem> (); + foreach (var item in grp) { + var evItem = new MSBuildEvaluatedItem (name, UnescapeString (item.EvaluatedInclude)); + foreach (var m in item.DirectMetadata) { + evItem.Metadata [m.Name] = UnescapeString (m.EvaluatedValue); + } + list.Add (evItem); + } + result.Items[name] = list; + } + } } catch (Microsoft.Build.Exceptions.InvalidProjectFileException ex) {
- var r = new MSBuildResult (
- file, false, ex.ErrorSubcategory, ex.ErrorCode, ex.ProjectFile,
- ex.LineNumber, ex.ColumnNumber, ex.EndLineNumber, ex.EndColumnNumber,
- ex.BaseMessage, ex.HelpKeyword);
- logWriter.WriteLine (r.ToString ());
- result = new [] { r };
+ var r = new MSBuildTargetResult ( + file, false, ex.ErrorSubcategory, ex.ErrorCode, ex.ProjectFile, + ex.LineNumber, ex.ColumnNumber, ex.EndLineNumber, ex.EndColumnNumber, + ex.BaseMessage, ex.HelpKeyword); + logWriter.WriteLine (r.ToString ()); + result = new MSBuildResult (new [] { r }); } finally {
currentLogWriter = null;
}
|