/// <summary> /// Return a version of the baseline with all definitions mapped to this compilation. /// Definitions from the initial generation, from metadata, are not mapped since /// the initial generation is always included as metadata. That is, the symbols from /// types, methods, ... in the TypesAdded, MethodsAdded, ... collections are replaced /// by the corresponding symbols from the current compilation. /// </summary> private static EmitBaseline MapToCompilation( CSharpCompilation compilation, PEDeltaAssemblyBuilder moduleBeingBuilt) { var previousGeneration = moduleBeingBuilt.PreviousGeneration; RoslynDebug.Assert(previousGeneration.Compilation != compilation); if (previousGeneration.Ordinal == 0) { // Initial generation, nothing to map. (Since the initial generation // is always loaded from metadata in the context of the current // compilation, there's no separate mapping step.) return(previousGeneration); } RoslynDebug.AssertNotNull(previousGeneration.Compilation); RoslynDebug.AssertNotNull(previousGeneration.PEModuleBuilder); var currentSynthesizedMembers = moduleBeingBuilt.GetAllSynthesizedMembers(); // Mapping from previous compilation to the current. var anonymousTypeMap = moduleBeingBuilt.GetAnonymousTypeMap(); var synthesizedDelegates = moduleBeingBuilt.GetSynthesizedDelegates(); var sourceAssembly = ((CSharpCompilation)previousGeneration.Compilation).SourceAssembly; var sourceContext = new EmitContext((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag(), metadataOnly: false, includePrivateMembers: true); var otherContext = new EmitContext(moduleBeingBuilt, null, new DiagnosticBag(), metadataOnly: false, includePrivateMembers: true); var matcher = new CSharpSymbolMatcher( anonymousTypeMap, synthesizedDelegates, sourceAssembly, sourceContext, compilation.SourceAssembly, otherContext, currentSynthesizedMembers); var mappedSynthesizedMembers = matcher.MapSynthesizedMembers(previousGeneration.SynthesizedMembers, currentSynthesizedMembers); // TODO: can we reuse some data from the previous matcher? var matcherWithAllSynthesizedMembers = new CSharpSymbolMatcher( anonymousTypeMap, synthesizedDelegates, sourceAssembly, sourceContext, compilation.SourceAssembly, otherContext, mappedSynthesizedMembers); return(matcherWithAllSynthesizedMembers.MapBaselineToCompilation( previousGeneration, compilation, moduleBeingBuilt, mappedSynthesizedMembers)); }
/// <summary> /// Return a version of the baseline with all definitions mapped to this compilation. /// Definitions from the initial generation, from metadata, are not mapped since /// the initial generation is always included as metadata. That is, the symbols from /// types, methods, ... in the TypesAdded, MethodsAdded, ... collections are replaced /// by the corresponding symbols from the current compilation. /// </summary> private static EmitBaseline MapToCompilation( CSharpCompilation compilation, PEDeltaAssemblyBuilder moduleBeingBuilt) { var previousGeneration = moduleBeingBuilt.PreviousGeneration; Debug.Assert(previousGeneration.Compilation != compilation); if (previousGeneration.Ordinal == 0) { // Initial generation, nothing to map. (Since the initial generation // is always loaded from metadata in the context of the current // compilation, there's no separate mapping step.) return previousGeneration; } var currentSynthesizedMembers = moduleBeingBuilt.GetSynthesizedMembers(); // Mapping from previous compilation to the current. var anonymousTypeMap = moduleBeingBuilt.GetAnonymousTypeMap(); var sourceAssembly = ((CSharpCompilation)previousGeneration.Compilation).SourceAssembly; var sourceContext = new EmitContext((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag()); var otherContext = new EmitContext(moduleBeingBuilt, null, new DiagnosticBag()); var matcher = new CSharpSymbolMatcher( anonymousTypeMap, sourceAssembly, sourceContext, compilation.SourceAssembly, otherContext, currentSynthesizedMembers); var mappedSynthesizedMembers = matcher.MapSynthesizedMembers(previousGeneration.SynthesizedMembers, currentSynthesizedMembers); // TODO: can we reuse some data from the previos matcher? var matcherWithAllSynthesizedMembers = new CSharpSymbolMatcher( anonymousTypeMap, sourceAssembly, sourceContext, compilation.SourceAssembly, otherContext, mappedSynthesizedMembers); return matcherWithAllSynthesizedMembers.MapBaselineToCompilation( previousGeneration, compilation, moduleBeingBuilt, mappedSynthesizedMembers); }
/// <summary> /// Return a version of the baseline with all definitions mapped to this compilation. /// Definitions from the initial generation, from metadata, are not mapped since /// the initial generation is always included as metadata. That is, the symbols from /// types, methods, ... in the TypesAdded, MethodsAdded, ... collections are replaced /// by the corresponding symbols from the current compilation. /// </summary> private static EmitBaseline MapToCompilation( CSharpCompilation compilation, PEDeltaAssemblyBuilder moduleBeingBuilt) { var previousGeneration = moduleBeingBuilt.PreviousGeneration; Debug.Assert(previousGeneration.Compilation != compilation); if (previousGeneration.Ordinal == 0) { // Initial generation, nothing to map. (Since the initial generation // is always loaded from metadata in the context of the current // compilation, there's no separate mapping step.) return(previousGeneration); } var map = new SymbolMatcher( moduleBeingBuilt.GetAnonymousTypeMap(), ((CSharpCompilation)previousGeneration.Compilation).SourceAssembly, new EmitContext((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag()), compilation.SourceAssembly, new EmitContext((Cci.IModule)moduleBeingBuilt, null, new DiagnosticBag())); // Map all definitions to this compilation. var typesAdded = MapDefinitions(map, previousGeneration.TypesAdded); var eventsAdded = MapDefinitions(map, previousGeneration.EventsAdded); var fieldsAdded = MapDefinitions(map, previousGeneration.FieldsAdded); var methodsAdded = MapDefinitions(map, previousGeneration.MethodsAdded); var propertiesAdded = MapDefinitions(map, previousGeneration.PropertiesAdded); // Map anonymous types to this compilation. var anonymousTypeMap = new Dictionary <AnonymousTypeKey, AnonymousTypeValue>(); foreach (var pair in previousGeneration.AnonymousTypeMap) { var key = pair.Key; var value = pair.Value; var type = (Cci.ITypeDefinition)map.MapDefinition(value.Type); Debug.Assert(type != null); anonymousTypeMap.Add(key, new AnonymousTypeValue(value.Name, value.UniqueIndex, type)); } // Map locals (specifically, local types) to this compilation. var locals = new Dictionary <uint, ImmutableArray <EncLocalInfo> >(); foreach (var pair in previousGeneration.LocalsForMethodsAddedOrChanged) { locals.Add(pair.Key, pair.Value.SelectAsArray((l, m) => MapLocalInfo(m, l), map)); } return(previousGeneration.With( compilation, moduleBeingBuilt, previousGeneration.Ordinal, previousGeneration.EncId, typesAdded, eventsAdded, fieldsAdded, methodsAdded, propertiesAdded, eventMapAdded: previousGeneration.EventMapAdded, propertyMapAdded: previousGeneration.PropertyMapAdded, methodImplsAdded: previousGeneration.MethodImplsAdded, tableEntriesAdded: previousGeneration.TableEntriesAdded, blobStreamLengthAdded: previousGeneration.BlobStreamLengthAdded, stringStreamLengthAdded: previousGeneration.StringStreamLengthAdded, userStringStreamLengthAdded: previousGeneration.UserStringStreamLengthAdded, guidStreamLengthAdded: previousGeneration.GuidStreamLengthAdded, anonymousTypeMap: anonymousTypeMap, localsForMethodsAddedOrChanged: locals, localNames: previousGeneration.LocalNames)); }