From e378b90e2e2cdbe6ac13a6c764a4eab80a94850d Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 1 Mar 2006 15:46:28 +0000 Subject: [PATCH] Fixed exception when opening a solution containing web projects. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.0@1194 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Src/Gui/Workbench/DefaultWorkbench.cs | 7 +++- .../Project/Src/Project/AbstractProject.cs | 19 +++++++-- src/Main/Base/Project/Src/Project/IProject.cs | 7 ++++ .../Project/Src/Project/MSBuildProject.cs | 4 +- .../Project/Src/Project/MissingProject.cs | 4 +- .../Src/Project/Solution/ProjectSection.cs | 6 +-- .../Project/Src/Project/Solution/Solution.cs | 42 ++++++++++++------- .../Src/Project/Solution/SolutionFolder.cs | 17 ++++++-- .../Project/Src/Project/UnknownProject.cs | 4 +- .../LanguageBinding/LanguageBindingService.cs | 6 +-- .../Src/Services/FileUtility/FileUtility.cs | 15 ++++++- .../Core/Test/AddInTreeTests/ExtPathTests.cs | 3 ++ 12 files changed, 96 insertions(+), 38 deletions(-) diff --git a/src/Main/Base/Project/Src/Gui/Workbench/DefaultWorkbench.cs b/src/Main/Base/Project/Src/Gui/Workbench/DefaultWorkbench.cs index d1f069e8bb..2cff9bdcaa 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/DefaultWorkbench.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/DefaultWorkbench.cs @@ -563,7 +563,12 @@ namespace ICSharpCode.SharpDevelop.Gui foreach (string file in files) { if (File.Exists(file)) { - FileService.OpenFile(file); + IProjectLoader loader = ProjectService.GetProjectLoader(file); + if (loader != null) { + FileUtility.ObservedLoad(new NamedFileOperationDelegate(loader.Load), file); + } else { + FileService.OpenFile(file); + } } } } diff --git a/src/Main/Base/Project/Src/Project/AbstractProject.cs b/src/Main/Base/Project/Src/Project/AbstractProject.cs index ffa3b6c970..69dc09f414 100644 --- a/src/Main/Base/Project/Src/Project/AbstractProject.cs +++ b/src/Main/Base/Project/Src/Project/AbstractProject.cs @@ -29,9 +29,10 @@ namespace ICSharpCode.SharpDevelop.Project protected List items = new List(); protected List imports = new List(); + readonly List projectSections = new List(); - protected string fileName; - protected string language; + string fileName; + string language; [Browsable(false)] public Dictionary Configurations { @@ -153,6 +154,16 @@ namespace ICSharpCode.SharpDevelop.Project } } + /// + /// Gets a list of property sections stored in the solution file. + /// + [Browsable(false)] + public List ProjectSections { + get { + return projectSections; + } + } + /// /// Gets the list of MSBuild Imports. /// @@ -172,7 +183,7 @@ namespace ICSharpCode.SharpDevelop.Project if (fileName == null) { return String.Empty; } - return Path.GetFullPath(fileName); + return fileName; } set { fileName = value; @@ -188,7 +199,7 @@ namespace ICSharpCode.SharpDevelop.Project if (fileName == null) { return String.Empty; } - directoryName = Path.GetFullPath(Path.GetDirectoryName(fileName)); + directoryName = Path.GetDirectoryName(fileName); } return directoryName; } diff --git a/src/Main/Base/Project/Src/Project/IProject.cs b/src/Main/Base/Project/Src/Project/IProject.cs index 56f6ddb91b..9886818ded 100644 --- a/src/Main/Base/Project/Src/Project/IProject.cs +++ b/src/Main/Base/Project/Src/Project/IProject.cs @@ -30,6 +30,13 @@ namespace ICSharpCode.SharpDevelop.Project get; } + /// + /// Gets a list of property sections stored in the solution file. + /// + List ProjectSections { + get; + } + /// /// Marks a project for needing recompilation. /// diff --git a/src/Main/Base/Project/Src/Project/MSBuildProject.cs b/src/Main/Base/Project/Src/Project/MSBuildProject.cs index 78075ce767..a079437884 100644 --- a/src/Main/Base/Project/Src/Project/MSBuildProject.cs +++ b/src/Main/Base/Project/Src/Project/MSBuildProject.cs @@ -57,7 +57,7 @@ namespace ICSharpCode.SharpDevelop.Project configurations["Release|*"]["DebugSymbols"] = "False"; configurations["Release|*"]["DebugType"] = "None"; - fileName = information.OutputProjectFileName; + this.FileName = Path.GetFullPath(information.OutputProjectFileName); } public override bool CanCompile(string fileName) @@ -82,7 +82,7 @@ namespace ICSharpCode.SharpDevelop.Project protected void SetupProject(string projectFileName) { - this.fileName = projectFileName; + this.FileName = Path.GetFullPath(projectFileName); using (MSBuildFileReader reader = new MSBuildFileReader(projectFileName)) { reader.WhitespaceHandling = WhitespaceHandling.Significant; reader.MoveToContent(); // we have to skip over the XmlDeclaration (if it exists) diff --git a/src/Main/Base/Project/Src/Project/MissingProject.cs b/src/Main/Base/Project/Src/Project/MissingProject.cs index 7d6344a5e1..518f76a480 100644 --- a/src/Main/Base/Project/Src/Project/MissingProject.cs +++ b/src/Main/Base/Project/Src/Project/MissingProject.cs @@ -24,9 +24,9 @@ namespace ICSharpCode.SharpDevelop.Project } } - public MissingProject(string fileName) + public MissingProject(string fileName, string title) { - Name = Path.GetFileNameWithoutExtension(fileName); + Name = title; FileName = fileName; IdGuid = "{" + Guid.NewGuid().ToString() + "}"; } diff --git a/src/Main/Base/Project/Src/Project/Solution/ProjectSection.cs b/src/Main/Base/Project/Src/Project/Solution/ProjectSection.cs index 1ef1048f29..381fcbe781 100644 --- a/src/Main/Base/Project/Src/Project/Solution/ProjectSection.cs +++ b/src/Main/Base/Project/Src/Project/Solution/ProjectSection.cs @@ -55,17 +55,17 @@ namespace ICSharpCode.SharpDevelop.Project } static Regex sectionPattern = new Regex("\\s*(?.*\\S)\\s*=\\s*(?.*\\S)\\s*", RegexOptions.Compiled); - public static ProjectSection ReadGlobalSection(StreamReader sr, string name, string sectionType) + public static ProjectSection ReadGlobalSection(TextReader sr, string name, string sectionType) { return ReadSection(sr, name, sectionType, "EndGlobalSection"); } - public static ProjectSection ReadProjectSection(StreamReader sr, string name, string sectionType) + public static ProjectSection ReadProjectSection(TextReader sr, string name, string sectionType) { return ReadSection(sr, name, sectionType, "EndProjectSection"); } - static ProjectSection ReadSection(StreamReader sr, string name, string sectionType, string endTag) + static ProjectSection ReadSection(TextReader sr, string name, string sectionType, string endTag) { ProjectSection newFolder = new ProjectSection(name, sectionType); while (true) { diff --git a/src/Main/Base/Project/Src/Project/Solution/Solution.cs b/src/Main/Base/Project/Src/Project/Solution/Solution.cs index 48058dc6de..c2970b23db 100644 --- a/src/Main/Base/Project/Src/Project/Solution/Solution.cs +++ b/src/Main/Base/Project/Src/Project/Solution/Solution.cs @@ -271,23 +271,14 @@ namespace ICSharpCode.SharpDevelop.Project projectSection.AppendLine(); if (currentFolder is IProject) { - // IProject project = (IProject)currentFolder; - // currently nothing to do. (I don't know if projects may have sections). + IProject project = (IProject)currentFolder; + // Web projects can have sections + SaveProjectSections(project.ProjectSections, projectSection); + } else if (currentFolder is SolutionFolder) { SolutionFolder folder = (SolutionFolder)currentFolder; - foreach (ProjectSection section in folder.Sections) { - projectSection.Append("\tProjectSection("); - projectSection.Append(section.Name); - projectSection.Append(") = "); - projectSection.Append(section.SectionType); - projectSection.Append(Environment.NewLine); - - section.AppendSection(projectSection, "\t\t"); - - projectSection.Append("\tEndProjectSection"); - projectSection.Append(Environment.NewLine); - } + SaveProjectSections(folder.Sections, projectSection); foreach (ISolutionFolder subFolder in folder.Folders) { stack.Push(subFolder); @@ -339,6 +330,22 @@ namespace ICSharpCode.SharpDevelop.Project } } + static void SaveProjectSections(IEnumerable sections, StringBuilder projectSection) + { + foreach (ProjectSection section in sections) { + projectSection.Append("\tProjectSection("); + projectSection.Append(section.Name); + projectSection.Append(") = "); + projectSection.Append(section.SectionType); + projectSection.Append(Environment.NewLine); + + section.AppendSection(projectSection, "\t\t"); + + projectSection.Append("\tEndProjectSection"); + projectSection.Append(Environment.NewLine); + } + } + static Regex versionPattern = new Regex("Microsoft Visual Studio Solution File, Format Version\\s+(?.*)", RegexOptions.Compiled); static Regex projectLinePattern = new Regex("Project\\(\"(?.*)\"\\)\\s+=\\s+\"(?.*)\",\\s*\"(?<Location>.*)\",\\s*\"(?<Guid>.*)\"", RegexOptions.Compiled); @@ -432,14 +439,19 @@ namespace ICSharpCode.SharpDevelop.Project if (match.Success) { string projectGuid = match.Result("${ProjectGuid}"); string title = match.Result("${Title}"); - string location = Path.Combine(solutionDirectory, match.Result("${Location}")); + string location = match.Result("${Location}"); string guid = match.Result("${Guid}"); + if (!FileUtility.IsUrl(location)) { + location = Path.Combine(solutionDirectory, location); + } + if (projectGuid == FolderGuid) { SolutionFolder newFolder = SolutionFolder.ReadFolder(sr, title, location, guid); newSolution.AddFolder(newFolder); } else { IProject newProject = LanguageBindingService.LoadProject(location, title, projectGuid); + ReadProjectSections(sr, newProject.ProjectSections); newProject.IdGuid = guid; newSolution.AddFolder(newProject); } diff --git a/src/Main/Base/Project/Src/Project/Solution/SolutionFolder.cs b/src/Main/Base/Project/Src/Project/Solution/SolutionFolder.cs index 339c57a3e0..5c0701973c 100644 --- a/src/Main/Base/Project/Src/Project/Solution/SolutionFolder.cs +++ b/src/Main/Base/Project/Src/Project/Solution/SolutionFolder.cs @@ -117,9 +117,20 @@ namespace ICSharpCode.SharpDevelop.Project #endregion static Regex sectionHeaderPattern = new Regex("\\s*ProjectSection\\((?<Name>.*)\\)\\s*=\\s*(?<Type>.*)", RegexOptions.Compiled); - public static SolutionFolder ReadFolder(StreamReader sr, string title, string location, string guid) + + public static SolutionFolder ReadFolder(TextReader sr, string title, string location, string guid) { SolutionFolder newFolder = new SolutionFolder(title, location, guid); + ReadProjectSections(sr, newFolder.Sections); + return newFolder; + } + + /// <summary> + /// Reads project sections from the TextReader until the line "EndProject" is found and saves + /// them into the specified sectionList. + /// </summary> + public static void ReadProjectSections(TextReader sr, ICollection<ProjectSection> sectionList) + { while (true) { string line = sr.ReadLine(); if (line == null || line.Trim() == "EndProject") { @@ -127,11 +138,9 @@ namespace ICSharpCode.SharpDevelop.Project } Match match = sectionHeaderPattern.Match(line); if (match.Success) { - newFolder.Sections.Add(ProjectSection.ReadProjectSection(sr, match.Result("${Name}"), match.Result("${Type}"))); + sectionList.Add(ProjectSection.ReadProjectSection(sr, match.Result("${Name}"), match.Result("${Type}"))); } } - return newFolder; } - } } diff --git a/src/Main/Base/Project/Src/Project/UnknownProject.cs b/src/Main/Base/Project/Src/Project/UnknownProject.cs index e69107177b..fe6a44fded 100644 --- a/src/Main/Base/Project/Src/Project/UnknownProject.cs +++ b/src/Main/Base/Project/Src/Project/UnknownProject.cs @@ -24,9 +24,9 @@ namespace ICSharpCode.SharpDevelop.Project } } - public UnknownProject(string fileName) + public UnknownProject(string fileName, string title) { - Name = Path.GetFileNameWithoutExtension(fileName); + Name = title; FileName = fileName; IdGuid = "{" + Guid.NewGuid().ToString() + "}"; } diff --git a/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs b/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs index 91bca7ed2a..a6ca2db6ab 100644 --- a/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs +++ b/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs @@ -84,7 +84,7 @@ namespace ICSharpCode.Core { IProject newProject; if (!File.Exists(location)) { - newProject = new MissingProject(location); + newProject = new MissingProject(location, title); newProject.TypeGuid = projectTypeGuid; } else { ILanguageBinding binding = LanguageBindingService.GetBindingPerProjectFile(location); @@ -93,11 +93,11 @@ namespace ICSharpCode.Core newProject = binding.LoadProject(location, title); } catch (XmlException ex) { MessageService.ShowError("Error loading " + location + ":\n" + ex.Message); - newProject = new UnknownProject(location); + newProject = new UnknownProject(location, title); newProject.TypeGuid = projectTypeGuid; } } else { - newProject = new UnknownProject(location); + newProject = new UnknownProject(location, title); newProject.TypeGuid = projectTypeGuid; } } diff --git a/src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs b/src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs index 58db370b0f..d9611350db 100644 --- a/src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs +++ b/src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs @@ -103,6 +103,10 @@ namespace ICSharpCode.Core return result; } + public static bool IsUrl(string path) + { + return path.IndexOf(':') >= 2; + } /// <summary> /// Converts a given absolute path and a given base path to a path that leads @@ -110,8 +114,15 @@ namespace ICSharpCode.Core /// </summary> public static string GetRelativePath(string baseDirectoryPath, string absPath) { - baseDirectoryPath = Path.GetFullPath(baseDirectoryPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)); - absPath = Path.GetFullPath(absPath); + if (IsUrl(absPath) || IsUrl(baseDirectoryPath)){ + return absPath; + } + try { + baseDirectoryPath = Path.GetFullPath(baseDirectoryPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)); + absPath = Path.GetFullPath(absPath); + } catch (Exception ex) { + throw new ArgumentException("GetRelativePath error '" + baseDirectoryPath + "' -> '" + absPath + "'", ex); + } string[] bPath = baseDirectoryPath.Split(separators); string[] aPath = absPath.Split(separators); diff --git a/src/Main/Core/Test/AddInTreeTests/ExtPathTests.cs b/src/Main/Core/Test/AddInTreeTests/ExtPathTests.cs index 200decd755..ef8e2e3fc4 100644 --- a/src/Main/Core/Test/AddInTreeTests/ExtPathTests.cs +++ b/src/Main/Core/Test/AddInTreeTests/ExtPathTests.cs @@ -56,6 +56,9 @@ namespace ICSharpCode.Core.Tests.AddInTreeTests.Tests Assert.AreEqual(@"blub", FileUtility.GetRelativePath(@"C:\hello\.\..\A", @"C:\.\a\blub")); Assert.AreEqual(@"..\a\blub", FileUtility.GetRelativePath(@"C:\.\.\.\.\HELlo", @"C:\.\blub\.\..\.\a\.\blub")); Assert.AreEqual(@"..\a\blub", FileUtility.GetRelativePath(@"C:\.\.\.\.\heLLo\A\..", @"C:\.\blub\.\..\.\a\.\blub")); + + // Project filename could be an URL + Assert.AreEqual("http://example.com/vdir/", FileUtility.GetRelativePath("C:\\temp", "http://example.com/vdir/")); } [Test]