private static List <string> MergeFixedCode(IReadOnlyList <string> codes, string fixedCode) { var merged = new List <string>(codes.Count); var found = false; var @namespace = CodeReader.Namespace(fixedCode); var fileName = CodeReader.FileName(fixedCode); foreach (var code in codes) { if (CodeReader.FileName(code) == fileName && CodeReader.Namespace(code) == @namespace) { if (found) { throw new AssertException("Expected unique class names."); } merged.Add(fixedCode); found = true; } else { merged.Add(code); } } if (!found) { throw new AssertException("Failed merging expected one class to have same namespace and class name as fixedCode.\r\n" + "Try specifying a list with all fixed code."); } return(merged); }
/// <summary> /// Create a <see cref="Solution"/> for <paramref name="code"/> /// Each unique namespace in <paramref name="code"/> is added as a project. /// </summary> /// <param name="code">The code to create the solution from.</param> /// <param name="compilationOptions">The <see cref="CSharpCompilationOptions"/>.</param> /// <param name="metadataReferences">The metadata references.</param> /// <returns>A <see cref="Solution"/>.</returns> public static Solution CreateSolutionWithOneProject(IEnumerable <string> code, CSharpCompilationOptions compilationOptions, IEnumerable <MetadataReference> metadataReferences = null) { var projectInfo = GetProjectInfo(); return(EmptySolution.AddProject(projectInfo)); ProjectInfo GetProjectInfo() { string projectName = null; foreach (var doc in code) { if (projectName == null) { projectName = CodeReader.Namespace(doc); } else { var ns = CodeReader.Namespace(doc); var indexOf = ns.IndexOf('.'); if (indexOf > 0) { ns = ns.Substring(0, indexOf); } if (ns.Length < projectName.Length) { projectName = ns; } } } var projectId = ProjectId.CreateNewId(projectName); return(ProjectInfo.Create( projectId, VersionStamp.Default, projectName, projectName, LanguageNames.CSharp, metadataReferences: metadataReferences, compilationOptions: compilationOptions, documents: code.Select( x => { var documentName = CodeReader.FileName(x); return DocumentInfo.Create( DocumentId.CreateNewId(projectId, documentName), documentName, sourceCodeKind: SourceCodeKind.Regular, loader: TextLoader.From( TextAndVersion.Create( SourceText.From(x, (Encoding)null, SourceHashAlgorithm.Sha1), VersionStamp.Default))); }))); } }
private static async Task AreEqualAsync(IReadOnlyList <string> expected, Solution actual, string?messageHeader) { var actualCount = actual.Projects.SelectMany(x => x.Documents).Count(); if (expected.Count != actualCount) { throw new AssertException($"Expected {expected.Count} documents the fixed solution has {actualCount} documents."); } foreach (var project in actual.Projects) { foreach (var document in project.Documents) { var fixedSource = await CodeReader.GetStringFromDocumentAsync(document, CancellationToken.None).ConfigureAwait(false); CodeAssert.AreEqual(FindExpected(fixedSource), fixedSource, messageHeader); } } string FindExpected(string fixedSource) { var fixedNamespace = CodeReader.Namespace(fixedSource); var fixedFileName = CodeReader.FileName(fixedSource); var match = expected.FirstOrDefault(x => x == fixedSource); if (match != null) { return(match); } foreach (var candidate in expected) { if (CodeReader.Namespace(candidate) == fixedNamespace && CodeReader.FileName(candidate) == fixedFileName) { return(candidate); } } throw new AssertException($"The fixed solution contains a document {fixedFileName} in namespace {fixedNamespace} that is not in the expected documents."); } }
public SourceMetadata(string code) { this.Code = code; this.FileName = CodeReader.FileName(code); this.Namespace = CodeReader.Namespace(code); }
/// <summary> /// Create a <see cref="Solution"/> for <paramref name="code"/> /// Each unique namespace in <paramref name="code"/> is added as a project. /// </summary> /// <param name="code">The code to create the solution from.</param> /// <param name="compilationOptions">The <see cref="CSharpCompilationOptions"/>.</param> /// <param name="metadataReferences">The metadata references.</param> /// <param name="languageVersion">The <see cref="LanguageVersion"/>.</param> /// <returns>A <see cref="Solution"/>.</returns> public static Solution CreateSolution(IEnumerable <string> code, CSharpCompilationOptions compilationOptions, IEnumerable <MetadataReference> metadataReferences = null, LanguageVersion languageVersion = LanguageVersion.Latest) { var solutionInfo = SolutionInfo.Create( SolutionId.CreateNewId("Test.sln"), VersionStamp.Default, projects: GetProjectInfos()); var solution = EmptySolution; foreach (var projectInfo in solutionInfo.Projects) { solution = solution.AddProject(projectInfo.WithProjectReferences(FindReferences(projectInfo))); } return(solution); IEnumerable <ProjectInfo> GetProjectInfos() { var byNamespace = new SortedDictionary <string, List <string> >(); foreach (var document in code) { var ns = CodeReader.Namespace(document); if (byNamespace.TryGetValue(ns, out var doc)) { doc.Add(document); } else { byNamespace[ns] = new List <string> { document }; } } var byProject = new SortedDictionary <string, List <KeyValuePair <string, List <string> > > >(); foreach (var kvp in byNamespace) { var last = byProject.Keys.LastOrDefault(); var ns = kvp.Key; if (last != null && ns.Contains(last)) { byProject[last].Add(kvp); } else { byProject.Add(ns, new List <KeyValuePair <string, List <string> > > { kvp }); } } foreach (var kvp in byProject) { var assemblyName = kvp.Key; var projectId = ProjectId.CreateNewId(assemblyName); yield return(ProjectInfo.Create( projectId, VersionStamp.Default, assemblyName, assemblyName, LanguageNames.CSharp, compilationOptions: compilationOptions, metadataReferences: metadataReferences, documents: kvp.Value.SelectMany(x => x.Value) .Select( x => { var documentName = CodeReader.FileName(x); return DocumentInfo.Create( DocumentId.CreateNewId(projectId, documentName), documentName, sourceCodeKind: SourceCodeKind.Regular, loader: new StringLoader(x)); })) .WithParseOptions(CSharpParseOptions.Default.WithLanguageVersion(languageVersion))); } } IEnumerable <ProjectReference> FindReferences(ProjectInfo projectInfo) { var references = new List <ProjectReference>(); foreach (var other in solutionInfo.Projects.Where(x => x.Id != projectInfo.Id)) { if (projectInfo.Documents.Any(x => x.TextLoader is StringLoader stringLoader && (stringLoader.Code.Contains($"using {other.Name};") || stringLoader.Code.Contains($"{other.Name}.")))) { references.Add(new ProjectReference(other.Id)); } } return(references); } }