예제 #1
0
        /// <summary>
        /// Entrypoint for the <see cref="T:Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.CSharpExpressionCompiler"/>.
        /// </summary>
        internal static EmitBaseline CreateInitialBaselineWithoutChecks(ModuleMetadata module, LocalVariableNameProvider localNames)
        {
            var reader = module.MetadataReader;
            var moduleVersionId = module.GetModuleVersionId();

            return new EmitBaseline(
                module,
                compilation: null,
                moduleBuilder: null,
                moduleVersionId: moduleVersionId,
                ordinal: 0,
                encId: default(Guid),
                typesAdded: new Dictionary<ITypeDefinition, uint>(),
                eventsAdded: new Dictionary<IEventDefinition, uint>(),
                fieldsAdded: new Dictionary<IFieldDefinition, uint>(),
                methodsAdded: new Dictionary<IMethodDefinition, uint>(),
                propertiesAdded: new Dictionary<IPropertyDefinition, uint>(),
                eventMapAdded: new Dictionary<uint, uint>(),
                propertyMapAdded: new Dictionary<uint, uint>(),
                tableEntriesAdded: EmptyTableSizes,
                blobStreamLengthAdded: 0,
                stringStreamLengthAdded: 0,
                userStringStreamLengthAdded: 0,
                guidStreamLengthAdded: 0,
                anonymousTypeMap: null, // Unset for initial metadata
                localsForMethodsAddedOrChanged: new Dictionary<uint, ImmutableArray<EncLocalInfo>>(),
                localNames: localNames,
                typeToEventMap: reader.CalculateTypeEventMap(),
                typeToPropertyMap: reader.CalculateTypePropertyMap());
        }
예제 #2
0
        /// <summary>
        /// Creates an <see cref="EmitBaseline"/> from the metadata of the module before editing
        /// and from a function that maps from a method to an array of local names.
        /// </summary>
        /// <param name="module">The metadata of the module before editing.</param>
        /// <param name="debugInformationProvider">
        /// A function that for a method handle returns Edit and Continue debug information emitted by the compiler into the PDB.
        /// The function shall throw <see cref="InvalidDataException"/> if the debug information can't be read for the specified method.
        /// This exception and <see cref="IOException"/> are caught and converted to an emit diagnostic. Other exceptions are passed through.
        /// </param>
        /// <param name="localSignatureProvider">
        /// A function that for a method handle returns the signature of its local variables.
        /// The function shall throw <see cref="InvalidDataException"/> if the information can't be read for the specified method.
        /// This exception and <see cref="IOException"/> are caught and converted to an emit diagnostic. Other exceptions are passed through.
        /// </param>
        /// <param name="hasPortableDebugInformation">
        /// True if the baseline PDB is portable.
        /// </param>
        /// <returns>An <see cref="EmitBaseline"/> for the module.</returns>
        /// <remarks>
        /// Only the initial baseline is created using this method; subsequent baselines are created
        /// automatically when emitting the differences in subsequent compilations.
        ///
        /// When an active method (one for which a frame is allocated on a stack) is updated the values of its local variables need to be preserved.
        /// The mapping of local variable names to their slots in the frame is not included in the metadata and thus needs to be provided by
        /// <paramref name="debugInformationProvider"/>.
        ///
        /// The <paramref name="debugInformationProvider"/> is only needed for the initial generation. The mapping for the subsequent generations
        /// is carried over through <see cref="EmitBaseline"/>. The compiler assigns slots to named local variables (including named temporary variables)
        /// it the order in which they appear in the source code. This property allows the compiler to reconstruct the local variable mapping
        /// for the initial generation. A subsequent generation may add a new variable in between two variables of the previous generation.
        /// Since the slots of the previous generation variables need to be preserved the only option is to add these new variables to the end.
        /// The slot ordering thus no longer matches the syntax ordering. It is therefore necessary to pass <see cref="EmitDifferenceResult.Baseline"/>
        /// to the next generation (rather than e.g. create new <see cref="EmitBaseline"/>s from scratch based on metadata produced by subsequent compilations).
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="module"/> is null.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="debugInformationProvider"/> is null.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="localSignatureProvider"/> is null.</exception>
        /// <exception cref="IOException">Error reading module metadata.</exception>
        /// <exception cref="BadImageFormatException">Module metadata is invalid.</exception>
        /// <exception cref="ObjectDisposedException">Module has been disposed.</exception>
        internal static EmitBaseline CreateInitialBaseline(
            ModuleMetadata module,
            Func <MethodDefinitionHandle, EditAndContinueMethodDebugInformation> debugInformationProvider,
            Func <MethodDefinitionHandle, StandaloneSignatureHandle> localSignatureProvider,
            bool hasPortableDebugInformation)
        {
            if (module == null)
            {
                throw new ArgumentNullException(nameof(module));
            }

            if (debugInformationProvider == null)
            {
                throw new ArgumentNullException(nameof(debugInformationProvider));
            }

            if (localSignatureProvider == null)
            {
                throw new ArgumentNullException(nameof(localSignatureProvider));
            }

            var reader = module.MetadataReader;

            return(new EmitBaseline(
                       null,
                       module,
                       compilation: null,
                       moduleBuilder: null,
                       moduleVersionId: module.GetModuleVersionId(),
                       ordinal: 0,
                       encId: default,
예제 #3
0
        /// <summary>
        /// Entrypoint for the <see cref="T:Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.CSharpExpressionCompiler"/>.
        /// </summary>
        internal static EmitBaseline CreateInitialBaselineWithoutChecks(ModuleMetadata module, LocalVariableNameProvider localNames)
        {
            var reader          = module.MetadataReader;
            var moduleVersionId = module.GetModuleVersionId();

            return(new EmitBaseline(
                       module,
                       compilation: null,
                       moduleBuilder: null,
                       moduleVersionId: moduleVersionId,
                       ordinal: 0,
                       encId: default(Guid),
                       typesAdded: new Dictionary <ITypeDefinition, uint>(),
                       eventsAdded: new Dictionary <IEventDefinition, uint>(),
                       fieldsAdded: new Dictionary <IFieldDefinition, uint>(),
                       methodsAdded: new Dictionary <IMethodDefinition, uint>(),
                       propertiesAdded: new Dictionary <IPropertyDefinition, uint>(),
                       eventMapAdded: new Dictionary <uint, uint>(),
                       propertyMapAdded: new Dictionary <uint, uint>(),
                       tableEntriesAdded: EmptyTableSizes,
                       blobStreamLengthAdded: 0,
                       stringStreamLengthAdded: 0,
                       userStringStreamLengthAdded: 0,
                       guidStreamLengthAdded: 0,
                       anonymousTypeMap: null, // Unset for initial metadata
                       localsForMethodsAddedOrChanged: new Dictionary <uint, ImmutableArray <EncLocalInfo> >(),
                       localNames: localNames,
                       typeToEventMap: reader.CalculateTypeEventMap(),
                       typeToPropertyMap: reader.CalculateTypePropertyMap()));
        }
예제 #4
0
        /// <summary>
        /// Creates an <see cref="EmitBaseline"/> from the metadata of the module before editing
        /// and from a function that maps from a method to an array of local names.
        /// </summary>
        /// <param name="module">The metadata of the module before editing.</param>
        /// <param name="debugInformationProvider">
        /// A function that for a method handle returns Edit and Continue debug information emitted by the compiler into the PDB.
        /// The function shall throw <see cref="System.IO.InvalidDataException"/> if the debug information can't be read for the specified method.
        /// This exception is caught and converted to an emit diagnostic. Other exceptions are passed through.
        /// </param>
        /// <returns>An <see cref="EmitBaseline"/> for the module.</returns>
        /// <remarks>
        /// Only the initial baseline is created using this method; subsequent baselines are created
        /// automatically when emitting the differences in subsequent compilations.
        ///
        /// When an active method (one for which a frame is allocated on a stack) is updated the values of its local variables need to be preserved.
        /// The mapping of local variable names to their slots in the frame is not included in the metadata and thus needs to be provided by
        /// <paramref name="debugInformationProvider"/>.
        ///
        /// The <paramref name="debugInformationProvider"/> is only needed for the initial generation. The mapping for the subsequent generations
        /// is carried over through <see cref="EmitBaseline"/>. The compiler assigns slots to named local variables (including named temporary variables)
        /// it the order in which they appear in the source code. This property allows the compiler to reconstruct the local variable mapping
        /// for the initial generation. A subsequent generation may add a new variable in between two variables of the previous generation.
        /// Since the slots of the previous generation variables need to be preserved the only option is to add these new variables to the end.
        /// The slot ordering thus no longer matches the syntax ordering. It is therefore necessary to pass <see cref="EmitDifferenceResult.Baseline"/>
        /// to the next generation (rather than e.g. create new <see cref="EmitBaseline"/>s from scratch based on metadata produced by subsequent compilations).
        /// </remarks>
        /// <exception cref="ArgumentException"><paramref name="module"/> is not a PE image.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="module"/> is null.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="debugInformationProvider"/> is null.</exception>
        /// <exception cref="IOException">Error reading module metadata.</exception>
        /// <exception cref="BadImageFormatException">Module metadata is invalid.</exception>
        /// <exception cref="ObjectDisposedException">Module has been disposed.</exception>
        public static EmitBaseline CreateInitialBaseline(ModuleMetadata module, Func <MethodDefinitionHandle, EditAndContinueMethodDebugInformation> debugInformationProvider)
        {
            if (module == null)
            {
                throw new ArgumentNullException(nameof(module));
            }

            if (!module.Module.HasIL)
            {
                throw new ArgumentException(CodeAnalysisResources.PEImageNotAvailable, nameof(module));
            }

            if (debugInformationProvider == null)
            {
                throw new ArgumentNullException(nameof(debugInformationProvider));
            }

            // module has IL as checked above and hence a PE reader:
            Debug.Assert(module.Module.PEReaderOpt != null);

            MetadataReader reader          = module.MetadataReader;
            Guid           moduleVersionId = module.GetModuleVersionId();
            bool           hasPortablePdb  = module.Module.PEReaderOpt.ReadDebugDirectory().Any(entry => entry.IsPortableCodeView);

            return(new EmitBaseline(
                       null,
                       module,
                       compilation: null,
                       moduleBuilder: null,
                       moduleVersionId: moduleVersionId,
                       ordinal: 0,
                       encId: default(Guid),
                       hasPortablePdb: hasPortablePdb,
                       typesAdded: new Dictionary <Cci.ITypeDefinition, int>(),
                       eventsAdded: new Dictionary <Cci.IEventDefinition, int>(),
                       fieldsAdded: new Dictionary <Cci.IFieldDefinition, int>(),
                       methodsAdded: new Dictionary <Cci.IMethodDefinition, int>(),
                       propertiesAdded: new Dictionary <Cci.IPropertyDefinition, int>(),
                       eventMapAdded: new Dictionary <int, int>(),
                       propertyMapAdded: new Dictionary <int, int>(),
                       methodImplsAdded: new Dictionary <MethodImplKey, int>(),
                       tableEntriesAdded: s_emptyTableSizes,
                       blobStreamLengthAdded: 0,
                       stringStreamLengthAdded: 0,
                       userStringStreamLengthAdded: 0,
                       guidStreamLengthAdded: 0,
                       anonymousTypeMap: null, // Unset for initial metadata
                       synthesizedMembers: ImmutableDictionary <Cci.ITypeDefinition, ImmutableArray <Cci.ITypeDefinitionMember> > .Empty,
                       methodsAddedOrChanged: new Dictionary <int, AddedOrChangedMethodInfo>(),
                       debugInformationProvider: debugInformationProvider,
                       typeToEventMap: CalculateTypeEventMap(reader),
                       typeToPropertyMap: CalculateTypePropertyMap(reader),
                       methodImpls: CalculateMethodImpls(reader)));
        }
예제 #5
0
        /// <summary>
        /// Creates an <see cref="EmitBaseline"/> from the metadata of the module before editing
        /// and from a function that maps from a method to an array of local names.
        /// </summary>
        /// <param name="module">The metadata of the module before editing.</param>
        /// <param name="localNames">
        /// A function that returns the array of local names given a method index from the module metadata.
        /// </param>
        /// <returns>An <see cref="EmitBaseline"/> for the module.</returns>
        /// <remarks>
        /// Only the initial baseline is created using this method; subsequent baselines are created
        /// automatically when emitting the differences in subsequent compilations.
        ///
        /// When an active method (one for which a frame is allocated on a stack) is updated the values of its local variables need to be preserved.
        /// The mapping of local variable names to their slots in the frame is not included in the metadata and thus needs to be provided by
        /// <paramref name="localNames"/>.
        ///
        /// The <see cref="LocalVariableNameProvider"/> is only needed for the initial generation. The mapping for the subsequent generations
        /// is carried over through <see cref="EmitBaseline"/>. The compiler assigns slots to named local variables (including named temporary variables)
        /// it the order in which they appear in the source code. This property allows the compiler to reconstruct the local variable mapping
        /// for the initial generation. A subsequent generation may add a new variable in between two variables of the previous generation.
        /// Since the slots of the previous generation variables need to be preserved the only option is to add these new variables to the end.
        /// The slot ordering thus no longer matches the syntax ordering. It is therefore necessary to pass <see cref="EmitDifferenceResult.Baseline"/>
        /// to the next generation (rather than e.g. create new <see cref="EmitBaseline"/>s from scratch based on metadata produced by subsequent compilations).
        /// </remarks>
        public static EmitBaseline CreateInitialBaseline(ModuleMetadata module, LocalVariableNameProvider localNames)
        {
            if (module == null)
            {
                throw new ArgumentNullException("module");
            }

            if (!module.Module.HasIL)
            {
                throw new ArgumentException(CodeAnalysisResources.PEImageNotAvailable, "module");
            }

            if (localNames == null)
            {
                throw new ArgumentNullException("localNames");
            }

            var reader          = module.MetadataReader;
            var moduleVersionId = module.GetModuleVersionId();

            return(new EmitBaseline(
                       module,
                       compilation: null,
                       moduleBuilder: null,
                       moduleVersionId: moduleVersionId,
                       ordinal: 0,
                       encId: default(Guid),
                       typesAdded: new Dictionary <ITypeDefinition, uint>(),
                       eventsAdded: new Dictionary <IEventDefinition, uint>(),
                       fieldsAdded: new Dictionary <IFieldDefinition, uint>(),
                       methodsAdded: new Dictionary <IMethodDefinition, uint>(),
                       propertiesAdded: new Dictionary <IPropertyDefinition, uint>(),
                       eventMapAdded: new Dictionary <uint, uint>(),
                       propertyMapAdded: new Dictionary <uint, uint>(),
                       methodImplsAdded: new Dictionary <MethodImplKey, uint>(),
                       tableEntriesAdded: EmptyTableSizes,
                       blobStreamLengthAdded: 0,
                       stringStreamLengthAdded: 0,
                       userStringStreamLengthAdded: 0,
                       guidStreamLengthAdded: 0,
                       anonymousTypeMap: null, // Unset for initial metadata
                       localsForMethodsAddedOrChanged: new Dictionary <uint, ImmutableArray <EncLocalInfo> >(),
                       localNames: localNames,
                       typeToEventMap: reader.CalculateTypeEventMap(),
                       typeToPropertyMap: reader.CalculateTypePropertyMap(),
                       methodImpls: CalculateMethodImpls(reader)));
        }
예제 #6
0
        private EmitBaseline(
            ModuleMetadata module,
            Compilation compilation,
            CommonPEModuleBuilder moduleBuilder,
            Guid moduleVersionId,
            int ordinal,
            Guid encId,
            IReadOnlyDictionary<ITypeDefinition, uint> typesAdded,
            IReadOnlyDictionary<IEventDefinition, uint> eventsAdded,
            IReadOnlyDictionary<IFieldDefinition, uint> fieldsAdded,
            IReadOnlyDictionary<IMethodDefinition, uint> methodsAdded,
            IReadOnlyDictionary<IPropertyDefinition, uint> propertiesAdded,
            IReadOnlyDictionary<uint, uint> eventMapAdded,
            IReadOnlyDictionary<uint, uint> propertyMapAdded,
            ImmutableArray<int> tableEntriesAdded,
            int blobStreamLengthAdded,
            int stringStreamLengthAdded,
            int userStringStreamLengthAdded,
            int guidStreamLengthAdded,
            IReadOnlyDictionary<AnonymousTypeKey, AnonymousTypeValue> anonymousTypeMap,
            IReadOnlyDictionary<uint, ImmutableArray<EncLocalInfo>> localsForMethodsAddedOrChanged,
            LocalVariableNameProvider localNames,
            IReadOnlyDictionary<uint, uint> typeToEventMap,
            IReadOnlyDictionary<uint, uint> typeToPropertyMap)
        {
            Debug.Assert(module != null);
            Debug.Assert((ordinal == 0) == (encId == default(Guid)));
            Debug.Assert(encId != module.GetModuleVersionId());
            Debug.Assert(localNames != null);
            Debug.Assert(typeToEventMap != null);
            Debug.Assert(typeToPropertyMap != null);

            Debug.Assert(tableEntriesAdded.Length == MetadataTokens.TableCount);

            // The size of each table is the total number of entries added in all previous
            // generations after the initial generation. Depending on the table, some of the
            // entries may not be available in the current generation (say, a synthesized type
            // from a method that was not recompiled for instance)
            Debug.Assert(tableEntriesAdded[(int)TableIndex.TypeDef] >= typesAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.Event] >= eventsAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.Field] >= fieldsAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.MethodDef] >= methodsAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.Property] >= propertiesAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.EventMap] >= eventMapAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.PropertyMap] >= propertyMapAdded.Count);

            var reader = module.Module.MetadataReader;

            this.OriginalMetadata = module;
            this.Compilation = compilation;
            this.PEModuleBuilder = moduleBuilder;
            this.ModuleVersionId = moduleVersionId;
            this.Ordinal = ordinal;
            this.EncId = encId;

            this.TypesAdded = typesAdded;
            this.EventsAdded = eventsAdded;
            this.FieldsAdded = fieldsAdded;
            this.MethodsAdded = methodsAdded;
            this.PropertiesAdded = propertiesAdded;
            this.EventMapAdded = eventMapAdded;
            this.PropertyMapAdded = propertyMapAdded;
            this.TableEntriesAdded = tableEntriesAdded;
            this.BlobStreamLengthAdded = blobStreamLengthAdded;
            this.StringStreamLengthAdded = stringStreamLengthAdded;
            this.UserStringStreamLengthAdded = userStringStreamLengthAdded;
            this.GuidStreamLengthAdded = guidStreamLengthAdded;
            this.AnonymousTypeMap = anonymousTypeMap;
            this.LocalsForMethodsAddedOrChanged = localsForMethodsAddedOrChanged;

            this.LocalNames = localNames;
            this.TableSizes = CalculateTableSizes(reader, this.TableEntriesAdded);
            this.TypeToEventMap = typeToEventMap;
            this.TypeToPropertyMap = typeToPropertyMap;
        }
예제 #7
0
        private EmitBaseline(
            EmitBaseline initialBaseline,
            ModuleMetadata module,
            Compilation compilation,
            CommonPEModuleBuilder moduleBuilder,
            Guid moduleVersionId,
            int ordinal,
            Guid encId,
            IReadOnlyDictionary <Cci.ITypeDefinition, uint> typesAdded,
            IReadOnlyDictionary <Cci.IEventDefinition, uint> eventsAdded,
            IReadOnlyDictionary <Cci.IFieldDefinition, uint> fieldsAdded,
            IReadOnlyDictionary <Cci.IMethodDefinition, uint> methodsAdded,
            IReadOnlyDictionary <Cci.IPropertyDefinition, uint> propertiesAdded,
            IReadOnlyDictionary <uint, uint> eventMapAdded,
            IReadOnlyDictionary <uint, uint> propertyMapAdded,
            IReadOnlyDictionary <MethodImplKey, uint> methodImplsAdded,
            ImmutableArray <int> tableEntriesAdded,
            int blobStreamLengthAdded,
            int stringStreamLengthAdded,
            int userStringStreamLengthAdded,
            int guidStreamLengthAdded,
            IReadOnlyDictionary <AnonymousTypeKey, AnonymousTypeValue> anonymousTypeMap,
            ImmutableDictionary <Cci.ITypeDefinition, ImmutableArray <Cci.ITypeDefinitionMember> > synthesizedMembers,
            IReadOnlyDictionary <uint, AddedOrChangedMethodInfo> methodsAddedOrChanged,
            Func <MethodDefinitionHandle, EditAndContinueMethodDebugInformation> debugInformationProvider,
            IReadOnlyDictionary <uint, uint> typeToEventMap,
            IReadOnlyDictionary <uint, uint> typeToPropertyMap,
            IReadOnlyDictionary <MethodImplKey, uint> methodImpls)
        {
            Debug.Assert(module != null);
            Debug.Assert((ordinal == 0) == (encId == default(Guid)));
            Debug.Assert((ordinal == 0) == (initialBaseline == null));
            Debug.Assert(encId != module.GetModuleVersionId());
            Debug.Assert(debugInformationProvider != null);
            Debug.Assert(typeToEventMap != null);
            Debug.Assert(typeToPropertyMap != null);
            Debug.Assert(moduleVersionId != default(Guid));
            Debug.Assert(moduleVersionId == module.GetModuleVersionId());
            Debug.Assert(synthesizedMembers != null);

            Debug.Assert(tableEntriesAdded.Length == MetadataTokens.TableCount);

            // The size of each table is the total number of entries added in all previous
            // generations after the initial generation. Depending on the table, some of the
            // entries may not be available in the current generation (say, a synthesized type
            // from a method that was not recompiled for instance)
            Debug.Assert(tableEntriesAdded[(int)TableIndex.TypeDef] >= typesAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.Event] >= eventsAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.Field] >= fieldsAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.MethodDef] >= methodsAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.Property] >= propertiesAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.EventMap] >= eventMapAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.PropertyMap] >= propertyMapAdded.Count);

            var reader = module.Module.MetadataReader;

            this.InitialBaseline  = initialBaseline ?? this;
            this.OriginalMetadata = module;
            this.Compilation      = compilation;
            this.PEModuleBuilder  = moduleBuilder;
            this.ModuleVersionId  = moduleVersionId;
            this.Ordinal          = ordinal;
            this.EncId            = encId;

            this.TypesAdded                  = typesAdded;
            this.EventsAdded                 = eventsAdded;
            this.FieldsAdded                 = fieldsAdded;
            this.MethodsAdded                = methodsAdded;
            this.PropertiesAdded             = propertiesAdded;
            this.EventMapAdded               = eventMapAdded;
            this.PropertyMapAdded            = propertyMapAdded;
            this.MethodImplsAdded            = methodImplsAdded;
            this.TableEntriesAdded           = tableEntriesAdded;
            this.BlobStreamLengthAdded       = blobStreamLengthAdded;
            this.StringStreamLengthAdded     = stringStreamLengthAdded;
            this.UserStringStreamLengthAdded = userStringStreamLengthAdded;
            this.GuidStreamLengthAdded       = guidStreamLengthAdded;
            this._anonymousTypeMap           = anonymousTypeMap;
            this.SynthesizedMembers          = synthesizedMembers;
            this.AddedOrChangedMethods       = methodsAddedOrChanged;

            this.DebugInformationProvider = debugInformationProvider;
            this.TableSizes        = CalculateTableSizes(reader, this.TableEntriesAdded);
            this.TypeToEventMap    = typeToEventMap;
            this.TypeToPropertyMap = typeToPropertyMap;
            this.MethodImpls       = methodImpls;
        }
예제 #8
0
        private EmitBaseline(
            ModuleMetadata module,
            Compilation compilation,
            CommonPEModuleBuilder moduleBuilder,
            Guid moduleVersionId,
            int ordinal,
            Guid encId,
            IReadOnlyDictionary <ITypeDefinition, uint> typesAdded,
            IReadOnlyDictionary <IEventDefinition, uint> eventsAdded,
            IReadOnlyDictionary <IFieldDefinition, uint> fieldsAdded,
            IReadOnlyDictionary <IMethodDefinition, uint> methodsAdded,
            IReadOnlyDictionary <IPropertyDefinition, uint> propertiesAdded,
            IReadOnlyDictionary <uint, uint> eventMapAdded,
            IReadOnlyDictionary <uint, uint> propertyMapAdded,
            ImmutableArray <int> tableEntriesAdded,
            int blobStreamLengthAdded,
            int stringStreamLengthAdded,
            int userStringStreamLengthAdded,
            int guidStreamLengthAdded,
            IReadOnlyDictionary <AnonymousTypeKey, AnonymousTypeValue> anonymousTypeMap,
            IReadOnlyDictionary <uint, ImmutableArray <EncLocalInfo> > localsForMethodsAddedOrChanged,
            LocalVariableNameProvider localNames,
            IReadOnlyDictionary <uint, uint> typeToEventMap,
            IReadOnlyDictionary <uint, uint> typeToPropertyMap)
        {
            Debug.Assert(module != null);
            Debug.Assert((ordinal == 0) == (encId == default(Guid)));
            Debug.Assert(encId != module.GetModuleVersionId());
            Debug.Assert(localNames != null);
            Debug.Assert(typeToEventMap != null);
            Debug.Assert(typeToPropertyMap != null);

            Debug.Assert(tableEntriesAdded.Length == MetadataTokens.TableCount);

            // The size of each table is the total number of entries added in all previous
            // generations after the initial generation. Depending on the table, some of the
            // entries may not be available in the current generation (say, a synthesized type
            // from a method that was not recompiled for instance)
            Debug.Assert(tableEntriesAdded[(int)TableIndex.TypeDef] >= typesAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.Event] >= eventsAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.Field] >= fieldsAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.MethodDef] >= methodsAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.Property] >= propertiesAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.EventMap] >= eventMapAdded.Count);
            Debug.Assert(tableEntriesAdded[(int)TableIndex.PropertyMap] >= propertyMapAdded.Count);

            var reader = module.Module.MetadataReader;

            this.OriginalMetadata = module;
            this.Compilation      = compilation;
            this.PEModuleBuilder  = moduleBuilder;
            this.ModuleVersionId  = moduleVersionId;
            this.Ordinal          = ordinal;
            this.EncId            = encId;

            this.TypesAdded                     = typesAdded;
            this.EventsAdded                    = eventsAdded;
            this.FieldsAdded                    = fieldsAdded;
            this.MethodsAdded                   = methodsAdded;
            this.PropertiesAdded                = propertiesAdded;
            this.EventMapAdded                  = eventMapAdded;
            this.PropertyMapAdded               = propertyMapAdded;
            this.TableEntriesAdded              = tableEntriesAdded;
            this.BlobStreamLengthAdded          = blobStreamLengthAdded;
            this.StringStreamLengthAdded        = stringStreamLengthAdded;
            this.UserStringStreamLengthAdded    = userStringStreamLengthAdded;
            this.GuidStreamLengthAdded          = guidStreamLengthAdded;
            this.AnonymousTypeMap               = anonymousTypeMap;
            this.LocalsForMethodsAddedOrChanged = localsForMethodsAddedOrChanged;

            this.LocalNames        = localNames;
            this.TableSizes        = CalculateTableSizes(reader, this.TableEntriesAdded);
            this.TypeToEventMap    = typeToEventMap;
            this.TypeToPropertyMap = typeToPropertyMap;
        }