/// <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);
            }
        }
Пример #2
0
 internal static bool ShouldGenerateHashTableSwitch(
     CommonPEModuleBuilder module,
     int labelsCount
     )
 {
     return(module.SupportsPrivateImplClass && ShouldGenerateHashTableSwitch(labelsCount));
 }
Пример #3
0
        private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBuilder)
        {
            var method = ((EEAssemblyBuilder)moduleBuilder).Methods.Single(m => m.MetadataName == MethodName);

            Debug.Assert(method.ContainingType.MetadataName == TypeName);
            return(method);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        private void EmbedCompilationOptions(BlobReader?pdbCompilationOptionsReader, CommonPEModuleBuilder module)
        {
            var builder = new BlobBuilder();

            if (pdbCompilationOptionsReader is { } reader)
            {
                builder.WriteBytes(reader.ReadBytes(reader.RemainingBytes));
            }
Пример #8
0
        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));
            }
Пример #10
0
        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());
        }
Пример #11
0
        public EmitContext(CommonPEModuleBuilder module, SyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics)
        {
            Debug.Assert(module != null);
            Debug.Assert(diagnostics != null);

            Module = module;
            SyntaxNodeOpt = syntaxNodeOpt;
            Diagnostics = diagnostics;
        }
Пример #12
0
 internal override bool GenerateResourcesAndDocumentationComments(
     CommonPEModuleBuilder moduleBuilder,
     Stream xmlDocStream,
     Stream win32Resources,
     string outputNameOverride,
     DiagnosticBag diagnostics,
     CancellationToken cancellationToken)
 {
     throw new NotImplementedException();
 }
Пример #13
0
        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;
            }
        }
Пример #14
0
 internal override bool CompileMethods(
     CommonPEModuleBuilder moduleBuilder,
     bool emittingPdb,
     bool emitMetadataOnly,
     bool emitTestCoverageData,
     DiagnosticBag diagnostics,
     Predicate <ISymbol> filterOpt,
     CancellationToken cancellationToken)
 {
     throw new NotImplementedException();
 }
Пример #15
0
        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();
            }
        }
Пример #16
0
        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();
        }
Пример #17
0
        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);
        }
Пример #18
0
        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));
        }
Пример #19
0
        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));
        }
Пример #20
0
        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;
        }
Пример #21
0
 protected override IEnumerable <INamespaceTypeDefinition> GetTopLevelTypes(CommonPEModuleBuilder module)
 {
     return(module.GetTopLevelTypes(this.Context));
 }
Пример #22
0
        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;
        }
Пример #23
0
 public override abstract void Visit(CommonPEModuleBuilder module);
Пример #24
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;
        }
Пример #25
0
        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);
        }
Пример #26
0
 public abstract void Visit(CommonPEModuleBuilder module);
Пример #27
0
 internal Cci.ManagedResource ToManagedResource(CommonPEModuleBuilder moduleBeingBuilt)
 {
     return new Cci.ManagedResource(ResourceName, IsPublic, IsEmbedded ? DataProvider : null, IsEmbedded ? null : this, offset: 0);
 }
Пример #28
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;
        }
Пример #29
0
 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);
 }
Пример #31
0
 internal PEAssemblyBuilderWithAdditionalReferences(CommonPEModuleBuilder builder, INamespaceTypeDefinition objectType) :
     base((SourceModuleSymbol)builder.CommonSourceModule, builder.EmitOptions, builder.OutputKind, builder.SerializationProperties, builder.ManifestResources)
 {
     _builder = builder;
     _objectType = new NamespaceTypeDefinitionNoBase(objectType);
 }
Пример #32
0
 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);
 }
Пример #33
0
 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));
Пример #35
0
 public abstract void Visit(CommonPEModuleBuilder module);
Пример #36
0
        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);
        }
Пример #37
0
 public override abstract void Visit(CommonPEModuleBuilder module);
        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;
        }
Пример #39
0
        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;
        }