提交 c90632cf 编写于 作者: C ChuckStoner

EnC: Nested types should be emitted in the same order in delta and full emit

Enumerate the set of top-level and nested types in the base PeWriter class.
 (changeset 1250804)
上级 cc4175ab
......@@ -716,6 +716,72 @@ static object F()
}
}
/// <summary>
/// Nested types should be emitted in the
/// same order as full emit.
/// </summary>
[Fact]
public void AddNestedTypesOrder()
{
var source0 =
@"class A
{
class B1
{
class C1 { }
}
class B2
{
class C2 { }
}
}";
var source1 =
@"class A
{
class B1
{
class C1 { }
}
class B2
{
class C2 { }
}
class B3
{
class C3 { }
}
class B4
{
class C4 { }
}
}";
var compilation0 = CreateCompilationWithMscorlib(source0, compOptions: TestOptions.UnoptimizedDll);
var compilation1 = CreateCompilationWithMscorlib(source1, compOptions: TestOptions.UnoptimizedDll);
var bytes0 = compilation0.EmitToArray(debug: true);
using (var md0 = ModuleMetadata.CreateFromImage(bytes0))
{
var reader0 = md0.MetadataReader;
CheckNames(reader0, reader0.GetTypeDefNames(), "<Module>", "A", "B1", "B2", "C1", "C2");
Assert.Equal(4, reader0.GetTableRowCount(TableIndex.NestedClass));
var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider);
var diff1 = compilation1.EmitDifference(
generation0,
ImmutableArray.Create(
new SemanticEdit(SemanticEditKind.Insert, null, compilation1.GetMember<NamedTypeSymbol>("A.B3")),
new SemanticEdit(SemanticEditKind.Insert, null, compilation1.GetMember<NamedTypeSymbol>("A.B4"))));
using (var md1 = diff1.GetMetadata())
{
var reader1 = md1.Reader;
var readers = new[] { reader0, reader1 };
CheckNames(readers, reader1.GetTypeDefNames(), "B3", "B4", "C3", "C4");
Assert.Equal(4, reader1.GetTableRowCount(TableIndex.NestedClass));
}
}
}
[Fact]
public void AddNestedGenericType()
{
......
......@@ -414,38 +414,19 @@ protected override IReadOnlyList<uint> GetStandAloneSignatures()
return this.standAloneSignatureIndex.Rows;
}
private IEnumerable<INamespaceTypeDefinition> GetTopLevelTypes()
protected override IEnumerable<INamespaceTypeDefinition> GetTopLevelTypes(IModule module)
{
return this.changes.GetTopLevelTypes(this.Context);
}
protected override void CreateIndicesForModule()
{
var typeDefs = ArrayBuilder<ITypeDefinition>.GetInstance();
this.GetTypesAndNestedTypes(typeDefs, this.GetTopLevelTypes());
foreach (var typeDef in typeDefs)
{
this.CreateIndicesForNonTypeMembers(typeDef);
}
typeDefs.Free();
base.CreateIndicesForModule();
var module = (IPEDeltaAssemblyBuilder)this.module;
module.OnCreatedIndices(this.Context.Diagnostics);
}
/// <summary>
/// Get the set of types and nested types, enclosing types first.
/// </summary>
private void GetTypesAndNestedTypes(ArrayBuilder<ITypeDefinition> builder, IEnumerable<ITypeDefinition> typeDefs)
{
foreach (var typeDef in typeDefs)
{
builder.Add(typeDef);
GetTypesAndNestedTypes(builder, typeDef.GetNestedTypes(this.Context));
}
}
private void CreateIndicesForNonTypeMembers(ITypeDefinition typeDef)
protected override void CreateIndicesForNonTypeMembers(ITypeDefinition typeDef)
{
switch (this.changes.GetChange(typeDef))
{
......@@ -1340,7 +1321,7 @@ public override void Visit(IAssembly assembly)
public override void Visit(IModule module)
{
this.module = module;
this.Visit(((DeltaPeWriter)this.peWriter).GetTopLevelTypes());
this.Visit(((DeltaPeWriter)this.peWriter).GetTopLevelTypes(module));
}
public override void Visit(IEventDefinition eventDefinition)
......
......@@ -347,37 +347,12 @@ protected override void PopulatePropertyMapTableRows(List<PropertyMapRow> table)
}
}
protected override void CreateIndicesForModule()
protected override IEnumerable<INamespaceTypeDefinition> GetTopLevelTypes(IModule module)
{
var nestedTypes = new Queue<ITypeDefinition>();
foreach (INamespaceTypeDefinition typeDef in this.module.GetTopLevelTypes(this.Context))
{
this.CreateIndicesFor(typeDef, nestedTypes);
}
while (nestedTypes.Count > 0)
{
this.CreateIndicesFor(nestedTypes.Dequeue(), nestedTypes);
}
}
private void CreateIndicesFor(ITypeDefinition typeDef, Queue<ITypeDefinition> nestedTypes)
{
this.cancellationToken.ThrowIfCancellationRequested();
this.CreateIndicesForNonTypeMembers(typeDef);
// Metadata spec:
// The TypeDef table has a special ordering constraint:
// the definition of an enclosing class shall precede the definition of all classes it encloses.
foreach (var nestedType in typeDef.GetNestedTypes(this.Context))
{
nestedTypes.Enqueue(nestedType);
}
return module.GetTopLevelTypes(this.Context);
}
private void CreateIndicesForNonTypeMembers(ITypeDefinition typeDef)
protected override void CreateIndicesForNonTypeMembers(ITypeDefinition typeDef)
{
this.typeDefs.Add(typeDef);
......
......@@ -386,6 +386,10 @@ protected Guid ModuleVersionId
/// </summary>
protected abstract IReadOnlyList<uint> GetStandAloneSignatures();
protected abstract IEnumerable<INamespaceTypeDefinition> GetTopLevelTypes(IModule module);
protected abstract void CreateIndicesForNonTypeMembers(ITypeDefinition typeDef);
/// <summary>
/// Offset into full metadata blob stream.
/// </summary>
......@@ -443,7 +447,7 @@ protected virtual void OnSerializedMetadataTables()
// If true, it is allowed to have methods not have bodies (for emitting metadata-only
// assembly)
internal readonly bool allowMissingMethodBodies;
protected readonly CancellationToken cancellationToken;
private readonly CancellationToken cancellationToken;
protected readonly IModule module;
public readonly EmitContext Context;
private readonly CommonMessageProvider messageProvider;
......@@ -1086,7 +1090,35 @@ private void CreateUserStringIndices()
}
}
protected abstract void CreateIndicesForModule();
protected virtual void CreateIndicesForModule()
{
var nestedTypes = new Queue<ITypeDefinition>();
foreach (INamespaceTypeDefinition typeDef in this.GetTopLevelTypes(this.module))
{
this.CreateIndicesFor(typeDef, nestedTypes);
}
while (nestedTypes.Count > 0)
{
this.CreateIndicesFor(nestedTypes.Dequeue(), nestedTypes);
}
}
private void CreateIndicesFor(ITypeDefinition typeDef, Queue<ITypeDefinition> nestedTypes)
{
this.cancellationToken.ThrowIfCancellationRequested();
this.CreateIndicesForNonTypeMembers(typeDef);
// Metadata spec:
// The TypeDef table has a special ordering constraint:
// the definition of an enclosing class shall precede the definition of all classes it encloses.
foreach (var nestedType in typeDef.GetNestedTypes(Context))
{
nestedTypes.Enqueue(nestedType);
}
}
protected IEnumerable<IGenericTypeParameter> GetConsolidatedTypeParameters(ITypeDefinition typeDef)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册