public PEDeltaAssemblyBuilder(
            SourceAssemblySymbol sourceAssembly,
            string outputName,
            OutputKind outputKind,
            ModulePropertiesForSerialization serializationProperties,
            IEnumerable<ResourceDescription> manifestResources,
            Func<AssemblySymbol, AssemblyIdentity> assemblySymbolMapper,
            EmitBaseline previousGeneration,
            IEnumerable<SemanticEdit> edits)
            : base(sourceAssembly, outputName, outputKind, serializationProperties, manifestResources, assemblySymbolMapper, additionalTypes: ImmutableArray<NamedTypeSymbol>.Empty, metadataOnly:false)
        {
            var context = new EmitContext(this, null, new DiagnosticBag());
            var module = previousGeneration.OriginalMetadata;
            var compilation = sourceAssembly.DeclaringCompilation;
            var metadataAssembly = compilation.GetBoundReferenceManager().CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata.Create(module), MetadataImportOptions.All);
            var metadataDecoder = new Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.MetadataDecoder(metadataAssembly.PrimaryModule);

            previousGeneration = EnsureInitialized(previousGeneration, metadataDecoder);

            var matchToMetadata = new SymbolMatcher(previousGeneration.AnonymousTypeMap, sourceAssembly, context, metadataAssembly);

            SymbolMatcher matchToPrevious = null;
            if (previousGeneration.Ordinal > 0)
            {
                var previousAssembly = ((CSharpCompilation)previousGeneration.Compilation).SourceAssembly;
                var previousContext = new EmitContext((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag());
                matchToPrevious = new SymbolMatcher(previousGeneration.AnonymousTypeMap, sourceAssembly, context, previousAssembly, previousContext);
            }

            this.previousDefinitions = new CSharpDefinitionMap(previousGeneration.OriginalMetadata.Module, edits, metadataDecoder, matchToMetadata, matchToPrevious);
            this.previousGeneration = previousGeneration;
            this.changes = new SymbolChanges(this.previousDefinitions, edits);
        }
Exemple #2
0
        public EEAssemblyBuilder(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            ImmutableArray<MethodSymbol> methods,
            ModulePropertiesForSerialization serializationProperties,
            ImmutableArray<NamedTypeSymbol> additionalTypes,
            NamedTypeSymbol dynamicOperationContextType,
            CompilationTestData testData) :
            base(
                  sourceAssembly,
                  emitOptions,
                  outputKind: OutputKind.DynamicallyLinkedLibrary,
                  serializationProperties: serializationProperties,
                  manifestResources: SpecializedCollections.EmptyEnumerable<ResourceDescription>(),
                  additionalTypes: additionalTypes)
        {
            Methods = ImmutableHashSet.CreateRange(methods);
            _dynamicOperationContextType = dynamicOperationContextType;

            if (testData != null)
            {
                this.SetMethodTestData(testData.Methods);
                testData.Module = this;
            }
        }
        public PEDeltaAssemblyBuilder(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            OutputKind outputKind,
            Cci.ModulePropertiesForSerialization serializationProperties,
            IEnumerable<ResourceDescription> manifestResources,
            EmitBaseline previousGeneration,
            IEnumerable<SemanticEdit> edits,
            Func<ISymbol, bool> isAddedSymbol)
            : base(sourceAssembly, emitOptions, outputKind, serializationProperties, manifestResources, additionalTypes: ImmutableArray<NamedTypeSymbol>.Empty)
        {
            var initialBaseline = previousGeneration.InitialBaseline;
            var context = new EmitContext(this, null, new DiagnosticBag());

            // Hydrate symbols from initial metadata. Once we do so it is important to reuse these symbols across all generations,
            // in order for the symbol matcher to be able to use reference equality once it maps symbols to initial metadata.
            var metadataSymbols = GetOrCreateMetadataSymbols(initialBaseline, sourceAssembly.DeclaringCompilation);
            var metadataDecoder = (MetadataDecoder)metadataSymbols.MetadataDecoder;
            var metadataAssembly = (PEAssemblySymbol)metadataDecoder.ModuleSymbol.ContainingAssembly;

            var matchToMetadata = new CSharpSymbolMatcher(metadataSymbols.AnonymousTypes, sourceAssembly, context, metadataAssembly);

            CSharpSymbolMatcher matchToPrevious = null;
            if (previousGeneration.Ordinal > 0)
            {
                var previousAssembly = ((CSharpCompilation)previousGeneration.Compilation).SourceAssembly;
                var previousContext = new EmitContext((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag());

                matchToPrevious = new CSharpSymbolMatcher(
                    previousGeneration.AnonymousTypeMap,
                    sourceAssembly: sourceAssembly,
                    sourceContext: context,
                    otherAssembly: previousAssembly,
                    otherContext: previousContext,
                    otherSynthesizedMembersOpt: previousGeneration.SynthesizedMembers);
            }

            _previousDefinitions = new CSharpDefinitionMap(previousGeneration.OriginalMetadata.Module, edits, metadataDecoder, matchToMetadata, matchToPrevious);
            _previousGeneration = previousGeneration;
            _changes = new SymbolChanges(_previousDefinitions, edits, isAddedSymbol);

            // Workaround for https://github.com/dotnet/roslyn/issues/3192.
            // When compiling state machine we stash types of awaiters and state-machine hoisted variables,
            // so that next generation can look variables up and reuse their slots if possible.
            //
            // When we are about to allocate a slot for a lifted variable while compiling the next generation
            // we map its type to the previous generation and then check the slot types that we stashed earlier.
            // If the variable type matches we reuse it. In order to compare the previous variable type with the current one
            // both need to be completely lowered (translated). Standard translation only goes one level deep. 
            // Generic arguments are not translated until they are needed by metadata writer. 
            //
            // In order to get the fully lowered form we run the type symbols of stashed variables thru a deep translator
            // that translates the symbol recursively.
            _deepTranslator = new CSharpSymbolMatcher.DeepTranslator(sourceAssembly.GetSpecialType(SpecialType.System_Object));
        }
        internal SourceModuleSymbol(
            SourceAssemblySymbol assemblySymbol,
            DeclarationTable declarations,
            string moduleName)
        {
            Debug.Assert((object)assemblySymbol != null);

            _assemblySymbol = assemblySymbol;
            _sources = declarations;
            _name = moduleName;
        }
        internal SourceModuleSymbol(
            SourceAssemblySymbol assemblySymbol,
            DeclarationTable declarations,
            string nameWithExtension)
        {
            Debug.Assert((object)assemblySymbol != null);

            this.assemblySymbol = assemblySymbol;
            this.sources = declarations;
            this.name = nameWithExtension;
        }
        public CSharpSymbolMatcher(
            IReadOnlyDictionary <AnonymousTypeKey, AnonymousTypeValue> anonymousTypeMap,
            SourceAssemblySymbol sourceAssembly,
            EmitContext sourceContext,
            PEAssemblySymbol otherAssembly)
        {
            _defs = new MatchDefsToMetadata(sourceContext, otherAssembly);

            _symbols = new MatchSymbols(
                anonymousTypeMap,
                sourceAssembly,
                otherAssembly,
                otherSynthesizedMembersOpt: null,
                deepTranslatorOpt: null);
        }
Exemple #7
0
 public MatchSymbols(
     IReadOnlyDictionary <AnonymousTypeKey, AnonymousTypeValue> anonymousTypeMap,
     SourceAssemblySymbol sourceAssembly,
     AssemblySymbol otherAssembly,
     ImmutableDictionary <Cci.ITypeDefinition, ImmutableArray <Cci.ITypeDefinitionMember> > otherSynthesizedMembersOpt,
     DeepTranslator deepTranslatorOpt)
 {
     _anonymousTypeMap           = anonymousTypeMap;
     _sourceAssembly             = sourceAssembly;
     _otherAssembly              = otherAssembly;
     _otherSynthesizedMembersOpt = otherSynthesizedMembersOpt;
     _comparer         = new SymbolComparer(this, deepTranslatorOpt);
     _matches          = new ConcurrentDictionary <Symbol, Symbol>(ReferenceEqualityComparer.Instance);
     _otherTypeMembers = new ConcurrentDictionary <NamedTypeSymbol, IReadOnlyDictionary <string, ImmutableArray <Cci.ITypeDefinitionMember> > >();
 }
Exemple #8
0
        internal new ReferenceManager GetBoundReferenceManager()
        {
            if (_lazyAssemblySymbol == null)
            {
                lock (_referenceManager)
                {
                    _lazyAssemblySymbol = _referenceManager.CreateSourceAssemblyForCompilation(this);
                }
                Debug.Assert(_lazyAssemblySymbol != null);
            }

            // referenceManager can only be accessed after we initialized the lazyAssemblySymbol.
            // In fact, initialization of the assembly symbol might change the reference manager.
            return(_referenceManager);
        }
Exemple #9
0
        internal NamespaceSymbol Get_System_NamespaceSymbol(ModuleSymbol m)
        {
            var assembly = m.ContainingSymbol;
            SourceAssemblySymbol sourceAssembly = assembly as SourceAssemblySymbol;

            if (sourceAssembly != null)
            {
                return(sourceAssembly.DeclaringCompilation.GlobalNamespace.GetMember <NamespaceSymbol>("System"));
            }
            else
            {
                var peAssembly = (PEAssemblySymbol)assembly;
                return(peAssembly.CorLibrary.GlobalNamespace.GetMember <NamespaceSymbol>("System"));
            }
        }
Exemple #10
0
 public PEAssemblyBuilder(
     SourceAssemblySymbol sourceAssembly,
     EmitOptions emitOptions,
     OutputKind outputKind,
     Cci.ModulePropertiesForSerialization serializationProperties,
     IEnumerable <ResourceDescription> manifestResources
     )
     : base(
         sourceAssembly,
         emitOptions,
         outputKind,
         serializationProperties,
         manifestResources,
         ImmutableArray <NamedTypeSymbol> .Empty
         )
 {
 }
        public PEAssemblyBuilderBase(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            OutputKind outputKind,
            Cci.ModulePropertiesForSerialization serializationProperties,
            IEnumerable <ResourceDescription> manifestResources,
            ImmutableArray <NamedTypeSymbol> additionalTypes)
            : base((SourceModuleSymbol)sourceAssembly.Modules[0], emitOptions, outputKind, serializationProperties, manifestResources)
        {
            Debug.Assert((object)sourceAssembly != null);

            _sourceAssembly  = sourceAssembly;
            _additionalTypes = additionalTypes.NullToEmpty();
            _metadataName    = (emitOptions.OutputNameOverride == null) ? sourceAssembly.MetadataName : FileNameUtilities.ChangeExtension(emitOptions.OutputNameOverride, extension: null);

            AssemblyOrModuleSymbolToModuleRefMap.Add(sourceAssembly, this);
        }
        public PEAssemblyBuilderBase(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            OutputKind outputKind,
            Cci.ModulePropertiesForSerialization serializationProperties,
            IEnumerable<ResourceDescription> manifestResources,
            ImmutableArray<NamedTypeSymbol> additionalTypes)
            : base((SourceModuleSymbol)sourceAssembly.Modules[0], emitOptions, outputKind, serializationProperties, manifestResources)
        {
            Debug.Assert((object)sourceAssembly != null);

            _sourceAssembly = sourceAssembly;
            _additionalTypes = additionalTypes.NullToEmpty();
            _metadataName = (emitOptions.OutputNameOverride == null) ? sourceAssembly.MetadataName : FileNameUtilities.ChangeExtension(emitOptions.OutputNameOverride, extension: null);

            AssemblyOrModuleSymbolToModuleRefMap.Add(sourceAssembly, this);
        }
        internal SourceModuleSymbol(
            SourceAssemblySymbol assemblySymbol,
            MutableModel modelBuilder,
            DeclarationTable declarations,
            string moduleName)
        {
            Debug.Assert((object)assemblySymbol != null);

            _assemblySymbol = assemblySymbol;
            _modelBuilder   = modelBuilder;
            _sources        = declarations;
            _name           = moduleName;

            _csharpSymbolMap = new CSharpSymbolMap(this);

            _state = SymbolCompletionState.Create(assemblySymbol.Language);
        }
        public PEDeltaAssemblyBuilder(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            OutputKind outputKind,
            ModulePropertiesForSerialization serializationProperties,
            IEnumerable <ResourceDescription> manifestResources,
            EmitBaseline previousGeneration,
            IEnumerable <SemanticEdit> edits,
            Func <ISymbol, bool> isAddedSymbol)
            : base(sourceAssembly, emitOptions, outputKind, serializationProperties, manifestResources, assemblySymbolMapper: null, additionalTypes: ImmutableArray <NamedTypeSymbol> .Empty)
        {
            var initialBaseline  = previousGeneration.InitialBaseline;
            var context          = new EmitContext(this, null, new DiagnosticBag());
            var module           = previousGeneration.OriginalMetadata;
            var compilation      = sourceAssembly.DeclaringCompilation;
            var metadataAssembly = compilation.GetBoundReferenceManager().CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata.Create(module), MetadataImportOptions.All);
            var metadataDecoder  = new Symbols.Metadata.PE.MetadataDecoder(metadataAssembly.PrimaryModule);

            if (initialBaseline.LazyOriginalMetadataAnonymousTypeMap == null)
            {
                initialBaseline.LazyOriginalMetadataAnonymousTypeMap = GetAnonymousTypeMapFromMetadata(module.MetadataReader, metadataDecoder);
            }

            var matchToMetadata = new CSharpSymbolMatcher(initialBaseline.LazyOriginalMetadataAnonymousTypeMap, sourceAssembly, context, metadataAssembly);

            CSharpSymbolMatcher matchToPrevious = null;

            if (previousGeneration.Ordinal > 0)
            {
                var previousAssembly = ((CSharpCompilation)previousGeneration.Compilation).SourceAssembly;
                var previousContext  = new EmitContext((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag());

                matchToPrevious = new CSharpSymbolMatcher(
                    previousGeneration.AnonymousTypeMap,
                    sourceAssembly: sourceAssembly,
                    sourceContext: context,
                    otherAssembly: previousAssembly,
                    otherContext: previousContext,
                    otherSynthesizedMembersOpt: previousGeneration.SynthesizedMembers);
            }

            _previousDefinitions = new CSharpDefinitionMap(previousGeneration.OriginalMetadata.Module, edits, metadataDecoder, matchToMetadata, matchToPrevious);
            _previousGeneration  = previousGeneration;
            _changes             = new SymbolChanges(_previousDefinitions, edits, isAddedSymbol);
        }
Exemple #15
0
        public PEAssemblyBuilderBase(
            SourceAssemblySymbol sourceAssembly,
            string outputName,
            OutputKind outputKind,
            ModulePropertiesForSerialization serializationProperties,
            IEnumerable<ResourceDescription> manifestResources,
            Func<AssemblySymbol, AssemblyIdentity> assemblySymbolMapper,
            ImmutableArray<NamedTypeSymbol> additionalTypes)
            : base((SourceModuleSymbol)sourceAssembly.Modules[0], outputName, outputKind, serializationProperties, manifestResources, assemblySymbolMapper)
        {
            Debug.Assert((object)sourceAssembly != null);

            this.sourceAssembly = sourceAssembly;
            this.additionalTypes = additionalTypes.NullToEmpty();
            this.metadataName = outputName == null ? sourceAssembly.MetadataName : PathUtilities.RemoveExtension(outputName);

            AssemblyOrModuleSymbolToModuleRefMap.Add(sourceAssembly, this);
        }
        public PEAssemblyBuilderBase(
            SourceAssemblySymbol sourceAssembly,
            string outputName,
            OutputKind outputKind,
            ModulePropertiesForSerialization serializationProperties,
            IEnumerable <ResourceDescription> manifestResources,
            Func <AssemblySymbol, AssemblyIdentity> assemblySymbolMapper,
            ImmutableArray <NamedTypeSymbol> additionalTypes)
            : base((SourceModuleSymbol)sourceAssembly.Modules[0], outputName, outputKind, serializationProperties, manifestResources, assemblySymbolMapper)
        {
            Debug.Assert((object)sourceAssembly != null);

            this.sourceAssembly  = sourceAssembly;
            this.additionalTypes = additionalTypes.NullToEmpty();
            this.metadataName    = outputName == null ? sourceAssembly.MetadataName : PathUtilities.RemoveExtension(outputName);

            AssemblyOrModuleSymbolToModuleRefMap.Add(sourceAssembly, this);
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="underlyingAssembly">
        /// The underlying AssemblySymbol, cannot be an instance of RetargetingAssemblySymbol.
        /// </param>
        /// <param name="isLinked">
        /// Assembly is /l-ed by compilation that is using it as a reference.
        /// </param>
        internal RetargetingAssemblySymbol(SourceAssemblySymbol underlyingAssembly, bool isLinked)
        {
            Debug.Assert((object)underlyingAssembly != null);

            _underlyingAssembly = underlyingAssembly;

            ModuleSymbol[] modules = new ModuleSymbol[underlyingAssembly.Modules.Length];

            modules[0] = new RetargetingModuleSymbol(this, (SourceModuleSymbol)underlyingAssembly.Modules[0]);

            for (int i = 1; i < underlyingAssembly.Modules.Length; i++)
            {
                CSharpModuleSymbol under = (CSharpModuleSymbol)underlyingAssembly.Modules[i];
                modules[i] = new CSharpModuleSymbol(this, under.UnderlyingModule, i);
            }

            _modules  = modules.AsImmutableOrNull();
            _isLinked = isLinked;
        }
Exemple #18
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="underlyingAssembly">
        /// The underlying AssemblySymbol, cannot be an instance of RetargetingAssemblySymbol.
        /// </param>
        /// <param name="isLinked">
        /// Assembly is /l-ed by compilation that is using it as a reference.
        /// </param>
        public RetargetingAssemblySymbol(SourceAssemblySymbol underlyingAssembly, bool isLinked)
        {
            Debug.Assert((object)underlyingAssembly != null);

            _underlyingAssembly = underlyingAssembly;

            ModuleSymbol[] modules = new ModuleSymbol[underlyingAssembly.Modules.Length];

            modules[0] = new RetargetingModuleSymbol(this, (SourceModuleSymbol)underlyingAssembly.Modules[0]);

            for (int i = 1; i < underlyingAssembly.Modules.Length; i++)
            {
                PEModuleSymbol under = (PEModuleSymbol)underlyingAssembly.Modules[i];
                modules[i] = new PEModuleSymbol(this, under.Module, under.ImportOptions, i);
            }

            _modules  = modules.AsImmutableOrNull();
            _isLinked = isLinked;
        }
Exemple #19
0
        private static void GetConstants(
            ArrayBuilder <LocalSymbol> builder,
            MethodSymbol method,
            ArrayBuilder <ISymUnmanagedScope> scopes,
            MetadataDecoder metadataDecoder,
            ImmutableDictionary <string, ImmutableArray <bool> > dynamicLocalConstantMap,
            SourceAssemblySymbol containingAssembly)
        {
            foreach (var scope in scopes)
            {
                foreach (var constant in scope.GetConstants())
                {
                    string name      = constant.GetName();
                    object rawValue  = constant.GetValue();
                    var    signature = constant.GetSignature();

                    var info = metadataDecoder.GetLocalInfo(signature);
                    Debug.Assert(!info.IsByRef);
                    Debug.Assert(!info.IsPinned);
                    var type = info.Type;
                    if (type.IsErrorType())
                    {
                        continue;
                    }

                    var constantValue = PdbHelpers.GetConstantValue(type.EnumUnderlyingType(), rawValue);

                    ImmutableArray <bool> dynamicFlags;
                    if (dynamicLocalConstantMap != null && dynamicLocalConstantMap.TryGetValue(name, out dynamicFlags))
                    {
                        type = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(
                            type,
                            containingAssembly,
                            RefKind.None,
                            dynamicFlags);
                    }

                    builder.Add(new EELocalConstantSymbol(method, name, type, constantValue));
                }
            }
        }
Exemple #20
0
        /// <summary>
        /// Is it possible that the given symbol can be accessed somewhere in the given assembly?
        /// For the purposes of this test, we assume that code in the given assembly might derive from
        /// any type. So protected members are considered potentially accessible.
        /// </summary>
        private static bool IsAccessibleInAssembly(Symbol symbol, SourceAssemblySymbol assembly)
        {
            for (; symbol != null && symbol.Kind != SymbolKind.Namespace; symbol = symbol.ContainingSymbol)
            {
                switch (symbol.DeclaredAccessibility)
                {
                case Accessibility.Internal:
                case Accessibility.ProtectedAndInternal:
                    if (!assembly.HasInternalAccessTo(symbol.ContainingAssembly))
                    {
                        return(false);
                    }
                    break;

                case Accessibility.Private:
                    return(false);
                }
            }

            return(true);
        }
Exemple #21
0
        public EEAssemblyBuilder(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            Cci.ModulePropertiesForSerialization serializationProperties,
            ImmutableArray <NamedTypeSymbol> additionalTypes,
            Func <NamedTypeSymbol, NamedTypeSymbol> getDynamicOperationContextType,
            CompilationTestData?testData) :
            base(
                sourceAssembly,
                emitOptions,
                outputKind: OutputKind.DynamicallyLinkedLibrary,
                serializationProperties: serializationProperties,
                manifestResources: SpecializedCollections.EmptyEnumerable <ResourceDescription>(),
                additionalTypes: additionalTypes)
        {
            _getDynamicOperationContextType = getDynamicOperationContextType;

            if (testData != null)
            {
                this.SetMethodTestData(testData.Methods);
                testData.Module = this;
            }
        }
        public EEAssemblyBuilder(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            ImmutableArray <MethodSymbol> methods,
            ModulePropertiesForSerialization serializationProperties,
            ImmutableArray <NamedTypeSymbol> additionalTypes,
            CompilationTestData testData) :
            base(
                sourceAssembly,
                emitOptions,
                outputKind: OutputKind.DynamicallyLinkedLibrary,
                serializationProperties: serializationProperties,
                manifestResources: SpecializedCollections.EmptyEnumerable <ResourceDescription>(),
                assemblySymbolMapper: null,
                additionalTypes: additionalTypes)
        {
            _methods = ImmutableHashSet.CreateRange(methods);

            if (testData != null)
            {
                this.SetMethodTestData(testData.Methods);
                testData.Module = this;
            }
        }
Exemple #23
0
 /// <summary>
 /// A helper method for ReferenceManager to set assembly identities for assemblies
 /// referenced by this module and corresponding AssemblySymbols.
 /// </summary>
 /// <param name="moduleReferences">A description of the assemblies referenced by this module.</param>
 /// <param name="originatingSourceAssemblyDebugOnly">
 /// Source assembly that triggered creation of this module symbol.
 /// For debug purposes only, this assembly symbol should not be persisted within
 /// this module symbol because the module can be shared across multiple source
 /// assemblies. This method will only be called for the first one.
 /// </param>
 internal abstract void SetReferences(ModuleReferences <AssemblySymbol> moduleReferences, SourceAssemblySymbol originatingSourceAssemblyDebugOnly = null);
        private void VerifyRuntimeCompatibilityAttribute(CSharpAttributeData attribute, SourceAssemblySymbol sourceAssembly, bool isSynthesized)
        {
            ModuleSymbol module = sourceAssembly.Modules[0];
            NamespaceSymbol compilerServicesNS = Get_System_Runtime_CompilerServices_NamespaceSymbol(module);

            NamedTypeSymbol runtimeCompatibilityAttrType = compilerServicesNS.GetTypeMember("RuntimeCompatibilityAttribute");
            var runtimeCompatibilityCtor = (MethodSymbol)sourceAssembly.DeclaringCompilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_RuntimeCompatibilityAttribute__ctor);

            Assert.Equal(runtimeCompatibilityAttrType, attribute.AttributeClass);
            Assert.Equal(runtimeCompatibilityCtor, attribute.AttributeConstructor);

            Assert.Equal(0, attribute.CommonConstructorArguments.Length);

            if (isSynthesized)
            {
                Assert.Equal(1, attribute.CommonNamedArguments.Length);
                attribute.VerifyNamedArgumentValue<bool>(0, "WrapNonExceptionThrows", TypedConstantKind.Primitive, true);
            }
            else
            {
                Assert.Equal(0, attribute.CommonNamedArguments.Length);
            }
        }
        private void VerifySynthesizedDebuggableAttribute(CSharpAttributeData attribute, SourceAssemblySymbol sourceAssembly, OptimizationLevel optimizations)
        {
            var expectedDebuggingMode = DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints;

            if (optimizations == OptimizationLevel.Debug)
            {
                expectedDebuggingMode |=
                    DebuggableAttribute.DebuggingModes.Default |
                    DebuggableAttribute.DebuggingModes.DisableOptimizations |
                    DebuggableAttribute.DebuggingModes.EnableEditAndContinue;
            }

            VerifyDebuggableAttribute(attribute, sourceAssembly, expectedDebuggingMode);
        }
Exemple #26
0
 /// <summary>
 /// Create a cache for computing whether or not a struct type is "empty".
 /// </summary>
 /// <param name="dev12CompilerCompatibility">Enable compatibility with the native compiler, which
 ///  ignores inaccessible fields of reference type for structs loaded from metadata.</param>
 /// <param name="compilation">if <see cref="_dev12CompilerCompatibility"/> is true, set to the compilation from
 /// which to check accessibility.</param>
 internal EmptyStructTypeCache(Compilation compilation, bool dev12CompilerCompatibility)
 {
     Debug.Assert(compilation != null || !dev12CompilerCompatibility);
     _dev12CompilerCompatibility = dev12CompilerCompatibility;
     _sourceAssembly             = (SourceAssemblySymbol)compilation?.Assembly;
 }
Exemple #27
0
            internal SourceAssemblySymbol CreateSourceAssemblyForCompilation(PhpCompilation compilation)
            {
                if (compilation._lazyAssemblySymbol != null)
                {
                    return(compilation._lazyAssemblySymbol);
                }

                var resolver   = compilation.Options.MetadataReferenceResolver;
                var moduleName = compilation.MakeSourceModuleName();

                var assemblies = new List <AssemblySymbol>();

                if (_lazyExplicitReferences.IsDefault)
                {
                    //
                    var externalRefs = compilation.ExternalReferences;
                    var refmodules   = new List <PEModuleSymbol>();

                    var referencesMap = new Dictionary <MetadataReference, IAssemblySymbol>();
                    var metadataMap   = new Dictionary <IAssemblySymbol, MetadataReference>();
                    var assembliesMap = new Dictionary <AssemblyIdentity, PEAssemblySymbol>();

                    foreach (PortableExecutableReference pe in externalRefs)
                    {
                        var peass = ((AssemblyMetadata)pe.GetMetadata()).GetAssembly();

                        var symbol = _observedMetadata.TryGetOrDefault(peass.Identity) ?? PEAssemblySymbol.Create(pe, peass);
                        if (symbol != null)
                        {
                            assemblies.Add(symbol);
                            referencesMap[pe]   = symbol;
                            metadataMap[symbol] = pe;

                            if (_lazyCorLibrary == null && symbol.IsCorLibrary)
                            {
                                _lazyCorLibrary = symbol;
                            }

                            if (_lazyPhpCorLibrary == null && symbol.IsPchpCorLibrary)
                            {
                                _lazyPhpCorLibrary = symbol;
                            }

                            // cache bound assembly symbol
                            _observedMetadata[symbol.Identity] = symbol;

                            // list of modules to initialize later
                            refmodules.AddRange(symbol.Modules.Cast <PEModuleSymbol>());
                        }
                        else
                        {
                            throw new Exception($"symbol '{pe.FilePath}' could not be created!");
                        }
                    }

                    //
                    _lazyExplicitReferences = externalRefs;
                    _lazyImplicitReferences = ImmutableArray <MetadataReference> .Empty;
                    _metadataMap            = metadataMap.ToImmutableDictionary();
                    _referencesMap          = referencesMap.ToImmutableDictionary();

                    //
                    assemblies.ForEach(ass => ass.SetCorLibrary(_lazyCorLibrary));

                    // recursively initialize references of referenced modules
                    SetReferencesOfReferencedModules(resolver, refmodules);
                }
                else
                {
                    foreach (PortableExecutableReference pe in _lazyExplicitReferences)
                    {
                        var ass = (AssemblySymbol)_referencesMap[pe];
                        Debug.Assert(ass != null);
                        assemblies.Add(ass);
                    }
                }

                //
                var assembly = new SourceAssemblySymbol(compilation, this.SimpleAssemblyName, moduleName);

                assembly.SetCorLibrary(_lazyCorLibrary);
                assembly.SourceModule.SetReferences(new ModuleReferences <AssemblySymbol>(
                                                        assemblies.Select(x => x.Identity).AsImmutable(),
                                                        assemblies.AsImmutable(),
                                                        ImmutableArray <UnifiedAssembly <AssemblySymbol> > .Empty), assembly);

                // set cor types for this compilation
                if (_lazyPhpCorLibrary == null)
                {
                    throw new DllNotFoundException("Peachpie.Runtime not found");
                }
                if (_lazyCorLibrary == null)
                {
                    throw new DllNotFoundException("A corlib not found");
                }

                compilation.CoreTypes.Update(_lazyPhpCorLibrary);
                compilation.CoreTypes.Update(_lazyCorLibrary);

                //
                return(assembly);
            }
        /// <summary>
        /// Is it possible that the given symbol can be accessed somewhere in the given assembly?
        /// For the purposes of this test, we assume that code in the given assembly might derive from
        /// any type. So protected members are considered potentially accessible.
        /// </summary>
        private static bool IsAccessibleInAssembly(Symbol symbol, SourceAssemblySymbol assembly)
        {
            for (; symbol != null && symbol.Kind != SymbolKind.Namespace; symbol = symbol.ContainingSymbol)
            {
                switch (symbol.DeclaredAccessibility)
                {
                    case Accessibility.Internal:
                    case Accessibility.ProtectedAndInternal:
                        if (!assembly.HasInternalAccessTo(symbol.ContainingAssembly)) return false;
                        break;

                    case Accessibility.Private:
                        return false;
                }
            }

            return true;
        }
Exemple #29
0
 internal PEModuleSymbol(SourceAssemblySymbol assemblySymbol, PEModule module, MetadataImportOptions importOptions, int ordinal)
     : this((AssemblySymbol)assemblySymbol, module, importOptions, ordinal)
 {
     Debug.Assert(ordinal > 0);
 }
 public CSharpEESymbolProvider(SourceAssemblySymbol sourceAssembly, PEModuleSymbol module, PEMethodSymbol method)
 {
     _metadataDecoder = new MetadataDecoder(module, method);
     _sourceAssembly  = sourceAssembly;
     _method          = method;
 }
Exemple #31
0
        /// <summary>
        /// A helper method for ReferenceManager to set assembly identities for assemblies
        /// referenced by this module and corresponding AssemblySymbols.
        /// </summary>
        internal override void SetReferences(ModuleReferences <AssemblySymbol> moduleReferences, SourceAssemblySymbol originatingSourceAssemblyDebugOnly = null)
        {
            Debug.Assert(moduleReferences != null);

            AssertReferencesUninitialized();

            _moduleReferences = moduleReferences;
        }
 public PEAssemblyBuilder(
     SourceAssemblySymbol sourceAssembly,
     string outputName,
     OutputKind outputKind,
     ModulePropertiesForSerialization serializationProperties,
     IEnumerable<ResourceDescription> manifestResources,
     Func<AssemblySymbol, AssemblyIdentity> assemblySymbolMapper = null,
     ImmutableArray<NamedTypeSymbol> additionalTypes = default(ImmutableArray<NamedTypeSymbol>),
     bool metadataOnly = false)
     : base(sourceAssembly, outputName, outputKind, serializationProperties, manifestResources, assemblySymbolMapper, additionalTypes, metadataOnly)
 {
 }
            private DynamicAttributeValidator(CSharpCompilation compilation)
            {
                _comp = compilation;
                _srcAssembly = compilation.SourceAssembly;
                NamespaceSymbol globalNamespace = _srcAssembly.Modules[0].GlobalNamespace;

                _base0Class = globalNamespace.GetMember<NamedTypeSymbol>("Base0");
                _base1Class = globalNamespace.GetMember<NamedTypeSymbol>("Base1");
                _base2Class = globalNamespace.GetMember<NamedTypeSymbol>("Base2");
                _derivedClass = globalNamespace.GetMember<NamedTypeSymbol>("Derived");
                _outerClass = globalNamespace.GetMember<NamedTypeSymbol>("Outer");
                _innerClass = _outerClass.GetTypeMember("Inner");
                _innerInnerClass = _innerClass.GetTypeMember("InnerInner");
                _outer2Class = globalNamespace.GetMember<NamedTypeSymbol>("Outer2");
                _inner2Class = _outer2Class.GetTypeMember("Inner2");
                _innerInner2Class = _inner2Class.GetTypeMember("InnerInner2");
                _outer3Class = globalNamespace.GetMember<NamedTypeSymbol>("Outer3");
                _inner3Class = _outer3Class.GetTypeMember("Inner3");
                _unsafeClass = globalNamespace.GetMember<NamedTypeSymbol>("UnsafeClass");
                _structType = globalNamespace.GetMember<NamedTypeSymbol>("Struct");
                _synthesizedMyDelegateType = globalNamespace.GetMember<NamedTypeSymbol>("MyDelegate");

                _dynamicAttributeCtorNoArgs = (MethodSymbol)compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_DynamicAttribute__ctor);
                _dynamicAttributeCtorTransformFlags = (MethodSymbol)compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_DynamicAttribute__ctorTransformFlags);

                _expectedTransformFlags = null;
            }
        /// <summary>
        /// Returns symbols for the locals emitted in the original method,
        /// based on the local signatures from the IL and the names and
        /// slots from the PDB. The actual locals are needed to ensure the
        /// local slots in the generated method match the original.
        /// </summary>
        private static void GetLocals(
            ArrayBuilder<LocalSymbol> builder,
            MethodSymbol method,
            ImmutableArray<string> names,
            ImmutableArray<LocalInfo<TypeSymbol>> localInfo,
            ImmutableDictionary<int, ImmutableArray<bool>> dynamicLocalMap,
            SourceAssemblySymbol containingAssembly)
        {
            if (localInfo.Length == 0)
            {
                // When debugging a .dmp without a heap, localInfo will be empty although
                // names may be non-empty if there is a PDB. Since there's no type info, the
                // locals are dropped. Note this means the local signature of any generated
                // method will not match the original signature, so new locals will overlap
                // original locals. That is ok since there is no live process for the debugger
                // to update (any modified values exist in the debugger only).
                return;
            }

            Debug.Assert(localInfo.Length >= names.Length);

            for (int i = 0; i < localInfo.Length; i++)
            {
                var name = (i < names.Length) ? names[i] : null;
                var info = localInfo[i];
                var isPinned = info.IsPinned;

                LocalDeclarationKind kind;
                RefKind refKind;
                TypeSymbol type;
                if (info.IsByRef && isPinned)
                {
                    kind = LocalDeclarationKind.FixedVariable;
                    refKind = RefKind.None;
                    type = new PointerTypeSymbol(info.Type);
                }
                else
                {
                    kind = LocalDeclarationKind.RegularVariable;
                    refKind = info.IsByRef ? RefKind.Ref : RefKind.None;
                    type = info.Type;
                }

                ImmutableArray<bool> dynamicFlags;
                if (dynamicLocalMap != null && dynamicLocalMap.TryGetValue(i, out dynamicFlags))
                {
                    type = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(
                        type,
                        containingAssembly,
                        refKind,
                        dynamicFlags);
                }

                // Custom modifiers can be dropped since binding ignores custom
                // modifiers from locals and since we only need to preserve
                // the type of the original local in the generated method.
                builder.Add(new EELocalSymbol(method, EELocalSymbol.NoLocations, name, i, kind, type, refKind, isPinned, isCompilerGenerated: false, canScheduleToStack: false));
            }
        }
Exemple #35
0
 private EmptyStructTypeCache(CSharpCompilation compilation, bool dev12CompilerCompatibility)
 {
     Debug.Assert(compilation != null || !dev12CompilerCompatibility);
     _dev12CompilerCompatibility = dev12CompilerCompatibility;
     _sourceAssembly             = compilation?.SourceAssembly;
 }
Exemple #36
0
            internal void CreateSourceAssemblyForCompilation(PhpCompilation compilation)
            {
                if (compilation._lazyAssemblySymbol != null)
                {
                    return;
                }

                // TODO: lock

                Debug.Assert(_lazyExplicitReferences.IsDefault);
                Debug.Assert(_lazyCorLibrary == null);
                Debug.Assert(_lazyPhpCorLibrary == null);

                //
                var externalRefs = CorLibReferences.SelectMany(reference => compilation.Options.MetadataReferenceResolver.ResolveReference(reference, null, new MetadataReferenceProperties()))
                                   .Concat(compilation.ExternalReferences).AsImmutable();
                var assemblies = new List <AssemblySymbol>(externalRefs.Length);

                var referencesMap = new Dictionary <MetadataReference, IAssemblySymbol>();
                var metadataMap   = new Dictionary <IAssemblySymbol, MetadataReference>();
                var assembliesMap = new Dictionary <AssemblyIdentity, PEAssemblySymbol>();

                var refmodules = new List <PEModuleSymbol>();

                foreach (PortableExecutableReference pe in externalRefs)
                {
                    var symbol = PEAssemblySymbol.Create(pe);
                    if (symbol != null)
                    {
                        assemblies.Add(symbol);
                        referencesMap[pe]   = symbol;
                        metadataMap[symbol] = pe;

                        if (_lazyCorLibrary == null && symbol.IsCorLibrary)
                        {
                            _lazyCorLibrary = symbol;
                        }

                        if (_lazyPhpCorLibrary == null && symbol.IsPchpCorLibrary)
                        {
                            _lazyPhpCorLibrary = symbol;
                        }

                        // cache bound assembly symbol
                        _assembliesMap.Add(symbol.Identity, symbol);

                        // list of modules to initialize later
                        refmodules.AddRange(symbol.Modules.Cast <PEModuleSymbol>());
                    }
                }

                //
                _lazyExplicitReferences = externalRefs;
                _lazyImplicitReferences = ImmutableArray <MetadataReference> .Empty;
                _metadataMap            = metadataMap.ToImmutableDictionary();
                _referencesMap          = referencesMap.ToImmutableDictionary();

                //
                var assembly = new SourceAssemblySymbol(compilation, compilation.Options.ModuleName, compilation.Options.ModuleName);

                assembly.SetCorLibrary(_lazyCorLibrary);
                compilation._lazyAssemblySymbol = assembly;

                assembly.SourceModule.SetReferences(new ModuleReferences <AssemblySymbol>(
                                                        assemblies.Select(x => x.Identity).AsImmutable(),
                                                        assemblies.AsImmutable(),
                                                        ImmutableArray <UnifiedAssembly <AssemblySymbol> > .Empty), assembly);

                assemblies.ForEach(ass => ass.SetCorLibrary(_lazyCorLibrary));

                // recursively initialize references of referenced modules
                SetReferencesOfReferencedModules(compilation.Options.MetadataReferenceResolver, refmodules);

                // set cor types for this compilation
                if (_lazyPhpCorLibrary == null)
                {
                    throw new DllNotFoundException("pchpcor.dll not found");
                }
                if (_lazyCorLibrary == null)
                {
                    throw new DllNotFoundException("corlib not found");
                }
                compilation.CoreTypes.Update(_lazyPhpCorLibrary);
                compilation.CoreTypes.Update(_lazyCorLibrary);
            }
Exemple #37
0
 public PEAssemblyBuilder(
     SourceAssemblySymbol sourceAssembly,
     EmitOptions emitOptions,
     OutputKind outputKind,
     ModulePropertiesForSerialization serializationProperties,
     IEnumerable<ResourceDescription> manifestResources,
     Func<AssemblySymbol, AssemblyIdentity> assemblySymbolMapper = null,
     ImmutableArray<NamedTypeSymbol> additionalTypes = default(ImmutableArray<NamedTypeSymbol>))
     : base(sourceAssembly, emitOptions, outputKind, serializationProperties, manifestResources, assemblySymbolMapper, additionalTypes)
 {
 }
 public PEAssemblyBuilder(
     SourceAssemblySymbol sourceAssembly,
     EmitOptions emitOptions,
     OutputKind outputKind,
     Cci.ModulePropertiesForSerialization serializationProperties,
     IEnumerable<ResourceDescription> manifestResources)
     : base(sourceAssembly, emitOptions, outputKind, serializationProperties, manifestResources, ImmutableArray<NamedTypeSymbol>.Empty)
 {
 }
Exemple #39
0
        private static void WarnUnusedFields(CSharpCompilation compilation, DiagnosticBag diagnostics, CancellationToken cancellationToken)
        {
            SourceAssemblySymbol assembly = (SourceAssemblySymbol)compilation.Assembly;

            diagnostics.AddRange(assembly.GetUnusedFieldWarnings(cancellationToken));
        }
        public PEDeltaAssemblyBuilder(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            OutputKind outputKind,
            Cci.ModulePropertiesForSerialization serializationProperties,
            IEnumerable <ResourceDescription> manifestResources,
            EmitBaseline previousGeneration,
            IEnumerable <SemanticEdit> edits,
            Func <ISymbol, bool> isAddedSymbol)
            : base(sourceAssembly, emitOptions, outputKind, serializationProperties, manifestResources, additionalTypes: ImmutableArray <NamedTypeSymbol> .Empty)
        {
            var initialBaseline = previousGeneration.InitialBaseline;
            var context         = new EmitContext(this, null, new DiagnosticBag(), metadataOnly: false, includePrivateMembers: true);

            // Hydrate symbols from initial metadata. Once we do so it is important to reuse these symbols across all generations,
            // in order for the symbol matcher to be able to use reference equality once it maps symbols to initial metadata.
            var metadataSymbols  = GetOrCreateMetadataSymbols(initialBaseline, sourceAssembly.DeclaringCompilation);
            var metadataDecoder  = (MetadataDecoder)metadataSymbols.MetadataDecoder;
            var metadataAssembly = (PEAssemblySymbol)metadataDecoder.ModuleSymbol.ContainingAssembly;

            var matchToMetadata = new CSharpSymbolMatcher(
                metadataSymbols.AnonymousTypes,
                metadataSymbols.AnonymousDelegates,
                metadataSymbols.AnonymousDelegatesWithFixedTypes,
                sourceAssembly,
                context,
                metadataAssembly);

            CSharpSymbolMatcher?matchToPrevious = null;

            if (previousGeneration.Ordinal > 0)
            {
                RoslynDebug.AssertNotNull(previousGeneration.Compilation);
                RoslynDebug.AssertNotNull(previousGeneration.PEModuleBuilder);

                var previousAssembly = ((CSharpCompilation)previousGeneration.Compilation).SourceAssembly;
                var previousContext  = new EmitContext((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag(), metadataOnly: false, includePrivateMembers: true);

                matchToPrevious = new CSharpSymbolMatcher(
                    previousGeneration.AnonymousTypeMap,
                    previousGeneration.AnonymousDelegates,
                    previousGeneration.AnonymousDelegatesWithFixedTypes,
                    sourceAssembly: sourceAssembly,
                    sourceContext: context,
                    otherAssembly: previousAssembly,
                    otherContext: previousContext,
                    otherSynthesizedMembers: previousGeneration.SynthesizedMembers,
                    otherDeletedMembers: previousGeneration.DeletedMembers);
            }

            _previousDefinitions = new CSharpDefinitionMap(edits, metadataDecoder, matchToMetadata, matchToPrevious);
            _previousGeneration  = previousGeneration;
            _changes             = new CSharpSymbolChanges(_previousDefinitions, edits, isAddedSymbol);

            // Workaround for https://github.com/dotnet/roslyn/issues/3192.
            // When compiling state machine we stash types of awaiters and state-machine hoisted variables,
            // so that next generation can look variables up and reuse their slots if possible.
            //
            // When we are about to allocate a slot for a lifted variable while compiling the next generation
            // we map its type to the previous generation and then check the slot types that we stashed earlier.
            // If the variable type matches we reuse it. In order to compare the previous variable type with the current one
            // both need to be completely lowered (translated). Standard translation only goes one level deep.
            // Generic arguments are not translated until they are needed by metadata writer.
            //
            // In order to get the fully lowered form we run the type symbols of stashed variables through a deep translator
            // that translates the symbol recursively.
            _deepTranslator = new CSharpSymbolMatcher.DeepTranslator(sourceAssembly.GetSpecialType(SpecialType.System_Object));
        }
 /// <summary>
 /// Create a cache for computing whether or not a struct type is "empty".
 /// </summary>
 /// <param name="dev12CompilerCompatibility">Enable compatibility with the native compiler, which
 ///  ignores inaccessible fields of reference type for structs loaded from metadata.</param>
 /// <param name="compilation">if <see cref="_dev12CompilerCompatibility"/> is true, set to the compilation from
 /// which to check accessibility.</param>
 internal EmptyStructTypeCache(Compilation compilation, bool dev12CompilerCompatibility)
 {
     Debug.Assert(compilation != null || !dev12CompilerCompatibility);
     _dev12CompilerCompatibility = dev12CompilerCompatibility;
     _sourceAssembly = (SourceAssemblySymbol)compilation?.Assembly;
 }
 internal override void SetReferences(ModuleReferences<AssemblySymbol> moduleReferences, SourceAssemblySymbol originatingSourceAssemblyDebugOnly)
 {
     throw ExceptionUtilities.Unreachable;
 }
 internal override void SetReferences(ModuleReferences <AssemblySymbol> moduleReferences, SourceAssemblySymbol originatingSourceAssemblyDebugOnly)
 {
     throw ExceptionUtilities.Unreachable;
 }
        private void VerifySynthesizedDebuggableAttribute(CSharpAttributeData attribute, SourceAssemblySymbol sourceAssembly, DebugInformationKind emitDebugInfoKind, bool optimizationsEnabled)
        {
            Assert.NotEqual(DebugInformationKind.None, emitDebugInfoKind);

            var expectedDebuggingMode = DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints;

            bool emittingFullDebugInfo = emitDebugInfoKind == DebugInformationKind.Full;
            if (emittingFullDebugInfo)
            {
                expectedDebuggingMode |= DebuggableAttribute.DebuggingModes.Default;
            }

            if (!optimizationsEnabled)
            {
                expectedDebuggingMode |= DebuggableAttribute.DebuggingModes.DisableOptimizations;

                if (emittingFullDebugInfo)
                {
                    expectedDebuggingMode |= DebuggableAttribute.DebuggingModes.EnableEditAndContinue;
                }
            }

            VerifyDebuggableAttribute(attribute, sourceAssembly, expectedDebuggingMode);
        }
            internal SourceAssemblySymbol CreateSourceAssemblyForCompilation(PhpCompilation compilation)
            {
                if (compilation._lazyAssemblySymbol != null)
                {
                    return(compilation._lazyAssemblySymbol);
                }

                var resolver   = compilation.Options.MetadataReferenceResolver;
                var moduleName = compilation.MakeSourceModuleName();

                var assemblies = new List <AssemblySymbol>();

                if (_lazyExplicitReferences.IsDefault)
                {
                    //
                    var externalRefs  = compilation.ExternalReferences;
                    var referencesMap = new Dictionary <MetadataReference, IAssemblySymbolInternal>();
                    var metadataMap   = new Dictionary <IAssemblySymbol, MetadataReference>();
                    var assembliesMap = new Dictionary <AssemblyIdentity, PEAssemblySymbol>();
                    var observed      = new HashSet <AssemblyIdentity>();

                    foreach (PortableExecutableReference pe in externalRefs)
                    {
                        var peass = ((AssemblyMetadata)pe.GetMetadata()).GetAssembly();

                        if (!observed.Add(peass.Identity))
                        {
                            // already added reference identity, different metadata
                            referencesMap[pe] = _observedMetadata[peass.Identity];
                            Debug.Assert(referencesMap[pe] != null);
                            continue;
                        }

                        var symbol = _observedMetadata.TryGetOrDefault(peass.Identity) ?? PEAssemblySymbol.Create(pe, peass, isLinked: true);
                        if (symbol != null)
                        {
                            assemblies.Add(symbol);
                            referencesMap[pe]   = symbol;
                            metadataMap[symbol] = pe;

                            if (_lazyCorLibrary == null && symbol.IsCorLibrary)
                            {
                                _lazyCorLibrary = symbol;
                            }

                            if (_lazyPhpCorLibrary == null && symbol.IsPeachpieCorLibrary)
                            {
                                _lazyPhpCorLibrary = symbol;
                            }

                            // cache bound assembly symbol
                            _observedMetadata[symbol.Identity] = symbol;
                        }
                        else
                        {
                            _diagnostics.Add(Location.None, Errors.ErrorCode.ERR_MetadataFileNotFound, peass.Identity);
                        }
                    }

                    // list of modules to initialize later
                    var refmodules = assemblies.SelectMany(symbol => symbol.Modules.Cast <PEModuleSymbol>()).ToList();

                    //
                    _lazyExplicitReferences = externalRefs;
                    _lazyImplicitReferences = ImmutableArray <MetadataReference> .Empty;
                    _metadataMap            = metadataMap.ToImmutableDictionary();
                    _referencesMap          = referencesMap.ToImmutableDictionary();

                    //
                    assemblies.ForEach(ass => ass.SetCorLibrary(_lazyCorLibrary));

                    // recursively initialize references of referenced modules
                    SetReferencesOfReferencedModules(resolver, refmodules);
                }
                else
                {
                    foreach (PortableExecutableReference pe in _lazyExplicitReferences)
                    {
                        var ass = (AssemblySymbol)_referencesMap[pe];
                        Debug.Assert(ass != null);
                        assemblies.Add(ass);
                    }
                }

                //
                var assembly = new SourceAssemblySymbol(compilation, this.SimpleAssemblyName, moduleName);

                assembly.SetCorLibrary(_lazyCorLibrary);
                assembly.SourceModule.SetReferences(new ModuleReferences <AssemblySymbol>(
                                                        assemblies.Select(x => x.Identity).AsImmutable(),
                                                        assemblies.AsImmutable(),
                                                        ImmutableArray <UnifiedAssembly <AssemblySymbol> > .Empty), assembly);

                // set cor types for this compilation
                if (_lazyPhpCorLibrary == null)
                {
                    _diagnostics.Add(Location.None, Errors.ErrorCode.ERR_MetadataFileNotFound, "Peachpie.Runtime.dll");
                    throw new DllNotFoundException("Peachpie.Runtime not found");
                }
                if (_lazyCorLibrary == null)
                {
                    throw new DllNotFoundException("A corlib not found");
                }

                compilation.CoreTypes.Update(_lazyPhpCorLibrary);
                compilation.CoreTypes.Update(_lazyCorLibrary);

                //
                return(assembly);
            }
Exemple #46
0
 internal PEModuleSymbol(SourceAssemblySymbol assemblySymbol, PEModule module, MetadataImportOptions importOptions, int ordinal)
     : this((AssemblySymbol)assemblySymbol, module, importOptions, ordinal)
 {
     Debug.Assert(ordinal > 0);
 }
        private void VerifyCompilationRelaxationsAttribute(CSharpAttributeData attribute, SourceAssemblySymbol sourceAssembly, bool isSynthesized)
        {
            ModuleSymbol module = sourceAssembly.Modules[0];
            NamespaceSymbol compilerServicesNS = Get_System_Runtime_CompilerServices_NamespaceSymbol(module);

            NamedTypeSymbol compilationRelaxationsAttrType = compilerServicesNS.GetTypeMember("CompilationRelaxationsAttribute");
            var compilationRelaxationsCtor = (MethodSymbol)sourceAssembly.DeclaringCompilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_CompilationRelaxationsAttribute__ctorInt32);

            Assert.Equal(compilationRelaxationsAttrType, attribute.AttributeClass);
            Assert.Equal(compilationRelaxationsCtor, attribute.AttributeConstructor);

            int expectedArgValue = isSynthesized ? (int)CompilationRelaxations.NoStringInterning : 0;
            Assert.Equal(1, attribute.CommonConstructorArguments.Length);
            attribute.VerifyValue<int>(0, TypedConstantKind.Primitive, expectedArgValue);

            Assert.Equal(0, attribute.CommonNamedArguments.Length);
        }
        /// <summary>
        /// A helper method for ReferenceManager to set AssemblySymbols for assemblies 
        /// referenced by this module.
        /// </summary>
        internal override void SetReferences(ModuleReferences<AssemblySymbol> moduleReferences, SourceAssemblySymbol originatingSourceAssemblyDebugOnly)
        {
            base.SetReferences(moduleReferences, originatingSourceAssemblyDebugOnly);

            // Build the retargeting map
            _retargetingAssemblyMap.Clear();

            ImmutableArray<AssemblySymbol> underlyingBoundReferences = _underlyingModule.GetReferencedAssemblySymbols();
            ImmutableArray<AssemblySymbol> referencedAssemblySymbols = moduleReferences.Symbols;

            Debug.Assert(referencedAssemblySymbols.Length == moduleReferences.Identities.Length);
            Debug.Assert(referencedAssemblySymbols.Length <= underlyingBoundReferences.Length); // Linked references are filtered out.

            int i, j;
            for (i = 0, j = 0; i < referencedAssemblySymbols.Length; i++, j++)
            {
                // Skip linked assemblies for source module
                while (underlyingBoundReferences[j].IsLinked)
                {
                    j++;
                }

#if DEBUG
                var identityComparer = _underlyingModule.DeclaringCompilation.Options.AssemblyIdentityComparer;
                var definitionIdentity = ReferenceEquals(referencedAssemblySymbols[i], originatingSourceAssemblyDebugOnly) ?
                        new AssemblyIdentity(name: originatingSourceAssemblyDebugOnly.Name) :
                        referencedAssemblySymbols[i].Identity;

                Debug.Assert(identityComparer.Compare(moduleReferences.Identities[i], definitionIdentity) != AssemblyIdentityComparer.ComparisonResult.NotEquivalent);
                Debug.Assert(identityComparer.Compare(moduleReferences.Identities[i], underlyingBoundReferences[j].Identity) != AssemblyIdentityComparer.ComparisonResult.NotEquivalent);
#endif

                if (!ReferenceEquals(referencedAssemblySymbols[i], underlyingBoundReferences[j]))
                {
                    DestinationData destinationData;

                    if (!_retargetingAssemblyMap.TryGetValue(underlyingBoundReferences[j], out destinationData))
                    {
                        _retargetingAssemblyMap.Add(underlyingBoundReferences[j],
                            new DestinationData { To = referencedAssemblySymbols[i] });
                    }
                    else
                    {
                        Debug.Assert(ReferenceEquals(destinationData.To, referencedAssemblySymbols[i]));
                    }
                }
            }

#if DEBUG
            while (j < underlyingBoundReferences.Length && underlyingBoundReferences[j].IsLinked)
            {
                j++;
            }

            Debug.Assert(j == underlyingBoundReferences.Length);
#endif
        }
        // NYI: /addmodule support
        // TODO: Add tests for assembly attributes emitted into netmodules which suppress synthesized CompilationRelaxationsAttribute/RuntimeCompatibilityAttribute

        #endregion

        #region DebuggableAttribute

        private void VerifyDebuggableAttribute(CSharpAttributeData attribute, SourceAssemblySymbol sourceAssembly, DebuggableAttribute.DebuggingModes expectedDebuggingMode)
        {
            ModuleSymbol module = sourceAssembly.Modules[0];
            NamespaceSymbol diagnosticsNS = Get_System_Diagnostics_NamespaceSymbol(module);

            NamedTypeSymbol debuggableAttributeType = diagnosticsNS.GetTypeMember("DebuggableAttribute");
            var debuggableAttributeCtor = (MethodSymbol)sourceAssembly.DeclaringCompilation.GetWellKnownTypeMember(WellKnownMember.System_Diagnostics_DebuggableAttribute__ctorDebuggingModes);

            Assert.Equal(debuggableAttributeType, attribute.AttributeClass);
            Assert.Equal(debuggableAttributeCtor, attribute.AttributeConstructor);

            Assert.Equal(1, attribute.CommonConstructorArguments.Length);
            attribute.VerifyValue(0, TypedConstantKind.Enum, (int)expectedDebuggingMode);

            Assert.Equal(0, attribute.CommonNamedArguments.Length);
        }
        private static void GetConstants(
            ArrayBuilder<LocalSymbol> builder,
            MethodSymbol method,
            ImmutableArray<NamedLocalConstant> constants,
            MetadataDecoder metadataDecoder,
            ImmutableDictionary<string, ImmutableArray<bool>> dynamicLocalConstantMap,
            SourceAssemblySymbol containingAssembly)
        {
            foreach (var constant in constants)
            {
                var info = metadataDecoder.GetLocalInfo(constant.Signature);
                Debug.Assert(!info.IsByRef);
                Debug.Assert(!info.IsPinned);
                var type = info.Type;

                ImmutableArray<bool> dynamicFlags;
                if (dynamicLocalConstantMap.TryGetValue(constant.Name, out dynamicFlags))
                {
                    type = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(
                        type,
                        containingAssembly,
                        RefKind.None,
                        dynamicFlags);
                }

                var constantValue = ReinterpretConstantValue(constant.Value, type.SpecialType);
                builder.Add(new EELocalConstantSymbol(method, constant.Name, type, constantValue));
            }
        }
        /// <summary>
        /// A helper method for ReferenceManager to set AssemblySymbols for assemblies
        /// referenced by this module.
        /// </summary>
        internal override void SetReferences(ModuleReferences <AssemblySymbol> moduleReferences, SourceAssemblySymbol originatingSourceAssemblyDebugOnly)
        {
            base.SetReferences(moduleReferences, originatingSourceAssemblyDebugOnly);

            // Build the retargeting map
            _retargetingAssemblyMap.Clear();

            ImmutableArray <AssemblySymbol> underlyingBoundReferences = _underlyingModule.GetReferencedAssemblySymbols();
            ImmutableArray <AssemblySymbol> referencedAssemblySymbols = moduleReferences.Symbols;

            Debug.Assert(referencedAssemblySymbols.Length == moduleReferences.Identities.Length);
            Debug.Assert(referencedAssemblySymbols.Length <= underlyingBoundReferences.Length); // Linked references are filtered out.

            int i, j;

            for (i = 0, j = 0; i < referencedAssemblySymbols.Length; i++, j++)
            {
                // Skip linked assemblies for source module
                while (underlyingBoundReferences[j].IsLinked)
                {
                    j++;
                }

#if DEBUG
                var identityComparer   = _underlyingModule.DeclaringCompilation.Options.AssemblyIdentityComparer;
                var definitionIdentity = ReferenceEquals(referencedAssemblySymbols[i], originatingSourceAssemblyDebugOnly) ?
                                         new AssemblyIdentity(name: originatingSourceAssemblyDebugOnly.Name) :
                                         referencedAssemblySymbols[i].Identity;

                Debug.Assert(identityComparer.Compare(moduleReferences.Identities[i], definitionIdentity) != AssemblyIdentityComparer.ComparisonResult.NotEquivalent);
                Debug.Assert(identityComparer.Compare(moduleReferences.Identities[i], underlyingBoundReferences[j].Identity) != AssemblyIdentityComparer.ComparisonResult.NotEquivalent);
#endif

                if (!ReferenceEquals(referencedAssemblySymbols[i], underlyingBoundReferences[j]))
                {
                    DestinationData destinationData;

                    if (!_retargetingAssemblyMap.TryGetValue(underlyingBoundReferences[j], out destinationData))
                    {
                        _retargetingAssemblyMap.Add(underlyingBoundReferences[j],
                                                    new DestinationData {
                            To = referencedAssemblySymbols[i]
                        });
                    }
                    else
                    {
                        Debug.Assert(ReferenceEquals(destinationData.To, referencedAssemblySymbols[i]));
                    }
                }
            }

#if DEBUG
            while (j < underlyingBoundReferences.Length && underlyingBoundReferences[j].IsLinked)
            {
                j++;
            }

            Debug.Assert(j == underlyingBoundReferences.Length);
#endif
        }
        /// <summary>
        /// A helper method for ReferenceManager to set assembly identities for assemblies 
        /// referenced by this module and corresponding AssemblySymbols.
        /// </summary>
        internal override void SetReferences(ModuleReferences<AssemblySymbol> moduleReferences, SourceAssemblySymbol originatingSourceAssemblyDebugOnly = null)
        {
            Debug.Assert(moduleReferences != null);

            AssertReferencesUninitialized();

            _moduleReferences = moduleReferences;
        }
        private static void GetConstants(
            ArrayBuilder<LocalSymbol> builder,
            MethodSymbol method,
            IEnumerable<ISymUnmanagedScope> scopes,
            MetadataDecoder metadataDecoder,
            ImmutableDictionary<string, ImmutableArray<bool>> dynamicLocalConstantMap,
            SourceAssemblySymbol containingAssembly)
        {
            foreach (var scope in scopes)
            {
                foreach (var constant in scope.GetConstants())
                {
                    string name = constant.GetName();
                    object rawValue = constant.GetValue();
                    var signature = constant.GetSignature();

                    var info = metadataDecoder.GetLocalInfo(signature);
                    Debug.Assert(!info.IsByRef);
                    Debug.Assert(!info.IsPinned);
                    var type = info.Type;

                    var constantValue = PdbHelpers.GetConstantValue(type.EnumUnderlyingType(), rawValue);

                    ImmutableArray<bool> dynamicFlags;
                    if (dynamicLocalConstantMap != null && dynamicLocalConstantMap.TryGetValue(name, out dynamicFlags))
                    {
                        type = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(
                            type,
                            containingAssembly,
                            RefKind.None,
                            dynamicFlags);
                    }

                    builder.Add(new EELocalConstantSymbol(method, name, type, constantValue));
                }
            }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="underlyingAssembly">
        /// The underlying AssemblySymbol, cannot be an instance of RetargetingAssemblySymbol.
        /// </param>
        /// <param name="isLinked">
        /// Assembly is /l-ed by compilation that is using it as a reference.
        /// </param>
        public RetargetingAssemblySymbol(SourceAssemblySymbol underlyingAssembly, bool isLinked)
        {
            Debug.Assert((object)underlyingAssembly != null);

            _underlyingAssembly = underlyingAssembly;

            ModuleSymbol[] modules = new ModuleSymbol[underlyingAssembly.Modules.Length];

            modules[0] = new RetargetingModuleSymbol(this, (SourceModuleSymbol)underlyingAssembly.Modules[0]);

            for (int i = 1; i < underlyingAssembly.Modules.Length; i++)
            {
                PEModuleSymbol under = (PEModuleSymbol)underlyingAssembly.Modules[i];
                modules[i] = new PEModuleSymbol(this, under.Module, under.ImportOptions, i);
            }

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