140 lines
8.7 KiB
C#
140 lines
8.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.IO;
|
|
using System.Reflection.Metadata;
|
|
using System.Threading;
|
|
using Microsoft.Cci;
|
|
using Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
using Microsoft.CodeAnalysis.CodeGen;
|
|
using Microsoft.CodeAnalysis.Collections;
|
|
using Microsoft.CodeAnalysis.Emit;
|
|
using Microsoft.CodeAnalysis.PooledObjects;
|
|
using Microsoft.CodeAnalysis.Symbols;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp.Emit;
|
|
|
|
internal static class EmitHelpers
|
|
{
|
|
internal static EmitDifferenceResult EmitDifference(CSharpCompilation compilation, EmitBaseline baseline, IEnumerable<SemanticEdit> edits, Func<ISymbol, bool> isAddedSymbol, Stream metadataStream, Stream ilStream, Stream pdbStream, CompilationTestData? testData, CancellationToken cancellationToken)
|
|
{
|
|
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00aa: Expected O, but got Unknown
|
|
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_018d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0193: Expected O, but got Unknown
|
|
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
|
|
DiagnosticBag instance = DiagnosticBag.GetInstance();
|
|
EmitOptions val = EmitOptions.Default.WithDebugInformationFormat((DebugInformationFormat)((!baseline.HasPortablePdb) ? 1 : 2));
|
|
string runtimeMetadataVersion = compilation.GetRuntimeMetadataVersion(val, instance);
|
|
ModulePropertiesForSerialization serializationProperties = ((Compilation)compilation).ConstructModuleSerializationProperties(val, runtimeMetadataVersion, baseline.ModuleVersionId);
|
|
IEnumerable<ResourceDescription> manifestResources = SpecializedCollections.EmptyEnumerable<ResourceDescription>();
|
|
PEDeltaAssemblyBuilder pEDeltaAssemblyBuilder;
|
|
try
|
|
{
|
|
pEDeltaAssemblyBuilder = new PEDeltaAssemblyBuilder(compilation.SourceAssembly, val, ((CompilationOptions)compilation.Options).OutputKind, serializationProperties, manifestResources, baseline, edits, isAddedSymbol);
|
|
}
|
|
catch (NotSupportedException ex)
|
|
{
|
|
instance.Add(ErrorCode.ERR_ModuleEmitFailure, NoLocation.Singleton, ((Compilation)compilation).AssemblyName, ex.Message);
|
|
return new EmitDifferenceResult(false, instance.ToReadOnlyAndFree(), (EmitBaseline)null, ImmutableArray<MethodDefinitionHandle>.Empty, ImmutableArray<TypeDefinitionHandle>.Empty);
|
|
}
|
|
if (testData != null)
|
|
{
|
|
((CommonPEModuleBuilder)pEDeltaAssemblyBuilder).SetTestData(testData);
|
|
}
|
|
CSharpDefinitionMap previousDefinitions = pEDeltaAssemblyBuilder.PreviousDefinitions;
|
|
SymbolChanges changes = ((CommonPEModuleBuilder)pEDeltaAssemblyBuilder).EncSymbolChanges;
|
|
EmitBaseline val2 = null;
|
|
ArrayBuilder<MethodDefinitionHandle> instance2 = ArrayBuilder<MethodDefinitionHandle>.GetInstance();
|
|
ArrayBuilder<TypeDefinitionHandle> instance3 = ArrayBuilder<TypeDefinitionHandle>.GetInstance();
|
|
if (((Compilation)compilation).Compile((CommonPEModuleBuilder)(object)pEDeltaAssemblyBuilder, true, instance, (Predicate<ISymbolInternal>)((ISymbolInternal s) => changes.RequiresCompilation(s.GetISymbol())), cancellationToken))
|
|
{
|
|
SynthesizedTypeMaps synthesizedTypes = baseline.SynthesizedTypes;
|
|
if (!ContainsPreviousAnonymousDelegates(previousDefinitions, ((SynthesizedTypeMaps)(ref synthesizedTypes)).AnonymousDelegatesWithIndexedNames, (IEnumerable<ITypeDefinition>)compilation.AnonymousTypeManager.GetCreatedAnonymousDelegateTypesWithIndexedNames()))
|
|
{
|
|
instance.Add(ErrorCode.ERR_EncUpdateFailedDelegateTypeChanged, Location.None);
|
|
}
|
|
else
|
|
{
|
|
EmitBaseline val3 = MapToCompilation(compilation, pEDeltaAssemblyBuilder);
|
|
val2 = ((Compilation)compilation).SerializeToDeltaStreams((CommonPEModuleBuilder)(object)pEDeltaAssemblyBuilder, val3, (DefinitionMap)(object)previousDefinitions, changes, metadataStream, ilStream, pdbStream, instance2, instance3, instance, testData?.SymWriterFactory, val.PdbFilePath, cancellationToken);
|
|
}
|
|
}
|
|
return new EmitDifferenceResult(val2 != null, instance.ToReadOnlyAndFree(), val2, instance2.ToImmutableAndFree(), instance3.ToImmutableAndFree());
|
|
}
|
|
|
|
private static bool ContainsPreviousAnonymousDelegates(CSharpDefinitionMap definitionMap, ImmutableSegmentedDictionary<string, AnonymousTypeValue> previousDictionary, IEnumerable<ITypeDefinition> currentTypes)
|
|
{
|
|
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
|
|
if (previousDictionary.Count == 0)
|
|
{
|
|
return true;
|
|
}
|
|
ImmutableDictionary<string, ITypeDefinition> immutableDictionary = currentTypes.ToImmutableDictionary(getName);
|
|
if (previousDictionary.Count > immutableDictionary.Count)
|
|
{
|
|
return false;
|
|
}
|
|
Enumerator<string, AnonymousTypeValue> enumerator = previousDictionary.GetEnumerator();
|
|
try
|
|
{
|
|
while (enumerator.MoveNext())
|
|
{
|
|
if (!immutableDictionary.TryGetValue(getName(enumerator.Current.Value.Type), out var value) || ((DefinitionMap)definitionMap).MapDefinition((IDefinition)(object)value) == null)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
((IDisposable)enumerator/*cast due to constrained. prefix*/).Dispose();
|
|
}
|
|
return true;
|
|
static string getName(ITypeDefinition type)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
return ((INamedEntity)type).Name;
|
|
}
|
|
}
|
|
|
|
private static EmitBaseline MapToCompilation(CSharpCompilation compilation, PEDeltaAssemblyBuilder moduleBeingBuilt)
|
|
{
|
|
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0055: Expected O, but got Unknown
|
|
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0065: Expected O, but got Unknown
|
|
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
|
|
EmitBaseline previousGeneration = ((CommonPEModuleBuilder)moduleBeingBuilt).PreviousGeneration;
|
|
if (previousGeneration.Ordinal == 0)
|
|
{
|
|
return previousGeneration;
|
|
}
|
|
SynthesizedTypeMaps synthesizedTypes = moduleBeingBuilt.GetSynthesizedTypes();
|
|
ImmutableDictionary<ISymbolInternal, ImmutableArray<ISymbolInternal>> allSynthesizedMembers = ((CommonPEModuleBuilder)moduleBeingBuilt).GetAllSynthesizedMembers();
|
|
ImmutableDictionary<ISymbolInternal, ImmutableArray<ISymbolInternal>> allDeletedMembers = ((CommonPEModuleBuilder)moduleBeingBuilt).EncSymbolChanges.GetAllDeletedMembers();
|
|
SourceAssemblySymbol sourceAssembly = ((CSharpCompilation)(object)previousGeneration.Compilation).SourceAssembly;
|
|
EmitContext sourceContext = default(EmitContext);
|
|
((EmitContext)(ref sourceContext))._002Ector((CommonPEModuleBuilder)(object)(PEModuleBuilder)(object)previousGeneration.PEModuleBuilder, (SyntaxNode)null, new DiagnosticBag(), false, true);
|
|
EmitContext otherContext = default(EmitContext);
|
|
((EmitContext)(ref otherContext))._002Ector((CommonPEModuleBuilder)(object)moduleBeingBuilt, (SyntaxNode)null, new DiagnosticBag(), false, true);
|
|
CSharpSymbolMatcher cSharpSymbolMatcher = new CSharpSymbolMatcher(sourceAssembly, sourceContext, compilation.SourceAssembly, otherContext, synthesizedTypes, allSynthesizedMembers, allDeletedMembers);
|
|
ImmutableDictionary<ISymbolInternal, ImmutableArray<ISymbolInternal>> immutableDictionary = ((SymbolMatcher)cSharpSymbolMatcher).MapSynthesizedOrDeletedMembers(previousGeneration.SynthesizedMembers, allSynthesizedMembers, false);
|
|
ImmutableDictionary<ISymbolInternal, ImmutableArray<ISymbolInternal>> immutableDictionary2 = ((SymbolMatcher)cSharpSymbolMatcher).MapSynthesizedOrDeletedMembers(previousGeneration.DeletedMembers, allDeletedMembers, true);
|
|
return ((SymbolMatcher)new CSharpSymbolMatcher(sourceAssembly, sourceContext, compilation.SourceAssembly, otherContext, synthesizedTypes, immutableDictionary, immutableDictionary2)).MapBaselineToCompilation(previousGeneration, (Compilation)(object)compilation, (CommonPEModuleBuilder)(object)moduleBeingBuilt, immutableDictionary, immutableDictionary2);
|
|
}
|
|
}
|