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 documents to PDB for types that have no methods with IL #56278

Merged
merged 27 commits into from
Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
20ddc2e
Added new information to the Custom debug information table in the PD…
samaw7 Jun 3, 2021
6efc57d
Update PortableCustomDebugInfoKinds.cs
samaw7 Jun 3, 2021
5b37062
CLeanup
davidwengier Sep 9, 2021
9221f39
VB
davidwengier Sep 9, 2021
60d40b1
Tests
davidwengier Sep 9, 2021
d6fd6b4
Rename variables
davidwengier Sep 10, 2021
0e33168
Rename and null checks
davidwengier Sep 10, 2021
c89d418
Fix null ref for some synthesized members, and add tests
davidwengier Sep 10, 2021
6c7924a
Fix rebuild tests
davidwengier Sep 10, 2021
d823b7a
Use a list instead of a MultiDictionary, and pool some collections
davidwengier Sep 12, 2021
49af95e
Fix VB
davidwengier Sep 13, 2021
1c5f450
Remove optimization
davidwengier Sep 13, 2021
d53a61f
PR feedback
davidwengier Sep 15, 2021
c90e328
Revert changed lines
davidwengier Sep 16, 2021
611bcae
ImmutableArray all the things
davidwengier Sep 23, 2021
51740d6
Fix return type
davidwengier Sep 24, 2021
cff5094
Support nested classes
davidwengier Sep 24, 2021
86389fd
Fix doc comment
davidwengier Sep 24, 2021
3b9800f
More tests
davidwengier Sep 24, 2021
92ba815
Test, and fix, line directives
davidwengier Sep 24, 2021
9ae7f82
Remove redundant checks
davidwengier Sep 24, 2021
36947a6
Fix PDB tests
davidwengier Sep 24, 2021
754b1ba
Ignore line directives and always use original locations
davidwengier Sep 26, 2021
345d514
Never emit document info for nested types, but always consider method…
davidwengier Sep 26, 2021
ddedd69
PR feedback
davidwengier Sep 27, 2021
8d2c248
Update src/Compilers/VisualBasic/Portable/Emit/PEModuleBuilder.vb
davidwengier Sep 27, 2021
35d3832
Merge remote-tracking branch 'upstream/main' into MoreCustomDebugInfo
davidwengier Sep 27, 2021
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
115 changes: 115 additions & 0 deletions src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,121 @@ private void ValidateReferencedAssembly(AssemblySymbol assembly, AssemblyReferen
return null;
}

public sealed override IEnumerable<(Cci.ITypeDefinition, ImmutableArray<Cci.DebugSourceDocument>)> GetTypeToDebugDocumentMap(EmitContext context)
{
var typesToProcess = ArrayBuilder<Cci.ITypeDefinition>.GetInstance();
var debugDocuments = ArrayBuilder<Cci.DebugSourceDocument>.GetInstance();
var methodDocumentList = PooledHashSet<Cci.DebugSourceDocument>.GetInstance();

var namespacesAndTopLevelTypesToProcess = ArrayBuilder<NamespaceOrTypeSymbol>.GetInstance();
namespacesAndTopLevelTypesToProcess.Push(SourceModule.GlobalNamespace);
while (namespacesAndTopLevelTypesToProcess.Count > 0)
{
var symbol = namespacesAndTopLevelTypesToProcess.Pop();

switch (symbol.Kind)
{
case SymbolKind.Namespace:
var location = GetSmallestSourceLocationOrNull(symbol);

// filtering out synthesized symbols not having real source
// locations such as anonymous types, etc...
if (location != null)
{
foreach (var member in symbol.GetMembers())
{
switch (member.Kind)
{
case SymbolKind.Namespace:
case SymbolKind.NamedType:
namespacesAndTopLevelTypesToProcess.Push((NamespaceOrTypeSymbol)member);
break;
default:
throw ExceptionUtilities.UnexpectedValue(member.Kind);
}
}
}
break;
case SymbolKind.NamedType:
davidwengier marked this conversation as resolved.
Show resolved Hide resolved
Debug.Assert(debugDocuments.Count == 0);
Debug.Assert(methodDocumentList.Count == 0);
Debug.Assert(typesToProcess.Count == 0);

var typeDefinition = (Cci.ITypeDefinition)symbol.GetCciAdapter();
davidwengier marked this conversation as resolved.
Show resolved Hide resolved
typesToProcess.Push(typeDefinition);
GetDocumentsForMethodsAndNestedTypes(methodDocumentList, typesToProcess, context);

foreach (var loc in symbol.Locations)
{
if (!loc.IsInSource)
{
continue;
}

var span = loc.GetLineSpan();
var debugDocument = DebugDocumentsBuilder.TryGetDebugDocument(span.Path, basePath: null);

// If we have a debug document that is already referenced by method debug info in this type, or a nested type,
// then we don't need to include it. Since its impossible to declare a nested type without also including
// a declaration for its containing type, we don't need to consider nested types in this method itself.
if (debugDocument is not null && !methodDocumentList.Contains(debugDocument))
{
debugDocuments.Add(debugDocument);
}
}

if (debugDocuments.Count > 0)
{
yield return (typeDefinition, debugDocuments.ToImmutable());
}

debugDocuments.Clear();
methodDocumentList.Clear();
break;
default:
throw ExceptionUtilities.UnexpectedValue(symbol.Kind);
}
}

namespacesAndTopLevelTypesToProcess.Free();
debugDocuments.Free();
methodDocumentList.Free();
typesToProcess.Free();
}

/// <summary>
/// Gets a list of documents from the method definitions in the types in <paramref name="typesToProcess"/> or any
/// nested types of those types.
/// </summary>
private static void GetDocumentsForMethodsAndNestedTypes(PooledHashSet<Cci.DebugSourceDocument> documentList, ArrayBuilder<Cci.ITypeDefinition> typesToProcess, EmitContext context)
davidwengier marked this conversation as resolved.
Show resolved Hide resolved
{
while (typesToProcess.Count > 0)
{
var definition = typesToProcess.Pop();

var typeMethods = definition.GetMethods(context);
foreach (var method in typeMethods)
{
var body = method.GetBody(context);
if (body is null)
{
continue;
}

foreach (var point in body.SequencePoints)
{
documentList.Add(point.Document);
}
}

var nestedTypes = definition.GetNestedTypes(context);
foreach (var nestedTypeDefinition in nestedTypes)
{
typesToProcess.Push(nestedTypeDefinition);
}
}
}

public sealed override MultiDictionary<Cci.DebugSourceDocument, Cci.DefinitionWithLocation> GetSymbolToLocationMap()
{
var result = new MultiDictionary<Cci.DebugSourceDocument, Cci.DefinitionWithLocation>();
Expand Down
Loading