[SuppressMessage("", "RS0001")] // TODO: This suppression should be removed once we have rulesets in place for Roslyn.sln private static IEnumerable <SectionBlock> ParseGlobal(SourceTextReader reader) { if (reader.Peek() == -1) { return(Enumerable.Empty <SectionBlock>()); } if (GetNextNonEmptyLine(reader) != "Global") { throw new Exception(string.Format(WorkspacesResources.MissingLineInSolutionFile, "Global")); } var globalSectionBlocks = new List <SectionBlock>(); // The blocks inside here are indented while (reader.Peek() != -1 && char.IsWhiteSpace((char)reader.Peek())) { globalSectionBlocks.Add(SectionBlock.Parse(reader)); } if (GetNextNonEmptyLine(reader) != "EndGlobal") { throw new Exception(string.Format(WorkspacesResources.MissingLineInSolutionFile, "EndGlobal")); } // Consume potential empty lines at the end of the global block while (reader.Peek() != -1 && "\r\n".Contains((char)reader.Peek())) { reader.ReadLine(); } return(globalSectionBlocks); }
internal static ProjectBlock Parse(SourceTextReader reader) { var startLine = reader.ReadLine().TrimStart(); var scanner = new LineScanner(startLine); if (scanner.ReadUpToAndEat("(\"") != "Project") { throw new Exception(string.Format(WorkspacesResources.InvalidProjectBlockInSolutionFile4, "Project")); } var projectTypeGuid = scanner.ReadUpToAndEat("\")").Parse(s => Guid.Parse(s)); // Read chars upto next quote, must contain "=" with optional leading/trailing whitespaces. if (scanner.ReadUpToAndEat("\"").Trim() != "=") { throw new Exception(WorkspacesResources.InvalidProjectBlockInSolutionFile); } var projectName = scanner.ReadUpToAndEat("\""); // Read chars upto next quote, must contain "," with optional leading/trailing whitespaces. if (scanner.ReadUpToAndEat("\"").Trim() != ",") { throw new Exception(WorkspacesResources.InvalidProjectBlockInSolutionFile2); } var projectPath = scanner.ReadUpToAndEat("\""); // Read chars upto next quote, must contain "," with optional leading/trailing whitespaces. if (scanner.ReadUpToAndEat("\"").Trim() != ",") { throw new Exception(WorkspacesResources.InvalidProjectBlockInSolutionFile3); } var projectGuid = scanner.ReadUpToAndEat("\"").Parse(s => Guid.Parse(s)); var projectSections = new List <SectionBlock>(); while (char.IsWhiteSpace((char)reader.Peek())) { projectSections.Add(SectionBlock.Parse(reader)); } // Expect to see "EndProject" but be tolerant with missing tags as in Dev12. // Instead, we may see either P' for "Project" or 'G' for "Global", which will be handled next. if (reader.Peek() != 'P' && reader.Peek() != 'G') { if (reader.ReadLine() != "EndProject") { throw new Exception(string.Format(WorkspacesResources.InvalidProjectBlockInSolutionFile4, "EndProject")); } } return(new ProjectBlock(projectTypeGuid, projectName.Parse(), projectPath.Parse(), projectGuid, projectSections)); }
public static SolutionFile Parse(SourceTextReader reader) { var headerLines = new List <string>(); var headerLine1 = GetNextNonEmptyLine(reader).ToString(); if (headerLine1 == null || !headerLine1.StartsWith("Microsoft Visual Studio Solution File", StringComparison.Ordinal)) { throw new Exception(string.Format(WorkspacesResources.MissingHeaderInSolutionFile, "Microsoft Visual Studio Solution File")); } headerLines.Add(headerLine1); // skip comment lines and empty lines while (reader.Peek() != -1 && "#\r\n".Contains((char)reader.Peek())) { headerLines.Add(reader.ReadLine().ToString()); } string visualStudioVersionLineOpt = null; if (reader.Peek() == 'V') { visualStudioVersionLineOpt = GetNextNonEmptyLine(reader).ToString(); if (!visualStudioVersionLineOpt.StartsWith("VisualStudioVersion", StringComparison.Ordinal)) { throw new Exception(string.Format(WorkspacesResources.MissingHeaderInSolutionFile, "VisualStudioVersion")); } } string minimumVisualStudioVersionLineOpt = null; if (reader.Peek() == 'M') { minimumVisualStudioVersionLineOpt = GetNextNonEmptyLine(reader).ToString(); if (!minimumVisualStudioVersionLineOpt.StartsWith("MinimumVisualStudioVersion", StringComparison.Ordinal)) { throw new Exception(string.Format(WorkspacesResources.MissingHeaderInSolutionFile, "MinimumVisualStudioVersion")); } } var projectBlocks = new List <ProjectBlock>(); // Parse project blocks while we have them while (reader.Peek() == 'P') { projectBlocks.Add(ProjectBlock.Parse(reader)); while (reader.Peek() != -1 && "#\r\n".Contains((char)reader.Peek())) { // Comments and Empty Lines between the Project Blocks are skipped reader.ReadLine(); } } // We now have a global block var globalSectionBlocks = ParseGlobal(reader); // We should now be at the end of the file if (reader.Peek() != -1) { throw new Exception(WorkspacesResources.MissingEndOfFileInSolutionFile); } return(new SolutionFile(reader.SourceText, headerLines, visualStudioVersionLineOpt, minimumVisualStudioVersionLineOpt, projectBlocks, globalSectionBlocks)); }