/// <summary> /// Capture the set of compilation options to allow a compilation /// to be reconstructed from the pdb /// </summary> private void EmbedCompilationOptions(CommonPEModuleBuilder module) { var builder = new BlobBuilder(); var compilerVersion = typeof(Compilation).Assembly.GetCustomAttribute <AssemblyInformationalVersionAttribute>().InformationalVersion; WriteValue(CompilationOptionNames.CompilerVersion, compilerVersion); WriteValue(CompilationOptionNames.Language, module.CommonCompilation.Options.Language); if (module.EmitOptions.FallbackSourceFileEncoding != null) { WriteValue(CompilationOptionNames.FallbackEncoding, module.EmitOptions.FallbackSourceFileEncoding.WebName); } if (module.EmitOptions.DefaultSourceFileEncoding != null) { WriteValue(CompilationOptionNames.DefaultEncoding, module.EmitOptions.DefaultSourceFileEncoding.WebName); } int portabilityPolicy = 0; if (module.CommonCompilation.Options.AssemblyIdentityComparer is DesktopAssemblyIdentityComparer identityComparer) { portabilityPolicy |= identityComparer.PortabilityPolicy.SuppressSilverlightLibraryAssembliesPortability ? 0b1 : 0; portabilityPolicy |= identityComparer.PortabilityPolicy.SuppressSilverlightPlatformAssembliesPortability ? 0b10 : 0; } if (portabilityPolicy != 0) { WriteValue(CompilationOptionNames.PortabilityPolicy, portabilityPolicy.ToString()); } var optimizationLevel = module.CommonCompilation.Options.OptimizationLevel; var debugPlusMode = module.CommonCompilation.Options.DebugPlusMode; if (optimizationLevel != OptimizationLevel.Debug || debugPlusMode) { WriteValue(CompilationOptionNames.Optimization, optimizationLevel.ToPdbSerializedString(debugPlusMode)); } var runtimeVersion = typeof(object).Assembly.GetCustomAttribute <AssemblyInformationalVersionAttribute>()?.InformationalVersion; WriteValue(CompilationOptionNames.RuntimeVersion, runtimeVersion); module.CommonCompilation.SerializePdbEmbeddedCompilationOptions(builder); _debugMetadataOpt.AddCustomDebugInformation( parent: EntityHandle.ModuleDefinition, kind: _debugMetadataOpt.GetOrAddGuid(PortableCustomDebugInfoKinds.CompilationOptions), value: _debugMetadataOpt.GetOrAddBlob(builder)); void WriteValue(string key, string value) { builder.WriteUTF8(key); builder.WriteByte(0); builder.WriteUTF8(value); builder.WriteByte(0); } }
internal static bool ShouldGenerateHashTableSwitch( CommonPEModuleBuilder module, int labelsCount ) { return(module.SupportsPrivateImplClass && ShouldGenerateHashTableSwitch(labelsCount)); }
private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBuilder) { var method = ((EEAssemblyBuilder)moduleBuilder).Methods.Single(m => m.MetadataName == MethodName); Debug.Assert(method.ContainingType.MetadataName == TypeName); return(method); }
internal PrivateImplementationDetails( CommonPEModuleBuilder moduleBuilder, string moduleName, int submissionSlotIndex, Cci.ITypeReference systemObject, Cci.ITypeReference systemValueType, Cci.ITypeReference systemInt8Type, Cci.ITypeReference systemInt16Type, Cci.ITypeReference systemInt32Type, Cci.ITypeReference systemInt64Type, Cci.ICustomAttribute compilerGeneratedAttribute) { Debug.Assert(systemObject != null); Debug.Assert(systemValueType != null); _moduleBuilder = moduleBuilder; _systemObject = systemObject; _systemValueType = systemValueType; _systemInt8Type = systemInt8Type; _systemInt16Type = systemInt16Type; _systemInt32Type = systemInt32Type; _systemInt64Type = systemInt64Type; _compilerGeneratedAttribute = compilerGeneratedAttribute; bool isNetModule = moduleBuilder.OutputKind == OutputKind.NetModule; _name = GetClassName(moduleName, submissionSlotIndex, isNetModule); }
private static ResourceSectionBuilder CreateNativeResourceSectionSerializer(CommonPEModuleBuilder module) { // Win32 resources are supplied to the compiler in one of two forms, .RES (the output of the resource compiler), // or .OBJ (the output of running cvtres.exe on a .RES file). A .RES file is parsed and processed into // a set of objects implementing IWin32Resources. These are then ordered and the final image form is constructed // and written to the resource section. Resources in .OBJ form are already very close to their final output // form. Rather than reading them and parsing them into a set of objects similar to those produced by // processing a .RES file, we process them like the native linker would, copy the relevant sections from // the .OBJ into our output and apply some fixups. var nativeResourceSectionOpt = module.Win32ResourceSection; if (nativeResourceSectionOpt != null) { return(new ResourceSectionBuilderFromObj(nativeResourceSectionOpt)); } var nativeResourcesOpt = module.Win32Resources; if (nativeResourcesOpt?.Any() == true) { return(new ResourceSectionBuilderFromResources(nativeResourcesOpt)); } return(null); }
internal static int CalculateStrongNameSignatureSize(CommonPEModuleBuilder module, RSAParameters?privateKey) { ISourceAssemblySymbolInternal assembly = module.SourceAssemblyOpt; if (assembly == null && !privateKey.HasValue) { return(0); } int keySize = 0; // EDMAURER the count of characters divided by two because the each pair of characters will turn in to one byte. if (keySize == 0 && assembly != null) { keySize = (assembly.SignatureKey == null) ? 0 : assembly.SignatureKey.Length / 2; } if (keySize == 0 && assembly != null) { keySize = assembly.Identity.PublicKey.Length; } if (keySize == 0 && privateKey.HasValue) { keySize = privateKey.Value.Modulus.Length; } if (keySize == 0) { return(0); } return((keySize < 128 + 32) ? 128 : keySize - 32); }
private void EmbedCompilationOptions(BlobReader?pdbCompilationOptionsReader, CommonPEModuleBuilder module) { var builder = new BlobBuilder(); if (pdbCompilationOptionsReader is { } reader) { builder.WriteBytes(reader.ReadBytes(reader.RemainingBytes)); }
public override void Visit(CommonPEModuleBuilder module) { //EDMAURER visit these assembly-level attributes even when producing a module. //They'll be attached off the "AssemblyAttributesGoHere" typeRef if a module is being produced. this.Visit(module.GetSourceAssemblyAttributes(Context.IsRefAssembly)); this.Visit(module.GetSourceAssemblySecurityAttributes()); this.Visit(module.GetSourceModuleAttributes()); }
private void EmbedCompilationOptions(CommonPEModuleBuilder module) { var builder = new BlobBuilder(); if (this.Context.RebuildData is { } rebuildData) { var reader = rebuildData.OptionsBlobReader; builder.WriteBytes(reader.ReadBytes(reader.RemainingBytes)); }
public override void Visit(CommonPEModuleBuilder module) { //EDMAURER visit these assembly-level attributes even when producing a module. //They'll be attached off the "AssemblyAttributesGoHere" typeRef if a module is being produced. this.Visit(module.GetSourceAssemblyAttributes()); this.Visit(module.GetSourceAssemblySecurityAttributes()); this.Visit(module.GetSourceModuleAttributes()); }
public EmitContext(CommonPEModuleBuilder module, SyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics) { Debug.Assert(module != null); Debug.Assert(diagnostics != null); Module = module; SyntaxNodeOpt = syntaxNodeOpt; Diagnostics = diagnostics; }
internal override bool GenerateResourcesAndDocumentationComments( CommonPEModuleBuilder moduleBuilder, Stream xmlDocStream, Stream win32Resources, string outputNameOverride, DiagnosticBag diagnostics, CancellationToken cancellationToken) { throw new NotImplementedException(); }
internal override bool CompileMethods(CommonPEModuleBuilder moduleBuilder, bool emittingPdb, bool emitMetadataOnly, bool emitTestCoverageData, DiagnosticBag diagnostics, Predicate <ISymbol> filterOpt, CancellationToken cancellationToken) { // The diagnostics should include syntax and declaration errors. We insert these before calling Emitter.Emit, so that the emitter // does not attempt to emit if there are declaration errors (but we do insert all errors from method body binding...) bool hasDeclarationErrors = false; // !FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, true, cancellationToken)); var moduleBeingBuilt = (PEModuleBuilder)moduleBuilder; if (emitMetadataOnly) { throw new NotImplementedException(); } if (emittingPdb) { if (!CreateDebugDocuments( moduleBeingBuilt.DebugDocumentsBuilder, moduleBeingBuilt.EmbeddedTexts.Concat(CollectAdditionalEmbeddedTexts()), diagnostics)) { return(false); } } // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag methodBodyDiagnosticBag = DiagnosticBag.GetInstance(); // Perform initial bind of method bodies in spite of earlier errors. This is the same // behavior as when calling GetDiagnostics() try { SourceCompiler.CompileSources( this, moduleBeingBuilt, emittingPdb, hasDeclarationErrors, methodBodyDiagnosticBag, cancellationToken); bool hasMethodBodyErrorOrWarningAsError = !FilterAndAppendAndFreeDiagnostics(diagnostics, ref methodBodyDiagnosticBag); if (hasDeclarationErrors || hasMethodBodyErrorOrWarningAsError) { return(false); } return(true); } catch (Exception ex) { this.TrackException(ex); throw; } }
internal override bool CompileMethods( CommonPEModuleBuilder moduleBuilder, bool emittingPdb, bool emitMetadataOnly, bool emitTestCoverageData, DiagnosticBag diagnostics, Predicate <ISymbol> filterOpt, CancellationToken cancellationToken) { throw new NotImplementedException(); }
public void GlobalSetup() { _peStream = new MemoryStream(); _comp = Helpers.CreateReproCompilation(); // Call GetDiagnostics to force binding to finish and most semantic analysis to be completed _ = _comp.GetDiagnostics(); if (Selection == EmitStageSelection.SerializeOnly) { _options = EmitOptions.Default.WithIncludePrivateMembers(true); bool embedPdb = _options.DebugInformationFormat == DebugInformationFormat.Embedded; var diagnostics = DiagnosticBag.GetInstance(); _moduleBeingBuilt = _comp.CheckOptionsAndCreateModuleBuilder( diagnostics, manifestResources: null, _options, debugEntryPoint: null, sourceLinkStream: null, embeddedTexts: null, testData: null, cancellationToken: default); bool success = false; success = _comp.CompileMethods( _moduleBeingBuilt, emittingPdb: embedPdb, emitMetadataOnly: _options.EmitMetadataOnly, emitTestCoverageData: _options.EmitTestCoverageData, diagnostics: diagnostics, filterOpt: null, cancellationToken: default); _comp.GenerateResourcesAndDocumentationComments( _moduleBeingBuilt, xmlDocumentationStream: null, win32ResourcesStream: null, _options.OutputNameOverride, diagnostics, cancellationToken: default); _comp.ReportUnusedImports(null, diagnostics, default); _moduleBeingBuilt.CompilationFinished(); diagnostics.Free(); } }
public void CompileMethods() { LoadCompilationAndGetDiagnostics(); _options = EmitOptions.Default.WithIncludePrivateMembers(true); bool embedPdb = _options.DebugInformationFormat == DebugInformationFormat.Embedded; var diagnostics = DiagnosticBag.GetInstance(); _moduleBeingBuilt = _comp.CheckOptionsAndCreateModuleBuilder( diagnostics, manifestResources: null, _options, debugEntryPoint: null, sourceLinkStream: null, embeddedTexts: null, testData: null, cancellationToken: default); bool success = false; success = _comp.CompileMethods( _moduleBeingBuilt, emittingPdb: embedPdb, emitMetadataOnly: _options.EmitMetadataOnly, emitTestCoverageData: _options.EmitTestCoverageData, diagnostics: diagnostics, filterOpt: null, cancellationToken: default); if (!success) { throw new InvalidOperationException("Did not successfully compile methods"); } _comp.GenerateResourcesAndDocumentationComments( _moduleBeingBuilt, xmlDocStream: null, win32Resources: null, _options.OutputNameOverride, diagnostics, cancellationToken: default); _comp.ReportUnusedImports(null, diagnostics, default); _moduleBeingBuilt.CompilationFinished(); diagnostics.Free(); }
internal override bool GenerateResourcesAndDocumentationComments(CommonPEModuleBuilder moduleBuilder, Stream xmlDocStream, Stream win32Resources, string outputNameOverride, DiagnosticBag diagnostics, CancellationToken cancellationToken) { // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag methodBodyDiagnosticBag = DiagnosticBag.GetInstance(); var moduleBeingBuilt = (PEModuleBuilder)moduleBuilder; try { SetupWin32Resources(moduleBeingBuilt, win32Resources, methodBodyDiagnosticBag); ReportManifestResourceDuplicates( moduleBeingBuilt.ManifestResources, SourceAssembly.Modules.Skip(1).Select((m) => m.Name), //all modules except the first one AddedModulesResourceNames(methodBodyDiagnosticBag), methodBodyDiagnosticBag); if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref methodBodyDiagnosticBag)) { return(false); } } catch (Exception ex) { this.TrackException(ex); throw; } cancellationToken.ThrowIfCancellationRequested(); // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag xmlDiagnostics = DiagnosticBag.GetInstance(); string assemblyName = FileNameUtilities.ChangeExtension(moduleBeingBuilt.EmitOptions.OutputNameOverride, extension: null); DocumentationCommentCompiler.WriteDocumentationCommentXml(this, assemblyName, xmlDocStream, xmlDiagnostics, cancellationToken); if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref xmlDiagnostics)) { return(false); } return(true); }
public override void Visit(CommonPEModuleBuilder module) { // Visit these assembly-level attributes even when producing a module. // They'll be attached off the "AssemblyAttributesGoHere" typeRef if a module is being produced. Visit(module.GetSourceAssemblyAttributes(Context.IsRefAssembly)); Visit(module.GetSourceAssemblySecurityAttributes()); Visit(module.GetAssemblyReferences(Context)); Visit(module.GetSourceModuleAttributes()); Visit(module.GetTopLevelTypes(Context)); foreach (var exportedType in module.GetExportedTypes(Context.Diagnostics)) { VisitExportedType(exportedType.Type); } Visit(module.GetResources(Context)); VisitImports(module.GetImports()); Visit(module.GetFiles(Context)); }
public override void Visit(CommonPEModuleBuilder module) { // Visit these assembly-level attributes even when producing a module. // They'll be attached off the "AssemblyAttributesGoHere" typeRef if a module is being produced. Visit(module.GetSourceAssemblyAttributes()); Visit(module.GetSourceAssemblySecurityAttributes()); Visit(module.GetAssemblyReferences(Context)); Visit(module.GetSourceModuleAttributes()); Visit(module.GetTopLevelTypes(Context)); foreach (var exportedType in module.GetExportedTypes(Context.Diagnostics)) { VisitExportedType(exportedType.Type); } Visit(module.GetResources(Context)); VisitImports(module.GetImports()); Visit(module.GetFiles(Context)); }
internal override bool CompileImpl(CommonPEModuleBuilder moduleBuilder, Stream win32Resources, Stream xmlDocStream, bool emittingPdb, DiagnosticBag diagnostics, Predicate<ISymbol> filterOpt, CancellationToken cancellationToken) { // The diagnostics should include syntax and declaration errors. We insert these before calling Emitter.Emit, so that the emitter // does not attempt to emit if there are declaration errors (but we do insert all errors from method body binding...) bool hasDeclarationErrors = false; // !FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, true, cancellationToken)); var moduleBeingBuilt = (PEModuleBuilder)moduleBuilder; if (moduleBeingBuilt.EmitOptions.EmitMetadataOnly) { throw new NotImplementedException(); } // Perform initial bind of method bodies in spite of earlier errors. This is the same // behavior as when calling GetDiagnostics() // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag methodBodyDiagnosticBag = DiagnosticBag.GetInstance(); SourceCompiler.CompileSources( this, moduleBeingBuilt, emittingPdb, hasDeclarationErrors, methodBodyDiagnosticBag, cancellationToken); SetupWin32Resources(moduleBeingBuilt, win32Resources, methodBodyDiagnosticBag); ReportManifestResourceDuplicates( moduleBeingBuilt.ManifestResources, SourceAssembly.Modules.Skip(1).Select((m) => m.Name), //all modules except the first one AddedModulesResourceNames(methodBodyDiagnosticBag), methodBodyDiagnosticBag); bool hasMethodBodyErrorOrWarningAsError = !FilterAndAppendAndFreeDiagnostics(diagnostics, ref methodBodyDiagnosticBag); if (hasDeclarationErrors || hasMethodBodyErrorOrWarningAsError) { return false; } cancellationToken.ThrowIfCancellationRequested(); // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag xmlDiagnostics = DiagnosticBag.GetInstance(); //string assemblyName = FileNameUtilities.ChangeExtension(moduleBeingBuilt.EmitOptions.OutputNameOverride, extension: null); //DocumentationCommentCompiler.WriteDocumentationCommentXml(this, assemblyName, xmlDocStream, xmlDiagnostics, cancellationToken); if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref xmlDiagnostics)) { return false; } //// Use a temporary bag so we don't have to refilter pre-existing diagnostics. //DiagnosticBag importDiagnostics = DiagnosticBag.GetInstance(); //this.ReportUnusedImports(importDiagnostics, cancellationToken); //if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref importDiagnostics)) //{ // Debug.Assert(false, "Should never produce an error"); // return false; //} return true; }
protected override IEnumerable <INamespaceTypeDefinition> GetTopLevelTypes(CommonPEModuleBuilder module) { return(module.GetTopLevelTypes(this.Context)); }
internal override bool Compile( CommonPEModuleBuilder moduleBuilder, string outputName, IEnumerable<ResourceDescription> manifestResources, Stream win32Resources, Stream xmlDocStream, CancellationToken cancellationToken, bool metadataOnly, bool generateDebugInfo, DiagnosticBag diagnostics, Predicate<ISymbol> filterOpt, bool hasDeclarationErrors) { // TODO (tomat): NoPIA: // EmbeddedSymbolManager.MarkAllDeferredSymbolsAsReferenced(this) var moduleBeingBuilt = (PEModuleBuilder)moduleBuilder; if (metadataOnly) { if (hasDeclarationErrors) { return false; } SynthesizedMetadataCompiler.ProcessSynthesizedMembers(this, moduleBeingBuilt, cancellationToken); } else { // start generating PDB checksums if we need to emit PDBs if (generateDebugInfo && moduleBeingBuilt != null) { // Add debug documents for all trees with distinct paths. foreach (var tree in this.syntaxTrees) { var path = tree.FilePath; if (!string.IsNullOrEmpty(path)) { // compilation does not guarantee that all trees will have distinct paths. // Do not attempt adding a document for a particular path if we already added one. string normalizedPath = moduleBeingBuilt.NormalizeDebugDocumentPath(path, basePath: null); var existingDoc = moduleBeingBuilt.TryGetDebugDocumentForNormalizedPath(normalizedPath); if (existingDoc == null) { moduleBeingBuilt.AddDebugDocument(MakeDebugSourceDocumentForTree(normalizedPath, tree)); } } } // Add debug documents for all pragmas. // If there are clashes with already processed directives, report warnings. // If there are clashes with debug documents that came from actual trees, ignore the pragma. foreach (var tree in this.syntaxTrees) { AddDebugSourceDocumentsForChecksumDirectives(moduleBeingBuilt, tree, diagnostics); } } // EDMAURER perform initial bind of method bodies in spite of earlier errors. This is the same // behavior as when calling GetDiagnostics() // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag methodBodyDiagnosticBag = DiagnosticBag.GetInstance(); MethodCompiler.CompileMethodBodies( this, moduleBeingBuilt, generateDebugInfo, hasDeclarationErrors, diagnostics: methodBodyDiagnosticBag, filterOpt: filterOpt, cancellationToken: cancellationToken); SetupWin32Resources(moduleBeingBuilt, win32Resources, methodBodyDiagnosticBag); ReportManifestResourceDuplicates( manifestResources, SourceAssembly.Modules.Skip(1).Select((m) => m.Name), //all modules except the first one AddedModulesResourceNames(methodBodyDiagnosticBag), methodBodyDiagnosticBag); bool hasMethodBodyErrorOrWarningAsError = !FilterAndAppendAndFreeDiagnostics(diagnostics, ref methodBodyDiagnosticBag); if (hasDeclarationErrors || hasMethodBodyErrorOrWarningAsError) { return false; } } cancellationToken.ThrowIfCancellationRequested(); // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag xmlDiagnostics = DiagnosticBag.GetInstance(); DocumentationCommentCompiler.WriteDocumentationCommentXml(this, outputName, xmlDocStream, xmlDiagnostics, cancellationToken); if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref xmlDiagnostics)) { return false; } // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag importDiagnostics = DiagnosticBag.GetInstance(); this.ReportUnusedImports(importDiagnostics, cancellationToken); if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref importDiagnostics)) { Debug.Assert(false, "Should never produce an error"); return false; } return true; }
public override abstract void Visit(CommonPEModuleBuilder module);
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; }
internal override bool CompileImpl(CommonPEModuleBuilder moduleBuilder, Stream win32Resources, Stream xmlDocStream, bool emittingPdb, DiagnosticBag diagnostics, Predicate <ISymbol> filterOpt, CancellationToken cancellationToken) { // The diagnostics should include syntax and declaration errors. We insert these before calling Emitter.Emit, so that the emitter // does not attempt to emit if there are declaration errors (but we do insert all errors from method body binding...) bool hasDeclarationErrors = false; // !FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, true, cancellationToken)); var moduleBeingBuilt = (PEModuleBuilder)moduleBuilder; if (moduleBeingBuilt.EmitOptions.EmitMetadataOnly) { throw new NotImplementedException(); } // Perform initial bind of method bodies in spite of earlier errors. This is the same // behavior as when calling GetDiagnostics() // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag methodBodyDiagnosticBag = DiagnosticBag.GetInstance(); SourceCompiler.CompileSources( this, moduleBeingBuilt, emittingPdb, hasDeclarationErrors, methodBodyDiagnosticBag, cancellationToken); SetupWin32Resources(moduleBeingBuilt, win32Resources, methodBodyDiagnosticBag); ReportManifestResourceDuplicates( moduleBeingBuilt.ManifestResources, SourceAssembly.Modules.Skip(1).Select((m) => m.Name), //all modules except the first one AddedModulesResourceNames(methodBodyDiagnosticBag), methodBodyDiagnosticBag); bool hasMethodBodyErrorOrWarningAsError = !FilterAndAppendAndFreeDiagnostics(diagnostics, ref methodBodyDiagnosticBag); if (hasDeclarationErrors || hasMethodBodyErrorOrWarningAsError) { return(false); } cancellationToken.ThrowIfCancellationRequested(); // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag xmlDiagnostics = DiagnosticBag.GetInstance(); string assemblyName = FileNameUtilities.ChangeExtension(moduleBeingBuilt.EmitOptions.OutputNameOverride, extension: null); DocumentationCommentCompiler.WriteDocumentationCommentXml(this, assemblyName, xmlDocStream, xmlDiagnostics, cancellationToken); if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref xmlDiagnostics)) { return(false); } //// Use a temporary bag so we don't have to refilter pre-existing diagnostics. //DiagnosticBag importDiagnostics = DiagnosticBag.GetInstance(); //this.ReportUnusedImports(importDiagnostics, cancellationToken); //if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref importDiagnostics)) //{ // Debug.Assert(false, "Should never produce an error"); // return false; //} return(true); }
public abstract void Visit(CommonPEModuleBuilder module);
internal Cci.ManagedResource ToManagedResource(CommonPEModuleBuilder moduleBeingBuilt) { return new Cci.ManagedResource(ResourceName, IsPublic, IsEmbedded ? DataProvider : null, IsEmbedded ? null : this, offset: 0); }
private static int CalculateStrongNameSignatureSize(CommonPEModuleBuilder module) { ISourceAssemblySymbolInternal assembly = module.SourceAssemblyOpt; if (assembly == null) { return 0; } // EDMAURER the count of characters divided by two because the each pair of characters will turn in to one byte. int keySize = (assembly.SignatureKey == null) ? 0 : assembly.SignatureKey.Length / 2; if (keySize == 0) { keySize = assembly.Identity.PublicKey.Length; } if (keySize == 0) { return 0; } return (keySize < 128 + 32) ? 128 : keySize - 32; }
private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBuilder) { var method = ((EEAssemblyBuilder)moduleBuilder).Methods.Single(m => m.MetadataName == MethodName); Debug.Assert(method.ContainingType.MetadataName == TypeName); return method; }
internal static bool ShouldGenerateHashTableSwitch(CommonPEModuleBuilder module, int labelsCount) { return module.SupportsPrivateImplClass && ShouldGenerateHashTableSwitch(labelsCount); }
internal PEAssemblyBuilderWithAdditionalReferences(CommonPEModuleBuilder builder, INamespaceTypeDefinition objectType) : base((SourceModuleSymbol)builder.CommonSourceModule, builder.EmitOptions, builder.OutputKind, builder.SerializationProperties, builder.ManifestResources) { _builder = builder; _objectType = new NamespaceTypeDefinitionNoBase(objectType); }
internal PEAssemblyBuilderWithAdditionalReferences(CommonPEModuleBuilder builder, EmitOptions emitOptions, INamespaceTypeDefinition objectType) : base((SourceModuleSymbol)builder.CommonSourceModule, emitOptions, builder.OutputKind, builder.SerializationProperties, builder.ManifestResources) { _builder = builder; _objectType = new NamespaceTypeDefinitionNoBase(objectType); }
internal Cci.ManagedResource ToManagedResource(CommonPEModuleBuilder moduleBeingBuilt) { return(new Cci.ManagedResource(ResourceName, IsPublic, IsEmbedded ? DataProvider : null, IsEmbedded ? null : this, offset: 0)); }
/// <summary> /// Writes information about metadata references to the pdb so the same /// reference can be found on sourcelink to create the compilation again /// </summary> private void EmbedMetadataReferenceInformation(CommonPEModuleBuilder module) { var builder = new BlobBuilder(); // Order of information // File name (null terminated string): A.exe // Extern Alias (null terminated string): a1,a2,a3 // MetadataImageKind (byte) // EmbedInteropTypes (boolean) // COFF header Timestamp field (4 byte int) // COFF header SizeOfImage field (4 byte int) // MVID (Guid, 24 bytes) foreach (var metadataReference in module.CommonCompilation.ExternalReferences) { if (metadataReference is PortableExecutableReference portableReference && portableReference.FilePath is object) { var fileName = PathUtilities.GetFileName(portableReference.FilePath); var reference = module.CommonCompilation.GetAssemblyOrModuleSymbol(portableReference); var peReader = GetReader(reference); // Don't write before checking that we can get a peReader for the metadata reference if (peReader is null) { continue; } // Write file name first builder.WriteUTF8(fileName); // Make sure to add null terminator builder.WriteByte(0); // Extern alias if (portableReference.Properties.Aliases.Any()) { builder.WriteUTF8(string.Join(",", portableReference.Properties.Aliases)); } // Always null terminate the extern alias list builder.WriteByte(0); byte kindAndEmbedInteropTypes = (byte)(portableReference.Properties.EmbedInteropTypes ? 0b10 : 0b0); kindAndEmbedInteropTypes |= portableReference.Properties.Kind switch { MetadataImageKind.Assembly => 1, MetadataImageKind.Module => 0, _ => throw ExceptionUtilities.UnexpectedValue(portableReference.Properties.Kind) }; builder.WriteByte(kindAndEmbedInteropTypes); builder.WriteInt32(peReader.PEHeaders.CoffHeader.TimeDateStamp); builder.WriteInt32(peReader.PEHeaders.PEHeader.SizeOfImage); var metadataReader = peReader.GetMetadataReader(); var moduleDefinition = metadataReader.GetModuleDefinition(); builder.WriteGuid(metadataReader.GetGuid(moduleDefinition.Mvid)); } } _debugMetadataOpt.AddCustomDebugInformation( parent: EntityHandle.ModuleDefinition, kind: _debugMetadataOpt.GetOrAddGuid(PortableCustomDebugInfoKinds.CompilationMetadataReferences), value: _debugMetadataOpt.GetOrAddBlob(builder));
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); }
internal override bool CompileImpl( CommonPEModuleBuilder moduleBuilder, string outputName, Stream win32Resources, Stream xmlDocStream, CancellationToken cancellationToken, bool generateDebugInfo, DiagnosticBag diagnostics, Predicate<ISymbol> filterOpt) { // The diagnostics should include syntax and declaration errors. We insert these before calling Emitter.Emit, so that the emitter // does not attempt to emit if there are declaration errors (but we do insert all errors from method body binding...) bool hasDeclarationErrors = !FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, true, cancellationToken)); // TODO (tomat): NoPIA: // EmbeddedSymbolManager.MarkAllDeferredSymbolsAsReferenced(this) var moduleBeingBuilt = (PEModuleBuilder)moduleBuilder; if (moduleBeingBuilt.MetadataOnly) { if (hasDeclarationErrors) { return false; } SynthesizedMetadataCompiler.ProcessSynthesizedMembers(this, moduleBeingBuilt, cancellationToken); } else { if (generateDebugInfo && moduleBeingBuilt != null) { if (!StartSourceChecksumCalculation(moduleBeingBuilt, diagnostics)) { return false; } } // Perform initial bind of method bodies in spite of earlier errors. This is the same // behavior as when calling GetDiagnostics() // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag methodBodyDiagnosticBag = DiagnosticBag.GetInstance(); MethodCompiler.CompileMethodBodies( this, moduleBeingBuilt, generateDebugInfo, hasDeclarationErrors, diagnostics: methodBodyDiagnosticBag, filterOpt: filterOpt, cancellationToken: cancellationToken); SetupWin32Resources(moduleBeingBuilt, win32Resources, methodBodyDiagnosticBag); ReportManifestResourceDuplicates( moduleBeingBuilt.ManifestResources, SourceAssembly.Modules.Skip(1).Select((m) => m.Name), //all modules except the first one AddedModulesResourceNames(methodBodyDiagnosticBag), methodBodyDiagnosticBag); bool hasMethodBodyErrorOrWarningAsError = !FilterAndAppendAndFreeDiagnostics(diagnostics, ref methodBodyDiagnosticBag); if (hasDeclarationErrors || hasMethodBodyErrorOrWarningAsError) { return false; } } cancellationToken.ThrowIfCancellationRequested(); // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag xmlDiagnostics = DiagnosticBag.GetInstance(); string assemblyName = FileNameUtilities.ChangeExtension(outputName, extension: null); DocumentationCommentCompiler.WriteDocumentationCommentXml(this, assemblyName, xmlDocStream, xmlDiagnostics, cancellationToken); if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref xmlDiagnostics)) { return false; } // Use a temporary bag so we don't have to refilter pre-existing diagnostics. DiagnosticBag importDiagnostics = DiagnosticBag.GetInstance(); this.ReportUnusedImports(importDiagnostics, cancellationToken); if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref importDiagnostics)) { Debug.Assert(false, "Should never produce an error"); return false; } return true; }
private static ResourceSectionBuilder CreateNativeResourceSectionSerializer(CommonPEModuleBuilder module) { // Win32 resources are supplied to the compiler in one of two forms, .RES (the output of the resource compiler), // or .OBJ (the output of running cvtres.exe on a .RES file). A .RES file is parsed and processed into // a set of objects implementing IWin32Resources. These are then ordered and the final image form is constructed // and written to the resource section. Resources in .OBJ form are already very close to their final output // form. Rather than reading them and parsing them into a set of objects similar to those produced by // processing a .RES file, we process them like the native linker would, copy the relevant sections from // the .OBJ into our output and apply some fixups. var nativeResourceSectionOpt = module.Win32ResourceSection; if (nativeResourceSectionOpt != null) { return new ResourceSectionBuilderFromObj(nativeResourceSectionOpt); } var nativeResourcesOpt = module.Win32Resources; if (nativeResourcesOpt?.Any() == true) { return new ResourceSectionBuilderFromResources(nativeResourcesOpt); } return null; }