diff options
author | nosami <jasonimison@gmail.com> | 2018-04-13 14:51:02 +0300 |
---|---|---|
committer | nosami <jasonimison@gmail.com> | 2018-04-13 14:51:02 +0300 |
commit | bfeb4c99dc1e554010f0a518349bfb9063b6933b (patch) | |
tree | 331ca64b5106502a05f58ca1e296c1b3b91a91ba /main | |
parent | 4b6809430eee2f2345eae595a46e971a63f35333 (diff) |
Allow XAML files and codebehind files to be moved as a single unit
Fixes VSTS #599769 (#4544)
Diffstat (limited to 'main')
-rw-r--r-- | main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ProjectTests.fs | 57 | ||||
-rw-r--r-- | main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpProjectFileNodeExtension.fs | 36 |
2 files changed, 81 insertions, 12 deletions
diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ProjectTests.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ProjectTests.fs index 76adf1578e..673766933f 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ProjectTests.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ProjectTests.fs @@ -84,6 +84,63 @@ type ProjectTests() = newXml |> should equal expected [<Test;AsyncStateMachine(typeof<Task>)>] + member this.``Can reorder files with dependent files``() = + async { + if not MonoDevelop.Core.Platform.IsWindows then + let xml = + """ + <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <ProjectGuid>{F614AE96-C732-4C45-B098-52015B759E6B}</ProjectGuid> + <TargetProfile>netcore</TargetProfile> + <OutputType>Library</OutputType> + </PropertyGroup> + <ItemGroup> + <EmbeddedResource Include="outerfile.xaml"> + <Generator>MSBuild:UpdateDesignTimeXaml</Generator> + </EmbeddedResource> + <Compile Include="innerfile.xaml.fs"> + <DependentUpon>outerfile.xaml</DependentUpon> + </Compile> + <Compile Include="test1.fs" /> + </ItemGroup> + </Project> + """ + let path = Path.GetTempPath() + let fsproj = path / Guid.NewGuid().ToString() + ".fsproj" + File.WriteAllText (fsproj, xml) + let! (solutionItem:SolutionItem) = Services.ProjectService.ReadSolutionItem(monitor, fsproj) + let project = solutionItem :?> DotNetProject + let moveToFile = project.Files.GetFile(path/"test1.fs" |> FilePath) + let outerFile = project.Files.GetFile(path/"outerfile.xaml" |> FilePath) + + let fsp = new FSharpProjectNodeCommandHandler() + fsp.MoveNodes moveToFile outerFile DropPosition.After + + let newXml = File.ReadAllText fsproj + printfn "%s" newXml + let expected = + """<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <ProjectGuid>{F614AE96-C732-4C45-B098-52015B759E6B}</ProjectGuid> + <TargetProfile>netcore</TargetProfile> + <OutputType>Library</OutputType> + </PropertyGroup> + <ItemGroup> + <Compile Include="test1.fs" /> + <EmbeddedResource Include="outerfile.xaml"> + <Generator>MSBuild:UpdateDesignTimeXaml</Generator> + </EmbeddedResource> + <Compile Include="innerfile.xaml.fs"> + <DependentUpon>outerfile.xaml</DependentUpon> + </Compile> + </ItemGroup> +</Project>""" + + newXml |> should equal expected + } |> toTask + + [<Test;AsyncStateMachine(typeof<Task>)>] member this.``Doesn't change forward slashes to backslashes ``() = toTask <| async { if not MonoDevelop.Core.Platform.IsWindows then diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpProjectFileNodeExtension.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpProjectFileNodeExtension.fs index 52d636815b..2c6b7263b9 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpProjectFileNodeExtension.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpProjectFileNodeExtension.fs @@ -24,9 +24,7 @@ type FSharpProjectNodeCommandHandler() = monitor.Step (1) monitor.EndTask() - member x.MoveNodes (moveToNode: ProjectFile) (movingNode:ProjectFile) position = - let projectFile = movingNode.Project.FileName.ToString() - + let rec moveNodeInXDoc (xdoc:XElement) (moveToNode: ProjectFile) (movingNode:ProjectFile) position isNested = let descendantsNamed ns name ancestor = ///partially apply the default namespace of msbuild to xs let xd = xs ns @@ -40,10 +38,6 @@ type FSharpProjectNodeCommandHandler() = | Some l -> l.Value | None -> node |> attributeValue "Include" - //open project file - use file = IO.File.Open(projectFile, FileMode.Open) - let xdoc = XElement.Load(file) - file.Close() let defaultNamespace = xdoc.GetDefaultNamespace().NamespaceName let descendantsByNamespace = descendantsNamed defaultNamespace //get movable nodes from the project file @@ -70,17 +64,34 @@ type FSharpProjectNodeCommandHandler() = match (movingElement, moveToElement, position) with | Some(moving), Some(moveTo), (DropPosition.Before | DropPosition.After) -> moving.Remove() - //if the moving node contains a DependentUpon node as a child remove the DependentUpon nodes - moving |> descendantsByNamespace "DependentUpon" |> Seq.iter (fun node -> node.Remove()) + // If the moving node contains a DependentUpon node as a child remove the DependentUpon nodes, + // only if the moving node was moved directly - not via moving the parent node + if not isNested then + moving |> descendantsByNamespace "DependentUpon" |> Seq.iter (fun node -> node.Remove()) //get the add function using the position let add = addFunction moveTo position add(moving) - let settings = XmlWriterSettings(OmitXmlDeclaration = true, Indent = true) - use writer = XmlWriter.Create(projectFile, settings) - xdoc.Save(writer); + // If any of the project files depend on the file + // being moved, then move those files below the file being moved + movingNode.Project.Files + |> Seq.filter(fun f -> f.DependsOnFile = movingNode) + |> Seq.iter(fun f -> moveNodeInXDoc xdoc movingNode f DropPosition.After true) + | _ -> ()//If we cant find both nodes or the position isnt before or after we dont continue + member x.MoveNodes (moveToNode: ProjectFile) (movingNode:ProjectFile) position = + let projectFile = movingNode.Project.FileName.ToString() + + let xdoc = XElement.Load(projectFile) + + moveNodeInXDoc xdoc moveToNode movingNode position false + + let settings = XmlWriterSettings(OmitXmlDeclaration = true, Indent = true) + use writer = XmlWriter.Create(projectFile, settings) + xdoc.Save(writer); + writer.Close() + /// Implement drag and drop of nodes in F# projects in the solution explorer. override x.OnNodeDrop(dataObject, dragOperation, position) = match dataObject, dragOperation with @@ -181,3 +192,4 @@ type FSharpProjectFileNodeExtension() = x.Compare thisNode.DataItem otherNode.DataItem override x.CommandHandlerType = typeof<FSharpProjectNodeCommandHandler> + |