private ImmutableArray <EmbeddedText> AcquireEmbeddedTexts(Compilation compilation, IList <Diagnostic> diagnostics) { if (Arguments.EmbeddedFiles.IsEmpty) { return(ImmutableArray <EmbeddedText> .Empty); } var embeddedTreeMap = new Dictionary <string, SyntaxTree>(Arguments.EmbeddedFiles.Length); var embeddedFileOrderedSet = new OrderedSet <string>(Arguments.EmbeddedFiles.Select(e => e.Path)); foreach (var tree in compilation.SyntaxTrees) { // Skip trees that will not have their text embedded. if (!EmbeddedSourcePaths.Contains(tree.FilePath)) { continue; } // Skip trees with duplicated paths. (VB allows this and "first tree wins" is same as PDB emit policy.) if (embeddedTreeMap.ContainsKey(tree.FilePath)) { continue; } // map embedded file path to corresponding source tree embeddedTreeMap.Add(tree.FilePath, tree); // also embed the text of any #line directive targets of embedded tree ResolveEmbeddedFilesFromExternalSourceDirectives(tree, compilation.Options.SourceReferenceResolver, embeddedFileOrderedSet, diagnostics); } var embeddedTextBuilder = ImmutableArray.CreateBuilder <EmbeddedText>(embeddedFileOrderedSet.Count); foreach (var path in embeddedFileOrderedSet) { SyntaxTree tree; EmbeddedText text; if (embeddedTreeMap.TryGetValue(path, out tree)) { text = EmbeddedText.FromSource(path, tree.GetText()); Debug.Assert(text != null); } else { text = TryReadEmbeddedFileContent(path, diagnostics); Debug.Assert(text != null || diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error)); } // We can safely add nulls because result will be ignored if any error is produced. // This allows the MoveToImmutable to work below in all cases. embeddedTextBuilder.Add(text); } return(embeddedTextBuilder.MoveToImmutable()); }
/// <summary> /// Reads content of a source file. /// </summary> /// <param name="file">Source file information.</param> /// <param name="diagnostics">Storage for diagnostics.</param> /// <param name="normalizedFilePath">If given <paramref name="file"/> opens successfully, set to normalized absolute path of the file, null otherwise.</param> /// <returns>File content or null on failure.</returns> internal SourceText TryReadFileContent(CommandLineSourceFile file, IList <DiagnosticInfo> diagnostics, out string normalizedFilePath) { var filePath = file.Path; try { using (var data = OpenFileForReadWithSmallBufferOptimization(filePath)) { normalizedFilePath = data.Name; return(EncodedStringText.Create(data, Arguments.Encoding, Arguments.ChecksumAlgorithm, canBeEmbedded: EmbeddedSourcePaths.Contains(file.Path))); } } catch (Exception e) { diagnostics.Add(ToFileReadDiagnostics(this.MessageProvider, e, filePath)); normalizedFilePath = null; return(null); } }