Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for embedding C# source in portable pdb #12353

Merged
merged 4 commits into from
Aug 11, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build/Targets/Dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<SystemDynamicRuntimeVersion>4.0.11</SystemDynamicRuntimeVersion>
<SystemGlobalizationVersion>4.0.11</SystemGlobalizationVersion>
<SystemIOVersion>4.1.0</SystemIOVersion>
<SystemIOCompressionVersion>4.1.0</SystemIOCompressionVersion>
<SystemIOFileSystemVersion>4.0.1</SystemIOFileSystemVersion>
<SystemIOFileSystemDriveInfoVersion>4.0.0</SystemIOFileSystemDriveInfoVersion>
<SystemIOFileSystemPrimitivesVersion>4.0.1</SystemIOFileSystemPrimitivesVersion>
Expand Down
9 changes: 9 additions & 0 deletions src/Compilers/CSharp/Portable/CSharpResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion src/Compilers/CSharp/Portable/CSharpResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -4407,6 +4407,8 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
/additionalfile:&lt;file list&gt; Additional files that don't directly affect code
generation but may be used by analyzers for producing
errors or warnings.
/embed Embed all source files in the PDB.
/embed:&lt;file list&gt; Embed specfic files the PDB

- RESOURCES -
/win32res:&lt;file&gt; Specify a Win32 resource file (.res)
Expand Down Expand Up @@ -4936,4 +4938,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="ERR_SourceLinkRequiresPortablePdb" xml:space="preserve">
<value>/sourcelink switch is only supported when emitting Portable PDB (/debug:portable or /debug:embedded must be specified).</value>
</data>
</root>
<data name="ERR_CannotEmbedWithoutPdb" xml:space="preserve">
<value>/embed switch is only supported when emitting Portable PDB (/debug:portable or /debug:embedded).</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable<string> ar
List<ResourceDescription> managedResources = new List<ResourceDescription>();
List<CommandLineSourceFile> sourceFiles = new List<CommandLineSourceFile>();
List<CommandLineSourceFile> additionalFiles = new List<CommandLineSourceFile>();
List<CommandLineSourceFile> embeddedFiles = new List<CommandLineSourceFile>();
bool sourceFilesSpecified = false;
bool embedAllSourceFiles = false;
bool resourcesOrModulesSpecified = false;
Encoding codepage = null;
var checksumAlgorithm = SourceHashAlgorithm.Sha1;
Expand Down Expand Up @@ -1097,7 +1099,17 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable<string> ar
continue;
}

additionalFiles.AddRange(ParseAdditionalFileArgument(value, baseDirectory, diagnostics));
additionalFiles.AddRange(ParseSeparatedFileArgument(value, baseDirectory, diagnostics));
continue;

case "embed":
if (string.IsNullOrEmpty(value))
{
embedAllSourceFiles = true;
continue;
}

embeddedFiles.AddRange(ParseSeparatedFileArgument(value, baseDirectory, diagnostics));
continue;
}
}
Expand Down Expand Up @@ -1161,11 +1173,26 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable<string> ar

if (sourceLink != null)
{
if (!emitPdb || debugInformationFormat != DebugInformationFormat.PortablePdb && debugInformationFormat != DebugInformationFormat.Embedded)
if (!emitPdb || !debugInformationFormat.IsPortable())
{
AddDiagnostic(diagnostics, ErrorCode.ERR_SourceLinkRequiresPortablePdb);
}
}

if (embedAllSourceFiles)
{
embeddedFiles.AddRange(sourceFiles);
}

if (embeddedFiles.Count > 0)
{
// Restricted to portable PDBs for now, but the IsPortable condition should be removed
// and the error message adjusted accordingly when native PDB support is added.
if (!emitPdb || !debugInformationFormat.IsPortable())
{
AddDiagnostic(diagnostics, ErrorCode.ERR_CannotEmbedWithoutPdb);
}
}

var parsedFeatures = CompilerOptionParseUtilities.ParseFeatures(features);

Expand Down Expand Up @@ -1273,7 +1300,8 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable<string> ar
PrintFullPaths = printFullPaths,
ShouldIncludeErrorEndLocation = errorEndLocation,
PreferredUILang = preferredUILang,
ReportAnalyzer = reportAnalyzer
ReportAnalyzer = reportAnalyzer,
EmbeddedFiles = embeddedFiles.AsImmutable()
};
}

Expand Down
36 changes: 35 additions & 1 deletion src/Compilers/CSharp/Portable/CommandLine/CSharpCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Microsoft.CodeAnalysis.CSharp
{
Expand Down Expand Up @@ -151,7 +153,7 @@ private SyntaxTree ParseFile(
out string normalizedFilePath)
{
var fileReadDiagnostics = new List<DiagnosticInfo>();
var content = ReadFileContent(file, fileReadDiagnostics, out normalizedFilePath);
var content = TryReadFileContent(file, fileReadDiagnostics, out normalizedFilePath);

if (content == null)
{
Expand Down Expand Up @@ -277,5 +279,37 @@ protected override ImmutableArray<DiagnosticAnalyzer> ResolveAnalyzersFromArgume
{
return Arguments.ResolveAnalyzersFromArguments(LanguageNames.CSharp, diagnostics, messageProvider, AssemblyLoader);
}

protected override void ResolveEmbeddedFilesFromExternalSourceDirectives(
SyntaxTree tree,
SourceReferenceResolver resolver,
OrderedSet<string> embeddedFiles,
IList<Diagnostic> diagnostics)
{
foreach (LineDirectiveTriviaSyntax directive in tree.GetRoot().GetDirectives(
d => d.IsActive && !d.HasErrors && d.Kind() == SyntaxKind.LineDirectiveTrivia))
{
string path = (string)directive.File.Value;
if (path == null)
{
continue;
}

string resolvedPath = resolver.ResolveReference(path, tree.FilePath);
if (resolvedPath == null)
{
diagnostics.Add(
MessageProvider.CreateDiagnostic(
(int)ErrorCode.ERR_NoSourceFile,
directive.File.GetLocation(),
path,
CSharpResources.CouldNotFindFile));

continue;
}

embeddedFiles.Add(resolvedPath);
}
}
}
}
15 changes: 11 additions & 4 deletions src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2222,6 +2222,7 @@ internal override CommonPEModuleBuilder CreateModuleBuilder(
EmitOptions emitOptions,
IMethodSymbol debugEntryPoint,
Stream sourceLinkStream,
IEnumerable<EmbeddedText> embeddedTexts,
IEnumerable<ResourceDescription> manifestResources,
CompilationTestData testData,
DiagnosticBag diagnostics,
Expand Down Expand Up @@ -2269,6 +2270,11 @@ internal override CommonPEModuleBuilder CreateModuleBuilder(

moduleBeingBuilt.SourceLinkStreamOpt = sourceLinkStream;

if (embeddedTexts != null)
{
moduleBeingBuilt.EmbeddedTexts = embeddedTexts;
}

// testData is only passed when running tests.
if (testData != null)
{
Expand Down Expand Up @@ -2314,7 +2320,8 @@ internal override bool CompileMethods(
}
else
{
if ((emittingPdb || emitOptions.EmitDynamicAnalysisData) && !StartSourceChecksumCalculation(moduleBeingBuilt.DebugDocumentsBuilder, diagnostics))
if ((emittingPdb || emitOptions.EmitDynamicAnalysisData) &&
!StartSourceChecksumCalculation(moduleBeingBuilt.DebugDocumentsBuilder, moduleBeingBuilt.EmbeddedTexts, diagnostics))
{
return false;
}
Expand Down Expand Up @@ -2491,11 +2498,11 @@ internal override void AddDebugSourceDocumentsForChecksumDirectives(
continue;
}

var checksumAndAlgorithm = existingDoc.ChecksumAndAlgorithm;
if (ChecksumMatches(checksumText, checksumAndAlgorithm.Item1))
var sourceInfo = existingDoc.GetSourceInfo();
if (ChecksumMatches(checksumText, sourceInfo.Checksum))
{
var guid = Guid.Parse(checksumDirective.Guid.ValueText);
if (guid == checksumAndAlgorithm.Item2)
if (guid == sourceInfo.ChecksumAlgorithmId)
{
// all parts match, nothing to do
continue;
Expand Down
3 changes: 2 additions & 1 deletion src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,8 @@ internal enum ErrorCode
ERR_InvalidDebugInformationFormat = 2042,
ERR_LegacyObjectIdSyntax = 2043,
ERR_SourceLinkRequiresPortablePdb = 2044,
// unused 2045-2999
ERR_CannotEmbedWithoutPdb = 2045,
// unused 2046-2999
WRN_CLS_NoVarArgs = 3000,
WRN_CLS_BadArgType = 3001, // Requires SymbolDistinguisher.
WRN_CLS_BadReturnType = 3002,
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/Errors/MessageProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ public override Diagnostic CreateDiagnostic(int code, Location location, params
return new CSDiagnostic(info, location);
}

public override Diagnostic CreateDiagnostic(DiagnosticInfo info)
{
return new CSDiagnostic(info, Location.None);
}

public override string GetErrorDisplayString(ISymbol symbol)
{
// show extra info for assembly if possible such as version, public key token etc.
Expand Down
Loading