/// <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()); }
internal EmitBaseline With( Compilation compilation, CommonPEModuleBuilder moduleBuilder, 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, IReadOnlyDictionary <MethodImplKey, uint> methodImplsAdded, ImmutableArray <int> tableEntriesAdded, int blobStreamLengthAdded, int stringStreamLengthAdded, int userStringStreamLengthAdded, int guidStreamLengthAdded, IReadOnlyDictionary <AnonymousTypeKey, AnonymousTypeValue> anonymousTypeMap, IReadOnlyDictionary <uint, ImmutableArray <EncLocalInfo> > localsForMethodsAddedOrChanged, LocalVariableNameProvider localNames) { Debug.Assert((this.AnonymousTypeMap == null) || (anonymousTypeMap != null)); Debug.Assert((this.AnonymousTypeMap == null) || (anonymousTypeMap.Count >= this.AnonymousTypeMap.Count)); return(new EmitBaseline( this.OriginalMetadata, compilation, moduleBuilder, this.ModuleVersionId, ordinal, encId, typesAdded, eventsAdded, fieldsAdded, methodsAdded, propertiesAdded, eventMapAdded, propertyMapAdded, methodImplsAdded, tableEntriesAdded, blobStreamLengthAdded: blobStreamLengthAdded, stringStreamLengthAdded: stringStreamLengthAdded, userStringStreamLengthAdded: userStringStreamLengthAdded, guidStreamLengthAdded: guidStreamLengthAdded, anonymousTypeMap: anonymousTypeMap, localsForMethodsAddedOrChanged: localsForMethodsAddedOrChanged, localNames: localNames, typeToEventMap: this.TypeToEventMap, typeToPropertyMap: this.TypeToPropertyMap, methodImpls: this.MethodImpls)); }
public void CreateInitialBaseline() { var provider = new LocalVariableNameProvider(_ => ImmutableArray.Create<string>()); var peModule = ModuleMetadata.CreateFromImage(TestResources.MetadataTests.Basic.Members); var peReader = peModule.Module.PEReaderOpt; var mdBytes = peReader.ReadAllMetadataBytes(); var mdBytesHandle = PinnedImmutableArray.Create(mdBytes); var mdModule = ModuleMetadata.CreateFromMetadata(mdBytesHandle.Pointer, mdBytes.Length); Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(null, provider)); Assert.Throws<ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(peModule, null)); Assert.Throws<ArgumentException>(() => EmitBaseline.CreateInitialBaseline(mdModule, provider)); }
public void CreateInitialBaseline() { var provider = new LocalVariableNameProvider(_ => ImmutableArray.Create <string>()); var peModule = ModuleMetadata.CreateFromImage(TestResources.MetadataTests.Basic.Members); var peReader = peModule.Module.PEReaderOpt; var mdBytes = peReader.GetMetadata().GetContent(); var mdBytesHandle = PinnedImmutableArray.Create(mdBytes); var mdModule = ModuleMetadata.CreateFromMetadata(mdBytesHandle.Pointer, mdBytes.Length); Assert.Throws <ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(null, provider)); Assert.Throws <ArgumentNullException>(() => EmitBaseline.CreateInitialBaseline(peModule, null)); Assert.Throws <ArgumentException>(() => EmitBaseline.CreateInitialBaseline(mdModule, provider)); }
/// <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))); }
/// <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. Only the /// initial baseline is created using this method; subsequent baselines are created /// automatically when emitting the differences in subsequent compilations. /// </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 EmitBaseline for the module.</returns> 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"); } return CreateInitialBaselineWithoutChecks(module, localNames); }
/// <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. Only the /// initial baseline is created using this method; subsequent baselines are created /// automatically when emitting the differences in subsequent compilations. /// </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 EmitBaseline for the module.</returns> 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"); } return(CreateInitialBaselineWithoutChecks(module, localNames)); }
internal EmitBaseline With( Compilation compilation, CommonPEModuleBuilder moduleBuilder, 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) { Debug.Assert((this.AnonymousTypeMap == null) || (anonymousTypeMap != null)); Debug.Assert((this.AnonymousTypeMap == null) || (anonymousTypeMap.Count >= this.AnonymousTypeMap.Count)); return new EmitBaseline( this.OriginalMetadata, compilation, moduleBuilder, this.ModuleVersionId, ordinal, encId, typesAdded, eventsAdded, fieldsAdded, methodsAdded, propertiesAdded, eventMapAdded, propertyMapAdded, tableEntriesAdded, blobStreamLengthAdded: blobStreamLengthAdded, stringStreamLengthAdded: stringStreamLengthAdded, userStringStreamLengthAdded: userStringStreamLengthAdded, guidStreamLengthAdded: guidStreamLengthAdded, anonymousTypeMap: anonymousTypeMap, localsForMethodsAddedOrChanged: localsForMethodsAddedOrChanged, localNames: localNames, typeToEventMap: this.TypeToEventMap, typeToPropertyMap: this.TypeToPropertyMap); }
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; }
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, IReadOnlyDictionary <MethodImplKey, uint> methodImplsAdded, 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, IReadOnlyDictionary <MethodImplKey, uint> methodImpls) { 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(moduleVersionId != default(Guid)); Debug.Assert(moduleVersionId == module.GetModuleVersionId()); 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.MethodImplsAdded = methodImplsAdded; 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; this.MethodImpls = methodImpls; }
/// <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())); }