diff options
author | Lluis Sanchez <llsan@microsoft.com> | 2017-10-10 19:25:56 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-10 19:25:56 +0300 |
commit | 0a9c6a5b6bb0084c0c7dfb03462d22901bfd5657 (patch) | |
tree | 7cfbaa1c64add84d3760edbbb0f07ee7a1b61d3d | |
parent | 8b9756cce474fd5d896c3101c78cf354b845b3ec (diff) | |
parent | 6ed7d72a04916ca35110186bfec772b97318303b (diff) |
Merge pull request #3159 from mono/d15-5-support-xamarin-forms-2.4
[d15-5] Support xamarin forms 2.4
19 files changed, 385 insertions, 21 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs index 8d47e18ad6..cac30b3bd4 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs @@ -89,6 +89,9 @@ namespace MonoDevelop.Projects.MSBuild public Regex DirectoryExcludeRegex; public Regex RemoveRegex; public bool Condition; + + public List<GlobInfo> Updates; + public Regex UpdateRegex; } #region implemented abstract members of MSBuildEngine @@ -223,10 +226,6 @@ namespace MonoDevelop.Projects.MSBuild list.Insert (index++, new MSBuildImport { Sdk = sdkPath, Project = "Sdk.props" }); list.Add (new MSBuildImport { Sdk = sdkPath, Project = "Sdk.targets" }); } - var nugetPropsPath = $"$(BaseIntermediateOutputPath)\\{pi.Project.FileName.FileName}.nuget.g.props"; - var nugetTargetsPath = $"$(BaseIntermediateOutputPath)\\{pi.Project.FileName.FileName}.nuget.g.targets"; - list.Insert (index, new MSBuildImport { Project = nugetPropsPath, Condition = $"Exists('{nugetPropsPath}')" }); - list.Add (new MSBuildImport { Project = nugetTargetsPath, Condition = $"Exists('{nugetTargetsPath}')" }); objects = list; } @@ -321,11 +320,12 @@ namespace MonoDevelop.Projects.MSBuild var it = CreateEvaluatedItem (context, project, project.Project, item, update); + var updateContext = new MSBuildEvaluationContext (context); if (update.IndexOf (';') == -1) - UpdateItem (project, item, update, trueCond, it); + UpdateItem (project, updateContext, item, update, trueCond, it); else { foreach (var inc in update.Split (new [] { ';' }, StringSplitOptions.RemoveEmptyEntries)) - UpdateItem (project, item, inc, trueCond, it); + UpdateItem (project, updateContext, item, inc, trueCond, it); } } else if (!string.IsNullOrEmpty (item.Remove)) { var remove = context.EvaluateString (item.Remove); @@ -362,31 +362,55 @@ namespace MonoDevelop.Projects.MSBuild } } - static void UpdateItem (ProjectInfo project, MSBuildItem item, string update, bool trueCond, MSBuildItemEvaluated it) + void UpdateItem (ProjectInfo project, MSBuildEvaluationContext context, MSBuildItem item, string update, bool trueCond, MSBuildItemEvaluated it) { if (IsWildcardInclude (update)) { + var regex = new Regex (ExcludeToRegex (update)); + AddUpdateToGlobInclude (project, item, update, regex); var rootProject = project.GetRootMSBuildProject (); - foreach (var f in GetIncludesForWildcardFilePath (rootProject, update)) - UpdateEvaluatedItemInAllProjects (project, item, f, trueCond, it); + foreach (var f in GetIncludesForWildcardFilePath (rootProject, update)) { + var fileName = rootProject.BaseDirectory.Combine (f); + context.SetItemContext (update, fileName, null); + UpdateEvaluatedItemInAllProjects (project, context, item, f, trueCond, it); + } } else - UpdateEvaluatedItemInAllProjects (project, item, update, trueCond, it); + UpdateEvaluatedItemInAllProjects (project, null, item, update, trueCond, it); } - static void UpdateEvaluatedItemInAllProjects (ProjectInfo project, MSBuildItem item, string include, bool trueCond, MSBuildItemEvaluated it) + void AddUpdateToGlobInclude (ProjectInfo project, MSBuildItem item, string update, Regex updateRegex) { do { - UpdateEvaluatedItem (project, item, include, trueCond, it); + foreach (var globInclude in project.GlobIncludes) { + if (globInclude.Item.Name != item.Name) + continue; + + if (globInclude.Updates == null) + globInclude.Updates = new List<GlobInfo> (); + globInclude.Updates.Add (new GlobInfo { Include = update, Item = item, UpdateRegex = updateRegex }); + } project = project.Parent; } while (project != null); } - static void UpdateEvaluatedItem (ProjectInfo project, MSBuildItem item, string include, bool trueCond, MSBuildItemEvaluated it) + void UpdateEvaluatedItemInAllProjects (ProjectInfo project, MSBuildEvaluationContext context, MSBuildItem item, string include, bool trueCond, MSBuildItemEvaluated it) + { + do { + UpdateEvaluatedItem (project, context, item, include, trueCond, it); + project = project.Parent; + } while (project != null); + } + + void UpdateEvaluatedItem (ProjectInfo project, MSBuildEvaluationContext context, MSBuildItem item, string include, bool trueCond, MSBuildItemEvaluated it) { if (trueCond) { foreach (var item2 in project.EvaluatedItems) { if (item2.Name == item.Name && item2.Include == include) { - foreach (var evaluatedProp in ((MSBuildPropertyGroupEvaluated)it.Metadata).GetProperties ()) { - ((MSBuildPropertyGroupEvaluated)item2.Metadata).SetProperty (evaluatedProp.Name, evaluatedProp); + if (context != null) { + UpdateProperties (project, context, item, item2); + } else { + foreach (var evaluatedProp in ((MSBuildPropertyGroupEvaluated)it.Metadata).GetProperties ()) { + ((MSBuildPropertyGroupEvaluated)item2.Metadata).SetProperty (evaluatedProp.Name, evaluatedProp); + } } item2.AddSourceItem (item); } @@ -395,14 +419,39 @@ namespace MonoDevelop.Projects.MSBuild foreach (var item2 in project.EvaluatedItemsIgnoringCondition) { if (item2.Name == item.Name && item2.Include == include) { - foreach (var evaluatedProp in ((MSBuildPropertyGroupEvaluated)it.Metadata).GetProperties ()) { - ((MSBuildPropertyGroupEvaluated)item2.Metadata).SetProperty (evaluatedProp.Name, evaluatedProp); + if (context != null) { + UpdateProperties (project, context, item, item2); + } else { + foreach (var evaluatedProp in ((MSBuildPropertyGroupEvaluated)it.Metadata).GetProperties ()) { + ((MSBuildPropertyGroupEvaluated)item2.Metadata).SetProperty (evaluatedProp.Name, evaluatedProp); + } } item2.AddSourceItem (item); } } } + void UpdateProperties (ProjectInfo project, MSBuildEvaluationContext context, MSBuildItem item, MSBuildItemEvaluated evaluatedItem) + { + var rootProject = project.GetRootMSBuildProject (); + + foreach (var p in item.Metadata.GetProperties ()) { + if (string.IsNullOrEmpty (p.Condition) || SafeParseAndEvaluate (project, context, p.Condition, true)) { + string evaluatedValue = context.EvaluateString (p.Value); + string unevaluatedValue = p.Value; + + if (rootProject != item.ParentProject) { + // Use the same evaluated value as the property value so expanded metadata properties from a wildcard + // item are not saved in the project file. + unevaluatedValue = evaluatedValue; + } + + var evaluatedProp = new MSBuildPropertyEvaluated (project.Project, p.Name, unevaluatedValue, evaluatedValue) { Condition = p.Condition }; + ((MSBuildPropertyGroupEvaluated)evaluatedItem.Metadata).SetProperty (evaluatedProp.Name, evaluatedProp); + } + } + } + /// <summary> /// Only supports exact match when looking for a glob. /// </summary> @@ -1341,6 +1390,18 @@ namespace MonoDevelop.Projects.MSBuild } } + internal override IEnumerable<MSBuildItem> FindUpdateGlobItemsIncludingFile (object projectInstance, string include, MSBuildItem globItem) + { + var pi = (ProjectInfo)projectInstance; + foreach (var g in pi.GlobIncludes.Where (g => g.Condition && g.Item == globItem && g.Updates != null)) { + foreach (var update in g.Updates) { + if (update.UpdateRegex.IsMatch (include)) { + yield return update.Item; + } + } + } + } + bool IsIncludedInGlob (string globInclude, string basePath, FilePath file) { var subpath = SplitWildcardFilePath (globInclude); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngine.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngine.cs index b59600cb83..2868e9ace2 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngine.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngine.cs @@ -103,6 +103,8 @@ namespace MonoDevelop.Projects.MSBuild public abstract ConditionedPropertyCollection GetConditionedProperties (object projectInstance); public abstract IEnumerable<MSBuildItem> FindGlobItemsIncludingFile (object projectInstance, string include); + + internal abstract IEnumerable<MSBuildItem> FindUpdateGlobItemsIncludingFile (object projectInstance, string include, MSBuildItem globItem); } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngineV12.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngineV12.cs index 4295ed82cb..0b83d3b91c 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngineV12.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngineV12.cs @@ -194,6 +194,11 @@ namespace MonoDevelop.Projects.MSBuild { throw new NotImplementedException (); } + + internal override IEnumerable<MSBuildItem> FindUpdateGlobItemsIncludingFile (object projectInstance, string include, MSBuildItem globItem) + { + throw new NotImplementedException (); + } } #if !WINDOWS diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildImport.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildImport.cs index 58b26be1e9..d2efb3d97d 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildImport.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildImport.cs @@ -126,6 +126,11 @@ namespace MonoDevelop.Projects.MSBuild writer.WriteAttributeString ("Condition", cond); writer.WriteEndElement (); } + + public override string ToString () + { + return string.Format ("<Import Project='{0}'>", Project); + } } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs index 8ea842408d..e211f5f2f0 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs @@ -683,6 +683,11 @@ namespace MonoDevelop.Projects.MSBuild return mainProjectInstance.FindGlobItemsIncludingFile (include); } + internal IEnumerable<MSBuildItem> FindUpdateGlobItemsIncludingFile (string include, MSBuildItem globItem) + { + return mainProjectInstance.FindUpdateGlobItemsIncludingFile (include, globItem); + } + public MSBuildPropertyGroup GetGlobalPropertyGroup () { return PropertyGroups.FirstOrDefault (g => g.Condition.Length == 0); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs index b7fe15428d..cdebefa689 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs @@ -231,6 +231,11 @@ namespace MonoDevelop.Projects.MSBuild { return engine?.FindGlobItemsIncludingFile (projectInstance, include); } + + internal IEnumerable<MSBuildItem> FindUpdateGlobItemsIncludingFile (string include, MSBuildItem globItem) + { + return engine?.FindUpdateGlobItemsIncludingFile (projectInstance, include, globItem); + } } class MSBuildProjectInstanceInfo diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs index 3e5c6d0d25..bc418ac74e 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs @@ -1371,6 +1371,10 @@ namespace MonoDevelop.Projects.MSBuild var vcTargetsPath = Path.Combine (extensionsPath, "Common7", "IDE", "VC", "VCTargets"); SetMSBuildConfigProperty (toolset, "VCTargetsPath", vcTargetsPath); + } else { + var path = MSBuildProjectService.GetProjectImportSearchPaths (runtime, false).FirstOrDefault (p => p.Property == "MSBuildSDKsPath"); + if (path != null) + SetMSBuildConfigProperty (toolset, path.Property, path.Path); } var projectImportSearchPaths = doc.Root.Elements ("msbuildToolsets").FirstOrDefault ()?.Elements ("toolset")?.FirstOrDefault ()?.Element ("projectImportSearchPaths"); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildTarget.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildTarget.cs index 664033f769..066b1d8cf3 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildTarget.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildTarget.cs @@ -229,6 +229,11 @@ namespace MonoDevelop.Projects.MSBuild task.RemoveIndent (); ChildNodes = ChildNodes.Remove (task); } + + public override string ToString () + { + return string.Format ("<Target Name='{0}'>", Name); + } } public interface IMSBuildTargetEvaluated diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs index b5232de2e1..41547914c2 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs @@ -3408,8 +3408,9 @@ namespace MonoDevelop.Projects var globItem = matchingGlobItems.FirstOrDefault (gi => gi.Name == item.ItemName); if (globItem != null) { + var updateGlobItems = msproject.FindUpdateGlobItemsIncludingFile (item.Include, globItem).ToList (); // Globbing magic can only be done if there is no metadata (for now) - if (globItem.Metadata.GetProperties ().Count () == 0) { + if (globItem.Metadata.GetProperties ().Count () == 0 && !updateGlobItems.Any ()) { var it = new MSBuildItem (item.ItemName); item.Write (this, it); if (it.Metadata.GetProperties ().Count () == 0) @@ -3439,6 +3440,11 @@ namespace MonoDevelop.Projects buildItem = new MSBuildItem (item.ItemName) { Update = item.Include }; msproject.AddItem (buildItem); } + } else if (updateGlobItems.Any ()) { + // Multiple update items not supported yet. + buildItem = updateGlobItems [0]; + } else { + buildItem = globItem; } } else if (item.IsFromWildcardItem && item.ItemName != item.WildcardItem.Name) { include = item.Include; @@ -3447,8 +3453,10 @@ namespace MonoDevelop.Projects } // Add remove item if file is included in a glob with a different MSBuild item type. + // But do not add the remove item if the item is already removed with another glob. var removeGlobItem = matchingGlobItems.FirstOrDefault (gi => gi.Name != item.ItemName); - if (removeGlobItem != null) { + var alreadyRemovedGlobItem = matchingGlobItems.FirstOrDefault (gi => gi.Name == item.ItemName); + if (removeGlobItem != null && alreadyRemovedGlobItem == null) { // Do not add the remove item if one already exists or if the Items contains // an include for the item. if (!msproject.GetAllItems ().Any (it => it.Name == removeGlobItem.Name && it.Remove == item.Include) && diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SingleFileDescriptionTemplate.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SingleFileDescriptionTemplate.cs index 6339e56d3f..250c2b496f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SingleFileDescriptionTemplate.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SingleFileDescriptionTemplate.cs @@ -59,6 +59,7 @@ namespace MonoDevelop.Ide.Templates string buildAction; string customTool; string customToolNamespace; + string subType; List<string> references = new List<string> (); public override void Load (XmlElement filenode, FilePath baseDirectory) @@ -70,6 +71,7 @@ namespace MonoDevelop.Ide.Templates dependsOn = filenode.GetAttribute ("DependsOn"); customTool = filenode.GetAttribute ("CustomTool"); customToolNamespace = filenode.GetAttribute ("CustomToolNamespace"); + subType = filenode.GetAttribute ("SubType"); buildAction = BuildAction.Compile; buildAction = filenode.GetAttribute ("BuildAction"); @@ -136,7 +138,10 @@ namespace MonoDevelop.Ide.Templates var model = CombinedTagModel.GetTagModel (ProjectTagModel, policyParent, project, language, name, generatedFile); projectFile.CustomToolNamespace = StringParserService.Parse (customToolNamespace, model); } - + + if (!string.IsNullOrEmpty (subType)) + projectFile.ContentType = subType; + DotNetProject netProject = project as DotNetProject; if (netProject != null) { // Add required references diff --git a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/DotNetCoreProjectTests.cs b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/DotNetCoreProjectTests.cs index e33deb19a2..9969e69db7 100644 --- a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/DotNetCoreProjectTests.cs +++ b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/DotNetCoreProjectTests.cs @@ -26,6 +26,7 @@ using System; using System.IO; +using System.Diagnostics; using System.Xml; using NUnit.Framework; using UnitTests; @@ -102,6 +103,13 @@ namespace MonoDevelop.Projects } } + /// <summary> + /// ProjectName.nuget.g.props and ProjectName.nuget.g.targets files are imported by Microsoft.Common.props + /// and Microsoft.Common.targets that are included with Mono: + /// + /// /Library/Frameworks/Mono.framework/Versions/5.4.0/lib/mono/xbuild/15.0/Microsoft.Common.props + /// /Library/Frameworks/Mono.framework/Versions/5.4.0/lib/mono/msbuild/15.0/bin/Microsoft.Common.targets + /// </summary> [Test] public async Task GeneratedNuGetMSBuildFilesAreImportedWithDotNetCoreProject () { @@ -277,5 +285,81 @@ namespace MonoDevelop.Projects sol.Dispose (); } + + /// <summary> + /// Tests that metadata from the imported file globs for the Compile update items is not saved + /// in the main project file. The DependentUpon property was being saved with the evaluated + /// filename. + /// + /// Compile Update="**\*.xaml$(DefaultLanguageSourceExtension)" DependentUpon="%(Filename)" SubType="Code" + /// </summary> + [Test] + public async Task SaveNetStandardProjectWithXamarinFormsVersion24PackageReference () + { + FilePath solFile = Util.GetSampleProject ("NetStandardXamarinForms", "NetStandardXamarinForms.sln"); + + var process = Process.Start ("msbuild", $"/t:Restore {solFile}"); + Assert.IsTrue (process.WaitForExit (120000), "Timeout restoring NuGet packages."); + Assert.AreEqual (0, process.ExitCode); + + var sol = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solFile); + var p = (Project)sol.Items [0]; + string expectedProjectXml = File.ReadAllText (p.FileName); + + var xamlCSharpFile = p.Files.Single (fi => fi.FilePath.FileName == "MyPage.xaml.cs"); + var xamlFile = p.Files.Single (fi => fi.FilePath.FileName == "MyPage.xaml"); + + Assert.AreEqual (xamlFile, xamlCSharpFile.DependsOnFile); + + // Ensure the expanded %(FileName) does not get added to the main project on saving. + await p.SaveAsync (Util.GetMonitor ()); + + string projectXml = File.ReadAllText (p.FileName); + Assert.AreEqual (expectedProjectXml, projectXml); + } + + [Test] + public async Task AddFiles_NetStandardProjectWithXamarinFormsVersion24PackageReference () + { + FilePath solFile = Util.GetSampleProject ("NetStandardXamarinForms", "NetStandardXamarinForms.sln"); + + var process = Process.Start ("msbuild", $"/t:Restore {solFile}"); + Assert.IsTrue (process.WaitForExit (120000), "Timeout restoring NuGet packages."); + Assert.AreEqual (0, process.ExitCode); + + var sol = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solFile); + var p = (Project)sol.Items [0]; + string expectedProjectXml = File.ReadAllText (p.FileName); + + // Add new xaml files. + var xamlFileName1 = p.BaseDirectory.Combine ("MyView1.xaml"); + File.WriteAllText (xamlFileName1, "xaml1"); + var xamlCSharpFileName = p.BaseDirectory.Combine ("MyView1.xaml.cs"); + File.WriteAllText (xamlCSharpFileName, "csharpxaml"); + + // Xaml file with Generator and Subtype set to match that defined in the glob. + var xamlFile1 = new ProjectFile (xamlFileName1, BuildAction.EmbeddedResource); + xamlFile1.Generator = "MSBuild:UpdateDesignTimeXaml"; + xamlFile1.ContentType = "Designer"; + p.Files.Add (xamlFile1); + + var xamlCSharpFile = p.AddFile (xamlCSharpFileName); + xamlCSharpFile.DependsOn = "MyView1.xaml"; + + // The project file should be unchanged after saving. + await p.SaveAsync (Util.GetMonitor ()); + + string projectXml = File.ReadAllText (p.FileName); + Assert.AreEqual (expectedProjectXml, projectXml); + + // Save again. A second save was adding an include for the .xaml file whilst + // the first save was not. + await p.SaveAsync (Util.GetMonitor ()); + + projectXml = File.ReadAllText (p.FileName); + Assert.AreEqual (expectedProjectXml, projectXml); + + sol.Dispose (); + } } } diff --git a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/MSBuildGlobTests.cs b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/MSBuildGlobTests.cs index 1649187010..9ceb7ad2c7 100644 --- a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/MSBuildGlobTests.cs +++ b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/MSBuildGlobTests.cs @@ -918,6 +918,92 @@ namespace MonoDevelop.Projects } } + /// <summary> + /// Tests that the %(FileName) metadata is correctly applied to a file from a Update glob. + /// + /// Compile Update="**\*.xaml.cs" DependentUpon="%(Filename)" + /// </summary> + [Test] + public async Task DependentUponUsingFileNameMetadataProperty () + { + var fn = new CustomItemNode<SupportImportedProjectFilesProjectExtension> (); + WorkspaceObject.RegisterCustomExtension (fn); + + try { + FilePath projFile = Util.GetSampleProject ("msbuild-glob-tests", "glob-import-metadata-prop.csproj"); + string expectedProjectXml = File.ReadAllText (projFile); + + var xamlCSharpFileName = projFile.ParentDirectory.Combine ("test.xaml.cs"); + File.WriteAllText (xamlCSharpFileName, "csharp"); + var xamlFileName = projFile.ParentDirectory.Combine ("test.xaml"); + File.WriteAllText (xamlFileName, "xaml"); + var p = (DotNetProject)await Services.ProjectService.ReadSolutionItem (Util.GetMonitor (), projFile); + p.UseAdvancedGlobSupport = true; + + var xamlCSharpFile = p.Files.Single (fi => fi.FilePath.FileName == "test.xaml.cs"); + var xamlFile = p.Files.Single (fi => fi.FilePath.FileName == "test.xaml"); + + Assert.AreEqual (xamlFileName.ToString (), xamlCSharpFile.DependsOn); + Assert.AreEqual (xamlCSharpFile.DependsOnFile, xamlFile); + + // Ensure the expanded %(FileName) does not get added to the main project on saving. + await p.SaveAsync (Util.GetMonitor ()); + + string projectXml = File.ReadAllText (p.FileName); + Assert.AreEqual (expectedProjectXml, projectXml); + + p.Dispose (); + } finally { + WorkspaceObject.UnregisterCustomExtension (fn); + } + } + + [Test] + public async Task AddFile_WildCardHasMetadataProperties () + { + var fn = new CustomItemNode<SupportImportedProjectFilesProjectExtension> (); + WorkspaceObject.RegisterCustomExtension (fn); + + try { + FilePath projFile = Util.GetSampleProject ("msbuild-glob-tests", "glob-import-metadata-prop.csproj"); + string expectedProjectXml = File.ReadAllText (projFile); + + var p = (DotNetProject)await Services.ProjectService.ReadSolutionItem (Util.GetMonitor (), projFile); + p.UseAdvancedGlobSupport = true; + + var xamlFileName1 = projFile.ParentDirectory.Combine ("MyView1.xaml"); + File.WriteAllText (xamlFileName1, "xaml1"); + var xamlCSharpFileName = projFile.ParentDirectory.Combine ("MyView1.xaml.cs"); + File.WriteAllText (xamlCSharpFileName, "csharpxaml"); + + // Xaml file with Generator and Subtype set to match that defined in the glob. + var xamlFile1 = new ProjectFile (xamlFileName1, BuildAction.EmbeddedResource); + xamlFile1.Generator = "MSBuild:UpdateDesignTimeXaml"; + xamlFile1.ContentType = "Designer"; + p.Files.Add (xamlFile1); + + var xamlCSharpFile = p.AddFile (xamlCSharpFileName); + xamlCSharpFile.DependsOn = "MyView1.xaml"; + + // Ensure no items are added to the project on saving. + await p.SaveAsync (Util.GetMonitor ()); + + string projectXml = File.ReadAllText (p.FileName); + Assert.AreEqual (expectedProjectXml, projectXml); + + // Save again. A second save was adding an include for the .xaml file whilst + // the first save was not. + await p.SaveAsync (Util.GetMonitor ()); + + projectXml = File.ReadAllText (p.FileName); + Assert.AreEqual (expectedProjectXml, projectXml); + + p.Dispose (); + } finally { + WorkspaceObject.UnregisterCustomExtension (fn); + } + } + class SupportImportedProjectFilesProjectExtension : DotNetProjectExtension { internal protected override bool OnGetSupportsImportedItem (IMSBuildItemEvaluated buildItem) diff --git a/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms.sln b/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms.sln new file mode 100644 index 0000000000..06492ca7e2 --- /dev/null +++ b/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms.sln @@ -0,0 +1,17 @@ +
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetStandardXamarinForms", "NetStandardXamarinForms\NetStandardXamarinForms.csproj", "{B32D4C8C-809E-4AD8-A71B-196D206AB0A4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B32D4C8C-809E-4AD8-A71B-196D206AB0A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B32D4C8C-809E-4AD8-A71B-196D206AB0A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B32D4C8C-809E-4AD8-A71B-196D206AB0A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B32D4C8C-809E-4AD8-A71B-196D206AB0A4}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms/MyPage.xaml b/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms/MyPage.xaml new file mode 100644 index 0000000000..b64fdc022c --- /dev/null +++ b/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms/MyPage.xaml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NetStandardXamarinForms.MyPage"> + <ContentPage.Content> + </ContentPage.Content> +</ContentPage> diff --git a/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms/MyPage.xaml.cs b/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms/MyPage.xaml.cs new file mode 100644 index 0000000000..c1d2145eb9 --- /dev/null +++ b/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms/MyPage.xaml.cs @@ -0,0 +1,13 @@ + +using Xamarin.Forms; + +namespace NetStandardXamarinForms +{ + public partial class MyPage : ContentPage + { + public MyPage() + { + InitializeComponent(); + } + } +} diff --git a/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms/NetStandardXamarinForms.csproj b/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms/NetStandardXamarinForms.csproj new file mode 100644 index 0000000000..20cac4df7a --- /dev/null +++ b/main/tests/test-projects/NetStandardXamarinForms/NetStandardXamarinForms/NetStandardXamarinForms.csproj @@ -0,0 +1,10 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>netstandard1.0</TargetFramework> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Xamarin.Forms" Version="2.4.0.280" /> + </ItemGroup> +</Project> diff --git a/main/tests/test-projects/dotnetcore-console/dotnetcore-console/dotnetcore-disable-default-items.csproj b/main/tests/test-projects/dotnetcore-console/dotnetcore-console/dotnetcore-disable-default-items.csproj index fd1623b06c..11a396011a 100755 --- a/main/tests/test-projects/dotnetcore-console/dotnetcore-console/dotnetcore-disable-default-items.csproj +++ b/main/tests/test-projects/dotnetcore-console/dotnetcore-console/dotnetcore-disable-default-items.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Test.Sdk" ToolsVersion="15.0"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> diff --git a/main/tests/test-projects/msbuild-glob-tests/glob-import-metadata-prop.csproj b/main/tests/test-projects/msbuild-glob-tests/glob-import-metadata-prop.csproj new file mode 100644 index 0000000000..ad3b9e462b --- /dev/null +++ b/main/tests/test-projects/msbuild-glob-tests/glob-import-metadata-prop.csproj @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="glob-import-metadata-prop.props" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">x86</Platform> + <ProjectGuid>{109A0AFA-67E0-4FF4-A942-78A545367EBD}</ProjectGuid> + <OutputType>Exe</OutputType> + <RootNamespace>GlobTest</RootNamespace> + <AssemblyName>GlobTest</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug</OutputPath> + <DefineConstants>DEBUG;</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <ExternalConsole>true</ExternalConsole> + <PlatformTarget>x86</PlatformTarget> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> + <Optimize>true</Optimize> + <OutputPath>bin\Release</OutputPath> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <ExternalConsole>true</ExternalConsole> + <PlatformTarget>x86</PlatformTarget> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/main/tests/test-projects/msbuild-glob-tests/glob-import-metadata-prop.props b/main/tests/test-projects/msbuild-glob-tests/glob-import-metadata-prop.props new file mode 100644 index 0000000000..970d990ca4 --- /dev/null +++ b/main/tests/test-projects/msbuild-glob-tests/glob-import-metadata-prop.props @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <EmbeddedResource Include="**\*.xaml" SubType="Designer" Generator="MSBuild:UpdateDesignTimeXaml" /> + <Compile Include="**\*.cs" /> + <Compile Update="**\*.xaml.cs" DependentUpon="%(Filename)" SubType="Code" /> + </ItemGroup> +</Project>
\ No newline at end of file |