private static Solution AddAssemblyAttributesFile(string language, string outputAssemblyPath, Solution solution) { if (!File.Exists(outputAssemblyPath)) { Log.Exception("AddAssemblyAttributesFile: assembly doesn't exist: " + outputAssemblyPath); return(solution); } var assemblyAttributesFileText = MetadataReading.GetAssemblyAttributesFileText( assemblyFilePath: outputAssemblyPath, language: language); if (assemblyAttributesFileText != null) { var extension = language == LanguageNames.CSharp ? ".cs" : ".vb"; var newAssemblyAttributesDocumentName = MetadataAsSource.GeneratedAssemblyAttributesFileName + extension; var existingAssemblyAttributesFileName = "AssemblyAttributes" + extension; var project = solution.Projects.First(); if (project.Documents.All(d => d.Name != existingAssemblyAttributesFileName || d.Folders.Count != 0)) { var document = project.AddDocument( newAssemblyAttributesDocumentName, assemblyAttributesFileText, filePath: newAssemblyAttributesDocumentName); solution = document.Project.Solution; } } return(solution); }
public static string GetAssemblyAttributesFileText(string assemblyFilePath, string language = LanguageNames.CSharp) { var assemblyAttributes = MetadataReading.GetAssemblyAttributes(assemblyFilePath, language); if (!assemblyAttributes.Any()) { return(null); } return(GetAssemblyAttributesFileText(language, assemblyFilePath.Substring(0, 3), assemblyAttributes)); }
public static Solution LoadMetadataAsSourceSolution(string assemblyFilePath) { try { using (Disposable.Timing("Metadata as source: " + assemblyFilePath)) { var assemblyName = Path.GetFileNameWithoutExtension(assemblyFilePath); var solution = new AdhocWorkspace(WorkspaceHacks.Pack).CurrentSolution; var workspace = solution.Workspace; var project = solution.AddProject(assemblyName, assemblyName, LanguageNames.CSharp); var metadataReference = CreateReferenceFromFilePath(assemblyFilePath); var referencePaths = MetadataReading.GetReferencePaths(metadataReference); foreach (var referencePath in referencePaths) { project = project.AddMetadataReference(CreateReferenceFromFilePath(referencePath)); } var projectWithReference = project.AddMetadataReference(metadataReference); var compilation = projectWithReference.GetCompilationAsync().ConfigureAwait(false).GetAwaiter().GetResult(); var assemblyOrModuleSymbol = compilation.GetAssemblyOrModuleSymbol(metadataReference); IAssemblySymbol assemblySymbol = assemblyOrModuleSymbol as IAssemblySymbol; IModuleSymbol moduleSymbol = assemblyOrModuleSymbol as IModuleSymbol; if (moduleSymbol != null && assemblySymbol == null) { assemblySymbol = moduleSymbol.ContainingAssembly; } var assemblyAttributes = MetadataReading.GetAssemblyAttributes(assemblySymbol); var assemblyAttributesFileText = MetadataReading.GetAssemblyAttributesFileText( LanguageNames.CSharp, assemblyFilePath.Substring(0, 3), assemblyAttributes); INamespaceSymbol namespaceSymbol = null; if (assemblySymbol != null) { namespaceSymbol = assemblySymbol.GlobalNamespace; } else if (moduleSymbol != null) { namespaceSymbol = moduleSymbol.GlobalNamespace; } var types = GetTypes(namespaceSymbol) .OfType <INamedTypeSymbol>() .Where(t => t.CanBeReferencedByName); var tempDocument = projectWithReference.AddDocument("temp", SourceText.From(""), null); var metadataAsSourceService = WorkspaceHacks.GetMetadataAsSourceService(tempDocument); if (addSourceToAsync == null) { addSourceToAsync = ReflectAddSourceToAsync(metadataAsSourceService); } var texts = new Dictionary <INamedTypeSymbol, string>(); Parallel.ForEach( types, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, type => { try { string text = ""; if (Configuration.GenerateMetadataAsSourceBodies) { var document = addSourceToAsync( tempDocument, type, CancellationToken.None).Result; text = document.GetTextAsync().Result.ToString(); } lock (texts) { texts.Add(type, text); } } catch (Exception ex) { Log.Exception(ex, "Error when adding a MAS document to texts: " + assemblyFilePath); } }); HashSet <string> existingFileNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (var kvp in texts) { var tempProject = AddDocument(project, kvp, existingFileNames); // tempProject can be null if the document was in an unutterable namespace // we want to skip such documents if (tempProject != null) { project = tempProject; } } project = project.AddDocument( "AssemblyAttributes.cs", assemblyAttributesFileText).Project; solution = project.Solution; return(solution); } } catch (Exception ex) { Log.Exception(ex, "Failed to run metadata as source for: " + assemblyFilePath); return(null); } }