WIP - embed source files into PDB · noahfalk/roslyn@e4e20bf (original) (raw)
8 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -160,7 +160,14 @@ private SyntaxTree ParseFile( | ||
160 | 160 | } |
161 | 161 | else |
162 | 162 | { |
163 | -return ParseFile(parseOptions, scriptParseOptions, content, file); | |
163 | +SyntaxTree tree = ParseFile(parseOptions, scriptParseOptions, content, file); | |
164 | +if(Arguments.EmbedSourceInPdb) | |
165 | +{ | |
166 | +SyntaxNode root = tree.GetRoot(); | |
167 | +root = root.WithAdditionalAnnotations(new SyntaxAnnotation("EmbedSourceInPdb")); | |
168 | +tree = tree.WithRootAndOptions(root, tree.Options); | |
169 | +} | |
170 | +return tree; | |
164 | 171 | } |
165 | 172 | } |
166 | 173 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -58,6 +58,7 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable ar | ||
58 | 58 | bool concurrentBuild = true; |
59 | 59 | bool emitPdb = false; |
60 | 60 | string pdbPath = null; |
61 | +bool embedSourceInPdb = false; | |
61 | 62 | bool noStdLib = false; |
62 | 63 | string outputDirectory = baseDirectory; |
63 | 64 | string outputFileName = null; |
@@ -971,6 +972,9 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable ar | ||
971 | 972 | |
972 | 973 | additionalFiles.AddRange(ParseAdditionalFileArgument(value, baseDirectory, diagnostics)); |
973 | 974 | continue; |
975 | +case "embedSource": | |
976 | +embedSourceInPdb = true; | |
977 | +continue; | |
974 | 978 | } |
975 | 979 | } |
976 | 980 | |
@@ -1102,6 +1106,7 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable ar | ||
1102 | 1106 | OutputFileName = outputFileName, |
1103 | 1107 | PdbPath = pdbPath, |
1104 | 1108 | EmitPdb = emitPdb, |
1109 | +EmbedSourceInPdb = embedSourceInPdb, | |
1105 | 1110 | OutputDirectory = outputDirectory, |
1106 | 1111 | DocumentationPath = documentationPath, |
1107 | 1112 | ErrorLogPath = errorLogPath, |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -2612,9 +2612,20 @@ private static ImmutableArray MakeChecksumBytes(string bytesText) | ||
2612 | 2612 | return builder.ToImmutableAndFree(); |
2613 | 2613 | } |
2614 | 2614 | |
2615 | +private static bool IsSyntaxTreePdbEmbedded(SyntaxTree tree) | |
2616 | +{ | |
2617 | +return tree.GetRoot().GetAnnotations().Any(a => a.Kind == "EmbedSourceInPdb"); | |
2618 | +} | |
2619 | + | |
2615 | 2620 | private static Cci.DebugSourceDocument MakeDebugSourceDocumentForTree(string normalizedPath, SyntaxTree tree) |
2616 | 2621 | { |
2617 | -return new Cci.DebugSourceDocument(normalizedPath, Cci.DebugSourceDocument.CorSymLanguageTypeCSharp, () => tree.GetChecksumAndAlgorithm()); | |
2622 | +byte[] pdbEmbeddedSourceBytes = null; | |
2623 | +if(IsSyntaxTreePdbEmbedded(tree)) | |
2624 | +{ | |
2625 | +SourceText text = tree.GetText(); | |
2626 | +pdbEmbeddedSourceBytes = text.Encoding.GetBytes(text.ToString()); | |
2627 | +} | |
2628 | +return new Cci.DebugSourceDocument(normalizedPath, Cci.DebugSourceDocument.CorSymLanguageTypeCSharp, () => tree.GetChecksumAndAlgorithm(), pdbEmbeddedSourceBytes); | |
2618 | 2629 | } |
2619 | 2630 | |
2620 | 2631 | private void SetupWin32Resources(PEModuleBuilder moduleBeingBuilt, Stream win32Resources, DiagnosticBag diagnostics) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -74,6 +74,11 @@ public abstract class CommandLineArguments | ||
74 | 74 | /// |
75 | 75 | public bool EmitPdb { get; internal set; } |
76 | 76 | |
77 | +/// |
|
78 | +/// True to embed source files in the PDB. | |
79 | +/// | |
80 | +public bool EmbedSourceInPdb { get; internal set; } | |
81 | + | |
77 | 82 | /// |
78 | 83 | /// Absolute path of the output directory. |
79 | 84 | /// |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -132,7 +132,8 @@ internal enum PdbWriterOperation : byte | ||
132 | 132 | DefineKickoffMethod, |
133 | 133 | OpenMapTokensToSourceSpans, |
134 | 134 | MapTokenToSourceSpan, |
135 | -CloseMapTokensToSourceSpans | |
135 | +CloseMapTokensToSourceSpans, | |
136 | +SetSource | |
136 | 137 | } |
137 | 138 | |
138 | 139 | public bool LogOperation(PdbWriterOperation op) |
@@ -949,6 +950,16 @@ private ISymUnmanagedDocumentWriter GetDocumentWriter(DebugSourceDocument docume | ||
949 | 950 | _callLogger.LogArgument(vendor.ToByteArray()); |
950 | 951 | _callLogger.LogArgument(type.ToByteArray()); |
951 | 952 | } |
953 | +if(document.EmbeddedSource != null) | |
954 | +{ | |
955 | +writer.SetSource((uint)document.EmbeddedSource.Length, document.EmbeddedSource); | |
956 | +if (_callLogger.LogOperation(OP.SetSource)) | |
957 | +{ | |
958 | +//logging length is irrelevant, it has no additional entropy | |
959 | +//for performance it might be better to log ChecksumAndAlgorithm instead? | |
960 | +_callLogger.LogArgument(document.EmbeddedSource); | |
961 | +} | |
962 | +} | |
952 | 963 | } |
953 | 964 | catch (Exception ex) |
954 | 965 | { |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -19,6 +19,7 @@ internal sealed class DebugSourceDocument | ||
19 | 19 | private readonly string _location; |
20 | 20 | private readonly Guid _language; |
21 | 21 | private readonly bool _isComputedChecksum; |
22 | +private readonly byte[] _embeddedSource; | |
22 | 23 | |
23 | 24 | private readonly Task<ValueTuple<ImmutableArray<byte>, Guid>> _checksumAndAlgorithm; |
24 | 25 | |
@@ -33,11 +34,12 @@ public DebugSourceDocument(string location, Guid language) | ||
33 | 34 | /// |
34 | 35 | /// Use to create a document when checksum is computed based on actual source stream. |
35 | 36 | /// |
36 | -public DebugSourceDocument(string location, Guid language, Func<ValueTuple<ImmutableArray<byte>, Guid>> checksumAndAlgorithm) | |
37 | +public DebugSourceDocument(string location, Guid language, Func<ValueTuple<ImmutableArray<byte>, Guid>> checksumAndAlgorithm, byte[] embeddedSource = null) | |
37 | 38 | : this(location, language) |
38 | 39 | { |
39 | 40 | _checksumAndAlgorithm = Task.Run(checksumAndAlgorithm); |
40 | 41 | _isComputedChecksum = true; |
42 | +_embeddedSource = embeddedSource; | |
41 | 43 | } |
42 | 44 | |
43 | 45 | /// |
@@ -108,6 +110,14 @@ public ValueTuple<ImmutableArray, Guid> ChecksumAndAlgorithm | ||
108 | 110 | } |
109 | 111 | } |
110 | 112 | |
113 | +public byte[] EmbeddedSource | |
114 | +{ | |
115 | +get | |
116 | +{ | |
117 | +return _embeddedSource; | |
118 | +} | |
119 | +} | |
120 | + | |
111 | 121 | /// |
112 | 122 | /// returns true when checksum was computed base on an actual source stream |
113 | 123 | /// as opposed to be suggested via a checksum directive/pragma |
@@ -119,5 +129,7 @@ internal bool IsComputedChecksum | ||
119 | 129 | return _isComputedChecksum; |
120 | 130 | } |
121 | 131 | } |
132 | + | |
133 | + | |
122 | 134 | } |
123 | 135 | } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
1 | 1 | *REMOVED*static Microsoft.CodeAnalysis.SyntaxNodeExtensions.NormalizeWhitespace(this TNode node, string indentation = " ", bool elasticTrivia = false) -> TNode |
2 | +Microsoft.CodeAnalysis.CommandLineArguments.EmbedSourceInPdb.get -> bool | |
2 | 3 | Microsoft.CodeAnalysis.CommandLineArguments.ScriptArguments.get -> System.Collections.Immutable.ImmutableArray |
3 | 4 | Microsoft.CodeAnalysis.CommandLineParser.IsInteractive.get -> bool |
4 | 5 | Microsoft.CodeAnalysis.Compilation.GetSubmissionResultType(out bool hasValue) -> Microsoft.CodeAnalysis.ITypeSymbol |