示例#1
0
 public PEModuleSymbol(PEAssemblySymbol assembly, PEModule module, MetadataImportOptions importOptions, int ordinal)
 {
     _assembly = assembly;
     _module = module;
     _ordinal = ordinal;
     this.ImportOptions = importOptions;
     _namespace = new PEGlobalNamespaceSymbol(this);
 }
示例#2
0
 /// <summary>
 /// Returns true if the field should be imported. Visibility
 /// and the value of <paramref name="importOptions"/> are considered
 /// </summary>
 public static bool ShouldImportField(this PEModule module, FieldDefinitionHandle field, MetadataImportOptions importOptions)
 {
     try
     {
         var flags = module.GetFieldDefFlagsOrThrow(field);
         return ShouldImportField(flags, importOptions);
     }
     catch (BadImageFormatException)
     {
         return true;
     }
 }
示例#3
0
        /// <summary>
        /// Returns true if the method should be imported. Returns false for private methods that are not
        /// explicit interface implementations. For other methods, visibility and the value of
        /// <paramref name="importOptions"/> are considered.
        /// </summary>
        public static bool ShouldImportMethod(this PEModule module, MethodDefinitionHandle methodDef, MetadataImportOptions importOptions)
        {
            try
            {
                var flags = module.GetMethodDefFlagsOrThrow(methodDef);

                // If the method is virtual, it must be accessible, although
                // it may be an explicit (private) interface implementation.
                // Otherwise, we need to check the accessibility.
                if ((flags & MethodAttributes.Virtual) == 0)
                {
                    switch (flags & MethodAttributes.MemberAccessMask)
                    {
                        case MethodAttributes.Private:
                        case MethodAttributes.PrivateScope:
                            if (importOptions != MetadataImportOptions.All)
                            {
                                return false;
                            }

                            break;

                        case MethodAttributes.Assembly:
                            if (importOptions == MetadataImportOptions.Public)
                            {
                                return false;
                            }

                            break;
                    }
                }
            }
            catch (BadImageFormatException)
            { }

            try
            {
                // As in the native C# compiler (see IMPORTER::ImportMethod), drop any method prefixed
                // with "_VtblGap".  They should be impossible to call/implement/etc.
                // BREAK: The native VB compiler does not drop such methods, but it produces unverfiable
                // code when they are called, so the break is acceptable.
                // TODO: Keep some record of vtable gaps (DevDiv #17472).
                var name = module.GetMethodDefNameOrThrow(methodDef);
                return !name.StartsWith(VTableGapMethodNamePrefix, StringComparison.Ordinal);
            }
            catch (BadImageFormatException)
            {
                return true;
            }
        }
示例#4
0
        /// <summary>
        /// Returns true if the flags represent a field that should be imported.
        /// Visibility and the value of <paramref name="importOptions"/> are considered
        /// </summary>
        public static bool ShouldImportField(FieldAttributes flags, MetadataImportOptions importOptions)
        {
            switch (flags & FieldAttributes.FieldAccessMask)
            {
                case FieldAttributes.Private:
                case FieldAttributes.PrivateScope:
                    return importOptions == MetadataImportOptions.All;

                case FieldAttributes.Assembly:
                    return importOptions >= MetadataImportOptions.Internal;

                default:
                    return true;
            }
        }
        internal PEAssemblySymbol(PEAssembly assembly, DocumentationProvider documentationProvider, bool isLinked, MetadataImportOptions importOptions)
        {
            Debug.Assert(assembly != null);
            Debug.Assert(documentationProvider != null);
            _assembly = assembly;
            _documentationProvider = documentationProvider;

            var modules = new ModuleSymbol[assembly.Modules.Length];

            for (int i = 0; i < assembly.Modules.Length; i++)
            {
                modules[i] = new PEModuleSymbol(this, assembly.Modules[i], importOptions, i);
            }

            _modules = modules.AsImmutableOrNull();
            _isLinked = isLinked;
        }
示例#6
0
 // Expects correct arguments.
 internal CompilationOptions(
     OutputKind outputKind,
     string moduleName,
     string mainTypeName,
     string scriptClassName,
     string cryptoKeyContainer,
     string cryptoKeyFile,
     bool? delaySign,
     bool optimize,
     bool checkOverflow,
     int fileAlignment,
     ulong baseAddress,
     Platform platform,
     ReportDiagnostic generalDiagnosticOption,
     int warningLevel,
     IEnumerable<KeyValuePair<string, ReportDiagnostic>> specificDiagnosticOptions,
     bool highEntropyVirtualAddressSpace,
     DebugInformationKind debugInformationKind,
     SubsystemVersion subsystemVersion,
     bool concurrentBuild,
     XmlReferenceResolver xmlReferenceResolver,
     SourceReferenceResolver sourceReferenceResolver,
     MetadataReferenceResolver metadataReferenceResolver,
     MetadataReferenceProvider metadataReferenceProvider,
     AssemblyIdentityComparer assemblyIdentityComparer,
     StrongNameProvider strongNameProvider,
     MetadataImportOptions metadataImportOptions)
 {
     Initialize(
         outputKind, moduleName, mainTypeName, scriptClassName, cryptoKeyContainer, cryptoKeyFile, delaySign, optimize, checkOverflow, fileAlignment, 
         baseAddress, platform, generalDiagnosticOption, warningLevel, specificDiagnosticOptions, highEntropyVirtualAddressSpace, debugInformationKind, 
         subsystemVersion, concurrentBuild, xmlReferenceResolver, sourceReferenceResolver, metadataReferenceResolver, metadataReferenceProvider, assemblyIdentityComparer, strongNameProvider, 
         metadataImportOptions);
 }
示例#7
0
 internal override IEnumerable<IModuleSymbol> ReferencesToModuleSymbols(IEnumerable<MetadataReference> references, MetadataImportOptions importOptions = MetadataImportOptions.Public)
 {
     throw new NotImplementedException();
 }
示例#8
0
        internal PEAssemblySymbol(PEAssembly assembly, DocumentationProvider documentationProvider, string filePath, bool isLinked, MetadataImportOptions importOptions)
        {
            Debug.Assert(assembly != null);
            Debug.Assert(documentationProvider != null);

            _assembly = assembly;
            _documentationProvider = documentationProvider;
            _filePath = filePath;

            var modules = new ModuleSymbol[assembly.Modules.Length];

            for (int i = 0; i < assembly.Modules.Length; i++)
            {
                modules[i] = new PEModuleSymbol(this, assembly.Modules[i], importOptions, i);
            }

            _modules  = modules.AsImmutableOrNull();
            _isLinked = isLinked;

            if (IsPchpCor(assembly))
            {
                _specialAssembly = SpecialAssembly.PeachpieCorLibrary;

                // initialize CoreTypes
                this.PrimaryModule.GlobalNamespace.GetTypeMembers();
            }
            else if (assembly.Identity.Name == "System.Runtime")
            {
                _specialAssembly = SpecialAssembly.CorLibrary;
            }
            else if (assembly.AssemblyReferences.Length == 0 && assembly.DeclaresTheObjectClass)
            {
                _specialAssembly = SpecialAssembly.CorLibrary;
            }
            else
            {
                // extension assembly ?
                //var attrs = this.GetAttributes();
            }
        }
        private void ResolveAndBindMissingAssemblies(
            ImmutableArray <AssemblyData> explicitAssemblies,
            MetadataReferenceResolver resolver,
            MetadataImportOptions importOptions,
            [In, Out] ArrayBuilder <AssemblyReferenceBinding[]> referenceBindings,
            out ImmutableArray <AssemblyData> allAssemblies,
            out ImmutableArray <MetadataReference> metadataReferences,
            out ImmutableArray <ResolvedReference> resolvedReferences,
            DiagnosticBag resolutionDiagnostics)
        {
            Debug.Assert(explicitAssemblies[0] is AssemblyDataForAssemblyBeingBuilt);

            var implicitAssemblies = ArrayBuilder <AssemblyData> .GetInstance();

            // tracks identities we already asked the resolver to resolve:
            var requestedIdentities = PooledHashSet <AssemblyIdentity> .GetInstance();

            // reference bindings of implicit assemblies, used to calculate a fixed point:
            var referenceBindingsToProcess = ArrayBuilder <AssemblyReferenceBinding[]> .GetInstance();

            var metadataReferencesBuilder = ArrayBuilder <MetadataReference> .GetInstance();

            Dictionary <string, List <ReferencedAssemblyIdentity> > lazyResolvedReferencesBySimpleName = null;
            Dictionary <MetadataReference, ArrayBuilder <string> >  lazyAliasMap = null;

            try
            {
                // collect all missing identities, resolve the assemblies and bind their references against explicit definitions:
                referenceBindingsToProcess.AddRange(referenceBindings);

                while (referenceBindingsToProcess.Count > 0)
                {
                    foreach (var binding in referenceBindingsToProcess.Pop())
                    {
                        // only attempt to resolve unbound references (regardless of version difference of the bound ones)
                        if (binding.IsBound)
                        {
                            continue;
                        }

                        if (!requestedIdentities.Add(binding.ReferenceIdentity))
                        {
                            continue;
                        }

                        var peReference = resolver.ResolveMissingAssembly(binding.ReferenceIdentity);
                        if (peReference == null)
                        {
                            continue;
                        }

                        var data = ResolveMissingAssembly(binding.ReferenceIdentity, peReference, importOptions, resolutionDiagnostics);
                        if (data == null)
                        {
                            continue;
                        }

                        // The resolver may return different version than we asked for, so it may happen that
                        // it returns the same identity for two different input identities (e.g. if a higher version
                        // of an assembly is available than what the assemblies reference: "A, v1" -> "A, v3" and "A, v2" -> "A, v3").
                        // If such case occurs merge the properties (aliases) of the resulting references in the same way we do
                        // during initial explicit references resolution.

                        var existingReference = TryAddAssembly(data.Identity, peReference, resolutionDiagnostics, Location.None, ref lazyResolvedReferencesBySimpleName);
                        if (existingReference != null)
                        {
                            MergeReferenceProperties(existingReference, peReference, resolutionDiagnostics, ref lazyAliasMap);
                            continue;
                        }

                        metadataReferencesBuilder.Add(peReference);
                        implicitAssemblies.Add(data);

                        var referenceBinding = data.BindAssemblyReferences(explicitAssemblies, IdentityComparer);
                        referenceBindings.Add(referenceBinding);
                        referenceBindingsToProcess.Push(referenceBinding);
                    }
                }

                if (implicitAssemblies.Count == 0)
                {
                    Debug.Assert(lazyAliasMap == null);
                    Debug.Assert(lazyResolvedReferencesBySimpleName == null);

                    resolvedReferences = ImmutableArray <ResolvedReference> .Empty;
                    metadataReferences = ImmutableArray <MetadataReference> .Empty;
                    allAssemblies      = explicitAssemblies;
                    return;
                }

                // Rebind assembly references that were initially missing. All bindings established above
                // are against explicitly specified references.

                // NB: includes the assembly being built:
                int explicitAssemblyCount = explicitAssemblies.Length;
                allAssemblies = explicitAssemblies.AddRange(implicitAssemblies);

                for (int bindingsIndex = 0; bindingsIndex < referenceBindings.Count; bindingsIndex++)
                {
                    var referenceBinding = referenceBindings[bindingsIndex];

                    for (int i = 0; i < referenceBinding.Length; i++)
                    {
                        var binding = referenceBinding[i];

                        // We don't rebind references bound to a non-matching version of a reference that was explicitly
                        // specified, even if we have a better version now.
                        if (binding.IsBound)
                        {
                            continue;
                        }

                        // We only need to resolve against implicitly resolved assemblies,
                        // since we already resolved against explicitly specified ones.
                        referenceBinding[i] = ResolveReferencedAssembly(
                            binding.ReferenceIdentity,
                            allAssemblies,
                            explicitAssemblyCount,
                            IdentityComparer);
                    }
                }

                UpdateBindingsOfAssemblyBeingBuilt(referenceBindings, explicitAssemblyCount, implicitAssemblies);

                metadataReferences = metadataReferencesBuilder.ToImmutable();
                resolvedReferences = ToResolvedAssemblyReferences(metadataReferences, lazyAliasMap, explicitAssemblyCount);
            }
            finally
            {
                implicitAssemblies.Free();
                requestedIdentities.Free();
                referenceBindingsToProcess.Free();
                metadataReferencesBuilder.Free();
            }
        }
 internal abstract IEnumerable<IModuleSymbol> ReferencesToModuleSymbols(IEnumerable<MetadataReference> references, MetadataImportOptions importOptions = MetadataImportOptions.Public);
示例#11
0
        internal IModuleSymbol GetSymbolFromMetadata(MetadataReference metadataReference, MetadataImportOptions importOptions)
        {
            var dummy = _compilation
                        .RemoveAllSyntaxTrees()
                        .AddReferences(metadataReference)
                        .WithAssemblyName("Dummy")
                        .WithOptions(_compilation.Options.WithMetadataImportOptions(importOptions));

            var symbol = dummy.GetAssemblyOrModuleSymbol(metadataReference);

            if (metadataReference.Properties.Kind == MetadataImageKind.Assembly)
            {
                return(((IAssemblySymbol)symbol).Modules.First());
            }
            else
            {
                return((IModuleSymbol)symbol);
            }
        }
示例#12
0
 protected override CompilationOptions CommonWithMetadataImportOptions(MetadataImportOptions value) =>
 WithMetadataImportOptions(value);
示例#13
0
        internal override IEnumerable <IModuleSymbol> ReferencesToModuleSymbols(IEnumerable <MetadataReference> references, MetadataImportOptions importOptions = MetadataImportOptions.Public)
        {
            var options = TestOptions.ReleaseDll.WithMetadataImportOptions(importOptions);
            var tc1     = CSharpCompilation.Create("Dummy", new SyntaxTree[0], references, options);

            return(references.Select(r =>
            {
                if (r.Properties.Kind == MetadataImageKind.Assembly)
                {
                    var assemblySymbol = tc1.GetReferencedAssemblySymbol(r);
                    return (object)assemblySymbol == null ? null : assemblySymbol.Modules[0];
                }
                else
                {
                    return tc1.GetReferencedModuleSymbol(r);
                }
            }));
        }
示例#14
0
 internal new IEnumerable <ModuleSymbol> ReferencesToModuleSymbols(IEnumerable <MetadataReference> references, MetadataImportOptions importOptions = MetadataImportOptions.Public)
 {
     return(base.ReferencesToModuleSymbols(references, importOptions).Cast <ModuleSymbol>());
 }
示例#15
0
        public static bool ShouldImportMethod(this PEModule module, MethodDefinitionHandle methodDef, MetadataImportOptions importOptions)
        {
            try
            {
                var flags = module.GetMethodDefFlagsOrThrow(methodDef);

                // If the method is virtual, it must be accessible, although
                // it may be an explicit (private) interface implementation.
                // Otherwise, we need to check the accessibility.
                if ((flags & MethodAttributes.Virtual) == 0)
                {
                    switch (flags & MethodAttributes.MemberAccessMask)
                    {
                    case MethodAttributes.Private:
                    case MethodAttributes.PrivateScope:
                        if (importOptions != MetadataImportOptions.All)
                        {
                            return(false);
                        }

                        break;

                    case MethodAttributes.Assembly:
                        if (importOptions == MetadataImportOptions.Public)
                        {
                            return(false);
                        }

                        break;
                    }
                }
            }
            catch (BadImageFormatException)
            { }

            try
            {
                // As in the native C# compiler (see IMPORTER::ImportMethod), drop any method prefixed
                // with "_VtblGap".  They should be impossible to call/implement/etc.
                // BREAK: The native VB compiler does not drop such methods, but it produces unverifiable
                // code when they are called, so the break is acceptable.
                // TODO: Keep some record of vtable gaps (DevDiv #17472).
                var name = module.GetMethodDefNameOrThrow(methodDef);
                return(!name.StartsWith(VTableGapMethodNamePrefix, StringComparison.Ordinal));
            }
            catch (BadImageFormatException)
            {
                return(true);
            }
        }
 public new MetaCompilationOptions WithMetadataImportOptions(MetadataImportOptions value) => (MetaCompilationOptions)base.WithMetadataImportOptions(value);
示例#17
0
 public static bool ShouldImportField(this PEModule module, FieldDefinitionHandle field, MetadataImportOptions importOptions)
 {
     try
     {
         var flags = module.GetFieldDefFlagsOrThrow(field);
         return(ShouldImportField(flags, importOptions));
     }
     catch (BadImageFormatException)
     {
         return(true);
     }
 }
示例#18
0
 internal abstract IEnumerable <IModuleSymbol> ReferencesToModuleSymbols(IEnumerable <MetadataReference> references, MetadataImportOptions importOptions = MetadataImportOptions.Public);
示例#19
0
        internal override void ValidateOptions(ArrayBuilder <Diagnostic> builder)
        {
            ValidateOptions(builder, MessageProvider.Instance);

            //  /main & /target:{library|netmodule|winmdobj}
            if (this.MainTypeName != null)
            {
                if (this.OutputKind.IsValid() && !this.OutputKind.IsApplication())
                {
                    builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_NoMainOnDLL));
                }

                if (!MainTypeName.IsValidClrTypeName())
                {
                    builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(MainTypeName), MainTypeName));
                }
            }

            if (!Platform.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadPlatformType, Platform.ToString()));
            }

            if (ModuleName != null)
            {
                MetadataHelpers.CheckAssemblyOrModuleName(ModuleName, MessageProvider.Instance, (int)ErrorCode.ERR_BadModuleName, builder);
            }

            if (!OutputKind.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(OutputKind), OutputKind.ToString()));
            }

            if (!OptimizationLevel.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(OptimizationLevel), OptimizationLevel.ToString()));
            }

            if (ScriptClassName == null || !ScriptClassName.IsValidClrTypeName())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(ScriptClassName), ScriptClassName ?? "null"));
            }

            if (WarningLevel < 0)
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(WarningLevel), WarningLevel));
            }

            if (Usings != null && Usings.Any(u => !u.IsValidClrNamespaceName()))
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(Usings), Usings.Where(u => !u.IsValidClrNamespaceName()).First() ?? "null"));
            }

            if (Platform == Platform.AnyCpu32BitPreferred && OutputKind.IsValid() && !(OutputKind == OutputKind.ConsoleApplication || OutputKind == OutputKind.WindowsApplication || OutputKind == OutputKind.WindowsRuntimeApplication))
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadPrefer32OnLib));
            }

            if (!MetadataImportOptions.IsValid())
            {
                builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(MetadataImportOptions), MetadataImportOptions.ToString()));
            }

            // TODO: add check for
            //          (kind == 'arm' || kind == 'appcontainer' || kind == 'winmdobj') &&
            //          (version >= "6.2")
        }
        // Temporary workaround while blocked on https://github.com/dotnet/roslyn/issues/6748
        // This method is only called once. No fancy tricks required for speed.
        public static void SetMetadataImportOptions(this CompilationOptions instance, MetadataImportOptions options)
        {
            FieldInfo field = typeof(CompilationOptions)
                              .GetField(
                "<MetadataImportOptions>k__BackingField",
                BindingFlags.NonPublic | BindingFlags.Instance);

            field.SetValue(instance, options);
        }
示例#21
0
 internal PEModuleSymbol(SourceAssemblySymbol assemblySymbol, PEModule module, MetadataImportOptions importOptions, int ordinal)
     : this((AssemblySymbol)assemblySymbol, module, importOptions, ordinal)
 {
     Debug.Assert(ordinal > 0);
 }
 internal static bool IsValid(this MetadataImportOptions value)
 {
     return(value >= MetadataImportOptions.Public && value <= MetadataImportOptions.All);
 }
        private static CSharpCompilationOptions CreateCSharpCompilationOptions()
        {
            string moduleName                        = null;
            string mainTypeName                      = null;
            string scriptClassName                   = null;
            IEnumerable <string> usings              = null;
            OptimizationLevel    optimizationLevel   = OptimizationLevel.Debug;
            bool   checkOverflow                     = false;
            bool   allowUnsafe                       = false;
            string cryptoKeyContainer                = null;
            string cryptoKeyFile                     = null;
            ImmutableArray <byte> cryptoPublicKey    = default(ImmutableArray <byte>);
            bool?            delaySign               = null;
            Platform         platform                = 0;
            ReportDiagnostic generalDiagnosticOption = 0;
            int warningLevel = 0;
            IEnumerable <KeyValuePair <string, ReportDiagnostic> > specificDiagnosticOptions = null;
            bool                    concurrentBuild         = false;
            bool                    deterministic           = false;
            DateTime                currentLocalTime        = default(DateTime);
            bool                    debugPlusMode           = false;
            XmlReferenceResolver    xmlReferenceResolver    = new XmlFileResolver(null);
            SourceReferenceResolver sourceReferenceResolver = new SourceFileResolver(
                ImmutableArray <string> .Empty,
                null
                );
            SyntaxTreeOptionsProvider syntaxTreeOptionsProvider = null;
            MetadataReferenceResolver metadataReferenceResolver =
                new MetadataReferenceResolverWithEquality();
            AssemblyIdentityComparer assemblyIdentityComparer = AssemblyIdentityComparer.Default; // Currently uses reference equality
            StrongNameProvider       strongNameProvider       = new DesktopStrongNameProvider();
            MetadataImportOptions    metadataImportOptions    = 0;
            bool referencesSupersedeLowerVersions             = false;
            bool reportSuppressedDiagnostics = false;
            var  topLevelBinderFlags         = BinderFlags.None;
            var  publicSign = false;
            NullableContextOptions nullableContextOptions = NullableContextOptions.Disable;

            return(new CSharpCompilationOptions(
                       OutputKind.ConsoleApplication,
                       reportSuppressedDiagnostics,
                       moduleName,
                       mainTypeName,
                       scriptClassName,
                       usings,
                       optimizationLevel,
                       checkOverflow,
                       allowUnsafe,
                       cryptoKeyContainer,
                       cryptoKeyFile,
                       cryptoPublicKey,
                       delaySign,
                       platform,
                       generalDiagnosticOption,
                       warningLevel,
                       specificDiagnosticOptions,
                       concurrentBuild,
                       deterministic,
                       currentLocalTime,
                       debugPlusMode,
                       xmlReferenceResolver,
                       sourceReferenceResolver,
                       syntaxTreeOptionsProvider,
                       metadataReferenceResolver,
                       assemblyIdentityComparer,
                       strongNameProvider,
                       metadataImportOptions,
                       referencesSupersedeLowerVersions,
                       publicSign,
                       topLevelBinderFlags,
                       nullableContextOptions
                       ));
        }
示例#24
0
 internal override IEnumerable <IModuleSymbol> ReferencesToModuleSymbols(IEnumerable <MetadataReference> references, MetadataImportOptions importOptions = MetadataImportOptions.Public)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// For the given set of AssemblyData objects, do the following:
        ///    1) Resolve references from each assembly against other assemblies in the set.
        ///    2) Choose suitable AssemblySymbol instance for each AssemblyData object.
        ///
        /// The first element (index==0) of the assemblies array represents the assembly being built.
        /// One can think about the rest of the items in assemblies array as assembly references given to the compiler to
        /// build executable for the assembly being built.
        /// </summary>
        ///
        /// <param name="explicitAssemblies">
        /// An array of <see cref="AssemblyData"/> objects describing assemblies, for which this method should
        /// resolve references and find suitable AssemblySymbols. The first slot contains the assembly being built.
        /// </param>
        /// <param name="resolverOpt">
        /// Reference resolver used to look up missing assemblies.
        /// </param>
        /// <param name="importOptions">
        /// Import options applied to implicitly resolved references.
        /// </param>
        /// <param name="allAssemblies">
        /// Updated array <paramref name="explicitAssemblies"/> with resolved implicitly referenced assemblies appended.
        /// </param>
        /// <param name="implicitlyResolvedReferences">
        /// Implicitly resolved references.
        /// </param>
        /// <param name="implicitlyResolvedReferenceMap">
        /// Maps indices of implicitly resolved references to the corresponding indices of resolved assemblies in <paramref name="allAssemblies"/> (explicit + implicit).
        /// </param>
        /// <param name="resolutionDiagnostics">
        /// Any diagnostics reported while resolving missing assemblies.
        /// </param>
        /// <param name="hasCircularReference">
        /// True if the assembly being compiled is indirectly referenced through some of its own references.
        /// </param>
        /// <param name="corLibraryIndex">
        /// The definition index of the COR library.
        /// </param>
        /// <return>
        /// An array of <see cref="BoundInputAssembly"/> structures describing the result. It has the same amount of items as
        /// the input assemblies array, <see cref="BoundInputAssembly"/> for each input AssemblyData object resides
        /// at the same position.
        ///
        /// Each <see cref="BoundInputAssembly"/> contains the following data:
        ///
        /// -    Suitable AssemblySymbol instance for the corresponding assembly,
        ///     null reference if none is available/found. Always null for the first element, which corresponds to the assembly being built.
        ///
        /// -    Result of resolving assembly references of the corresponding assembly
        ///     against provided set of assembly definitions. Essentially, this is an array returned by
        ///     <see cref="AssemblyData.BindAssemblyReferences(ImmutableArray{AssemblyData}, AssemblyIdentityComparer)"/> method.
        /// </return>
        protected BoundInputAssembly[] Bind(
            ImmutableArray <AssemblyData> explicitAssemblies,
            MetadataReferenceResolver resolverOpt,
            MetadataImportOptions importOptions,
            out ImmutableArray <AssemblyData> allAssemblies,
            out ImmutableArray <MetadataReference> implicitlyResolvedReferences,
            out ImmutableArray <ResolvedReference> implicitlyResolvedReferenceMap,
            DiagnosticBag resolutionDiagnostics,
            out bool hasCircularReference,
            out int corLibraryIndex)
        {
            Debug.Assert(explicitAssemblies[0] is AssemblyDataForAssemblyBeingBuilt);

            var referenceBindings = ArrayBuilder <AssemblyReferenceBinding[]> .GetInstance();

            try
            {
                // Based on assembly identity, for each assembly,
                // bind its references against the other assemblies we have.
                for (int i = 0; i < explicitAssemblies.Length; i++)
                {
                    referenceBindings.Add(explicitAssemblies[i].BindAssemblyReferences(explicitAssemblies, IdentityComparer));
                }

                if (resolverOpt?.ResolveMissingAssemblies == true)
                {
                    ResolveAndBindMissingAssemblies(explicitAssemblies, resolverOpt, importOptions, referenceBindings, out allAssemblies, out implicitlyResolvedReferences, out implicitlyResolvedReferenceMap, resolutionDiagnostics);
                }
                else
                {
                    allAssemblies = explicitAssemblies;
                    implicitlyResolvedReferences   = ImmutableArray <MetadataReference> .Empty;
                    implicitlyResolvedReferenceMap = ImmutableArray <ResolvedReference> .Empty;
                }

                // implicitly resolved missing assemblies were added to both referenceBindings and assemblies:
                Debug.Assert(referenceBindings.Count == allAssemblies.Length);

                hasCircularReference = CheckCircularReference(referenceBindings);
                corLibraryIndex      = IndexOfCorLibrary(allAssemblies);

                // For each assembly, locate AssemblySymbol with similar reference resolution
                // What does similar mean?
                // Similar means:
                // 1) The same references are resolved against the assemblies that we are given
                //   (or were found duiring implicit assembly resolution).
                // 2) The same assembly is used as the COR library.

                var boundInputs = new BoundInputAssembly[referenceBindings.Count];
                for (int i = 0; i < referenceBindings.Count; i++)
                {
                    boundInputs[i].ReferenceBinding = referenceBindings[i];
                }

                var candidateInputAssemblySymbols = new TAssemblySymbol[allAssemblies.Length];

                // If any assembly from assemblies array refers back to assemblyBeingBuilt,
                // we know that we cannot reuse symbols for any assemblies containing NoPia
                // local types. Because we cannot reuse symbols for assembly referring back
                // to assemblyBeingBuilt.
                if (!hasCircularReference)
                {
                    // Deal with assemblies containing NoPia local types.
                    if (ReuseAssemblySymbolsWithNoPiaLocalTypes(boundInputs, candidateInputAssemblySymbols, allAssemblies, corLibraryIndex))
                    {
                        return(boundInputs);
                    }
                }

                // NoPia shortcut either didn't apply or failed, go through general process
                // of matching candidates.

                ReuseAssemblySymbols(boundInputs, candidateInputAssemblySymbols, allAssemblies, corLibraryIndex);

                return(boundInputs);
            }
            finally
            {
                referenceBindings.Free();
            }
        }
示例#26
0
        internal PEAssemblySymbol(PEAssembly assembly, DocumentationProvider documentationProvider, bool isLinked, MetadataImportOptions importOptions)
        {
            Debug.Assert(assembly != null);
            Debug.Assert(documentationProvider != null);

            _assembly = assembly;
            _documentationProvider = documentationProvider;

            var modules = new ModuleSymbol[assembly.Modules.Length];

            for (int i = 0; i < assembly.Modules.Length; i++)
            {
                modules[i] = new PEModuleSymbol(this, assembly.Modules[i], importOptions, i);
            }

            _modules = modules.AsImmutableOrNull();
            _isLinked = isLinked;

            if (IsPchpCor(assembly))
            {
                _specialAssembly = SpecialAssembly.PchpCorLibrary;

                // initialize CoreTypes
                this.PrimaryModule.GlobalNamespace.GetTypeMembers();
            }
            else if (assembly.Identity.Name == "System.Runtime")
            {
                _specialAssembly = SpecialAssembly.CorLibrary;
            }
            else if (assembly.AssemblyReferences.Length == 0 && assembly.DeclaresTheObjectClass)
            {
                _specialAssembly = SpecialAssembly.CorLibrary;
            }
            else
            {
                // extension assembly ?
                //var attrs = this.GetAttributes();
            }
        }
示例#27
0
        private PEModuleSymbol(AssemblySymbol assemblySymbol, PEModule module, MetadataImportOptions importOptions, int ordinal)
        {
            Debug.Assert((object)assemblySymbol != null);
            Debug.Assert(module != null);

            _assemblySymbol = assemblySymbol;
            _ordinal = ordinal;
            _module = module;
            this.ImportOptions = importOptions;
            _globalNamespace = new PEGlobalNamespaceSymbol(this);

            this.MetadataLocation = ImmutableArray.Create<MetadataLocation>(new MetadataLocation(this));
        }
示例#28
0
        protected static void ReadCompilationOptionsFrom(
            ObjectReader reader,
            out OutputKind outputKind,
            out bool reportSuppressedDiagnostics,
            out string moduleName,
            out string mainTypeName,
            out string scriptClassName,
            out OptimizationLevel optimizationLevel,
            out bool checkOverflow,
            out string cryptoKeyContainer,
            out string cryptoKeyFile,
            out ImmutableArray <byte> cryptoPublicKey,
            out bool?delaySign,
            out Platform platform,
            out ReportDiagnostic generalDiagnosticOption,
            out int warningLevel,
            out IEnumerable <KeyValuePair <string, ReportDiagnostic> > specificDiagnosticOptions,
            out bool concurrentBuild,
            out bool deterministic,
            out bool publicSign,
            out MetadataImportOptions metadataImportOptions,
            out XmlReferenceResolver xmlReferenceResolver,
            out SourceReferenceResolver sourceReferenceResolver,
            out MetadataReferenceResolver metadataReferenceResolver,
            out AssemblyIdentityComparer assemblyIdentityComparer,
            out StrongNameProvider strongNameProvider,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            outputKind = (OutputKind)reader.ReadInt32();
            reportSuppressedDiagnostics = reader.ReadBoolean();
            moduleName   = reader.ReadString();
            mainTypeName = reader.ReadString();

            scriptClassName   = reader.ReadString();
            optimizationLevel = (OptimizationLevel)reader.ReadInt32();
            checkOverflow     = reader.ReadBoolean();

            // REVIEW: is it okay this being not part of snapshot?
            cryptoKeyContainer = reader.ReadString();
            cryptoKeyFile      = reader.ReadString();

            cryptoPublicKey = reader.ReadArray <byte>().ToImmutableArrayOrEmpty();

            delaySign = reader.ReadBoolean() ? reader.ReadBoolean() : null;

            platform = (Platform)reader.ReadInt32();
            generalDiagnosticOption = (ReportDiagnostic)reader.ReadInt32();

            warningLevel = reader.ReadInt32();

            // REVIEW: I don't think there is a guarantee on ordering of elements in the immutable dictionary.
            //         unfortunately, we need to sort them to make it deterministic
            //         not sure why CompilationOptions uses SequencialEqual to check options equality
            //         when ordering can change result of it even if contents are same.
            var count = reader.ReadInt32();
            List <KeyValuePair <string, ReportDiagnostic> > specificDiagnosticOptionsList = null;

            if (count > 0)
            {
                specificDiagnosticOptionsList = new List <KeyValuePair <string, ReportDiagnostic> >(count);

                for (var i = 0; i < count; i++)
                {
                    var key   = reader.ReadString();
                    var value = (ReportDiagnostic)reader.ReadInt32();

                    specificDiagnosticOptionsList.Add(KeyValuePairUtil.Create(key, value));
                }
            }

            specificDiagnosticOptions = specificDiagnosticOptionsList ?? SpecializedCollections.EmptyEnumerable <KeyValuePair <string, ReportDiagnostic> >();

            concurrentBuild = reader.ReadBoolean();
            deterministic   = reader.ReadBoolean();
            publicSign      = reader.ReadBoolean();

            metadataImportOptions = (MetadataImportOptions)reader.ReadByte();

            // REVIEW: What should I do with these. are these service required when compilation is built ourselves, not through
            //         compiler.
            xmlReferenceResolver      = XmlFileResolver.Default;
            sourceReferenceResolver   = SourceFileResolver.Default;
            metadataReferenceResolver = null;
            assemblyIdentityComparer  = DesktopAssemblyIdentityComparer.Default;
            strongNameProvider        = new DesktopStrongNameProvider();
        }
示例#29
0
        internal PEAssemblySymbol(PEAssembly assembly, DocumentationProvider documentationProvider, bool isLinked, MetadataImportOptions importOptions)
        {
            Debug.Assert(assembly != null);
            Debug.Assert(documentationProvider != null);
            _assembly = assembly;
            _documentationProvider = documentationProvider;

            var modules = new ModuleSymbol[assembly.Modules.Length];

            for (int i = 0; i < assembly.Modules.Length; i++)
            {
                modules[i] = new PEModuleSymbol(this, assembly.Modules[i], importOptions, i);
            }

            _modules  = modules.AsImmutableOrNull();
            _isLinked = isLinked;
        }
        // Expects correct arguments.
        internal CompilationOptions(
            OutputKind outputKind,
            bool reportSuppressedDiagnostics,
            string moduleName,
            string mainTypeName,
            string scriptClassName,
            string cryptoKeyContainer,
            string cryptoKeyFile,
            ImmutableArray <byte> cryptoPublicKey,
            bool?delaySign,
            bool publicSign,
            OptimizationLevel optimizationLevel,
            bool checkOverflow,
            Platform platform,
            ReportDiagnostic generalDiagnosticOption,
            int warningLevel,
            ImmutableDictionary <string, ReportDiagnostic> specificDiagnosticOptions,
            bool concurrentBuild,
            bool deterministic,
            DateTime currentLocalTime,
            bool debugPlusMode,
            XmlReferenceResolver xmlReferenceResolver,
            SourceReferenceResolver sourceReferenceResolver,
            MetadataReferenceResolver metadataReferenceResolver,
            AssemblyIdentityComparer assemblyIdentityComparer,
            StrongNameProvider strongNameProvider,
            MetadataImportOptions metadataImportOptions,
            bool referencesSupersedeLowerVersions)
        {
            this.OutputKind                       = outputKind;
            this.ModuleName                       = moduleName;
            this.MainTypeName                     = mainTypeName;
            this.ScriptClassName                  = scriptClassName ?? WellKnownMemberNames.DefaultScriptClassName;
            this.CryptoKeyContainer               = cryptoKeyContainer;
            this.CryptoKeyFile                    = string.IsNullOrEmpty(cryptoKeyFile) ? null : cryptoKeyFile;
            this.CryptoPublicKey                  = cryptoPublicKey.NullToEmpty();
            this.DelaySign                        = delaySign;
            this.CheckOverflow                    = checkOverflow;
            this.Platform                         = platform;
            this.GeneralDiagnosticOption          = generalDiagnosticOption;
            this.WarningLevel                     = warningLevel;
            this.SpecificDiagnosticOptions        = specificDiagnosticOptions;
            this.ReportSuppressedDiagnostics      = reportSuppressedDiagnostics;
            this.OptimizationLevel                = optimizationLevel;
            this.ConcurrentBuild                  = concurrentBuild;
            this.Deterministic                    = deterministic;
            this.CurrentLocalTime                 = currentLocalTime;
            this.DebugPlusMode                    = debugPlusMode;
            this.XmlReferenceResolver             = xmlReferenceResolver;
            this.SourceReferenceResolver          = sourceReferenceResolver;
            this.MetadataReferenceResolver        = metadataReferenceResolver;
            this.StrongNameProvider               = strongNameProvider;
            this.AssemblyIdentityComparer         = assemblyIdentityComparer ?? AssemblyIdentityComparer.Default;
            this.MetadataImportOptions            = metadataImportOptions;
            this.ReferencesSupersedeLowerVersions = referencesSupersedeLowerVersions;
            this.PublicSign                       = publicSign;

            _lazyErrors = new Lazy <ImmutableArray <Diagnostic> >(() =>
            {
                var builder = ArrayBuilder <Diagnostic> .GetInstance();
                ValidateOptions(builder);
                return(builder.ToImmutableAndFree());
            });
        }
 public CompilationOptions WithMetadataImportOptions(MetadataImportOptions value) => CommonWithMetadataImportOptions(value);
        // Expects correct arguments.
        internal CompilationOptions(
            OutputKind outputKind,
            string moduleName,
            string mainTypeName,
            string scriptClassName,
            string cryptoKeyContainer,
            string cryptoKeyFile,
            bool? delaySign,
            OptimizationLevel optimizationLevel,
            bool checkOverflow,
            int fileAlignment,
            ulong baseAddress,
            Platform platform,
            ReportDiagnostic generalDiagnosticOption,
            int warningLevel,
            ImmutableDictionary<string, ReportDiagnostic> specificDiagnosticOptions,
            bool highEntropyVirtualAddressSpace,
            SubsystemVersion subsystemVersion,
            bool concurrentBuild,
            XmlReferenceResolver xmlReferenceResolver,
            SourceReferenceResolver sourceReferenceResolver,
            MetadataReferenceResolver metadataReferenceResolver,
            MetadataReferenceProvider metadataReferenceProvider,
            AssemblyIdentityComparer assemblyIdentityComparer,
            StrongNameProvider strongNameProvider,
            MetadataImportOptions metadataImportOptions,
            ImmutableArray<string> features)
        {
            this.OutputKind = outputKind;
            this.ModuleName = moduleName;
            this.MainTypeName = mainTypeName;
            this.ScriptClassName = scriptClassName;
            this.CryptoKeyContainer = cryptoKeyContainer;
            this.CryptoKeyFile = cryptoKeyFile;
            this.DelaySign = delaySign;
            this.CheckOverflow = checkOverflow;
            this.FileAlignment = fileAlignment;
            this.BaseAddress = baseAddress;
            this.Platform = platform;
            this.GeneralDiagnosticOption = generalDiagnosticOption;
            this.WarningLevel = warningLevel;
            this.SpecificDiagnosticOptions = specificDiagnosticOptions;
            this.HighEntropyVirtualAddressSpace = highEntropyVirtualAddressSpace;
            this.OptimizationLevel = optimizationLevel;
            this.ConcurrentBuild = concurrentBuild;
            this.SubsystemVersion = subsystemVersion;
            this.XmlReferenceResolver = xmlReferenceResolver;
            this.SourceReferenceResolver = sourceReferenceResolver;
            this.MetadataReferenceResolver = metadataReferenceResolver;
            this.MetadataReferenceProvider = metadataReferenceProvider;
            this.StrongNameProvider = strongNameProvider;
            this.AssemblyIdentityComparer = assemblyIdentityComparer ?? AssemblyIdentityComparer.Default;
            this.MetadataImportOptions = metadataImportOptions;
            this.Features = features;

            this.lazyErrors = new Lazy<ImmutableArray<Diagnostic>>(() =>
            {
                var builder = ArrayBuilder<Diagnostic>.GetInstance();
                ValidateOptions(builder);
                return builder.ToImmutableAndFree();
            });
        }
 protected abstract CompilationOptions CommonWithMetadataImportOptions(MetadataImportOptions value);
示例#34
0
 internal PEModuleSymbol(SourceAssemblySymbol assemblySymbol, PEModule module, MetadataImportOptions importOptions, int ordinal)
     : this((AssemblySymbol)assemblySymbol, module, importOptions, ordinal)
 {
     Debug.Assert(ordinal > 0);
 }
示例#35
0
 internal override CompilationOptions CommonWithMetadataImportOptions(MetadataImportOptions value) =>
 WithMetadataImportOptions(value);
示例#36
0
        // Expects correct arguments.
        internal CompilationOptions(
            OutputKind outputKind,
            bool reportSuppressedDiagnostics,
            string moduleName,
            string mainTypeName,
            string scriptClassName,
            string cryptoKeyContainer,
            string cryptoKeyFile,
            ImmutableArray<byte> cryptoPublicKey,
            bool? delaySign,
            OptimizationLevel optimizationLevel,
            bool checkOverflow,
            Platform platform,
            ReportDiagnostic generalDiagnosticOption,
            int warningLevel,
            ImmutableDictionary<string, ReportDiagnostic> specificDiagnosticOptions,
            bool concurrentBuild,
            bool extendedCustomDebugInformation,
            bool debugPlusMode,
            XmlReferenceResolver xmlReferenceResolver,
            SourceReferenceResolver sourceReferenceResolver,
            MetadataReferenceResolver metadataReferenceResolver,
            AssemblyIdentityComparer assemblyIdentityComparer,
            StrongNameProvider strongNameProvider,
            MetadataImportOptions metadataImportOptions)
        {
            this.OutputKind = outputKind;
            this.ModuleName = moduleName;
            this.MainTypeName = mainTypeName;
            this.ScriptClassName = scriptClassName ?? WellKnownMemberNames.DefaultScriptClassName;
            this.CryptoKeyContainer = cryptoKeyContainer;
            this.CryptoKeyFile = cryptoKeyFile;
            this.CryptoPublicKey = cryptoPublicKey.NullToEmpty();
            this.DelaySign = delaySign;
            this.CheckOverflow = checkOverflow;
            this.Platform = platform;
            this.GeneralDiagnosticOption = generalDiagnosticOption;
            this.WarningLevel = warningLevel;
            this.SpecificDiagnosticOptions = specificDiagnosticOptions;
            this.ReportSuppressedDiagnostics = reportSuppressedDiagnostics;
            this.OptimizationLevel = optimizationLevel;
            this.ConcurrentBuild = concurrentBuild;
            this.ExtendedCustomDebugInformation = extendedCustomDebugInformation;
            this.DebugPlusMode = debugPlusMode;
            this.XmlReferenceResolver = xmlReferenceResolver;
            this.SourceReferenceResolver = sourceReferenceResolver;
            this.MetadataReferenceResolver = metadataReferenceResolver;
            this.StrongNameProvider = strongNameProvider;
            this.AssemblyIdentityComparer = assemblyIdentityComparer ?? AssemblyIdentityComparer.Default;
            this.MetadataImportOptions = metadataImportOptions;

            _lazyErrors = new Lazy<ImmutableArray<Diagnostic>>(() =>
            {
                var builder = ArrayBuilder<Diagnostic>.GetInstance();
                ValidateOptions(builder);
                return builder.ToImmutableAndFree();
            });
        }
示例#37
0
            private IModuleSymbol GetModuleSymbolForEmittedImage(ImmutableArray <byte> peImage, MetadataImportOptions importOptions)
            {
                if (peImage.IsDefault)
                {
                    return(null);
                }

                var targetReference = LoadTestEmittedExecutableForSymbolValidation(peImage, _compilation.Options.OutputKind, display: _compilation.AssemblyName);
                var references      = _compilation.References.Concat(new[] { targetReference });
                var assemblies      = _test.ReferencesToModuleSymbols(references, importOptions);

                return(assemblies.Last());
            }
            private IModuleSymbol GetModuleSymbolForEmittedImage(ImmutableArray<byte> peImage, MetadataImportOptions importOptions)
            {
                if (peImage.IsDefault)
                {
                    return null;
                }

                var targetReference = LoadTestEmittedExecutableForSymbolValidation(peImage, _compilation.Options.OutputKind, display: _compilation.AssemblyName);
                var references = _compilation.References.Concat(new[] { targetReference });
                var assemblies = _test.ReferencesToModuleSymbols(references, importOptions);
                return assemblies.Last();
            }
示例#39
0
        private IEnumerable <IModuleSymbol> GetReferencesToModuleSymbols(IEnumerable <MetadataReference> references, MetadataImportOptions importOptions)
        {
            var dummy = _compilation
                        .RemoveAllSyntaxTrees()
                        .WithReferences(references)
                        .WithAssemblyName("Dummy")
                        .WithOptions(_compilation.Options.WithMetadataImportOptions(importOptions));

            return(references.Select(reference =>
            {
                if (reference.Properties.Kind == MetadataImageKind.Assembly)
                {
                    return ((IAssemblySymbol)dummy.GetAssemblyOrModuleSymbol(reference))?.Modules.First();
                }
                else
                {
                    return (IModuleSymbol)dummy.GetAssemblyOrModuleSymbol(reference);
                }
            }));
        }