Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        private static IReadOnlyDictionary <AnonymousTypeKey, AnonymousTypeValue> GetAnonymousTypeMapFromMetadata(
            MetadataReader reader,
            Symbols.Metadata.PE.MetadataDecoder metadataDecoder)
        {
            var result = new Dictionary <AnonymousTypeKey, AnonymousTypeValue>();

            foreach (var handle in reader.TypeDefinitions)
            {
                var def = reader.GetTypeDefinition(handle);
                if (!def.Namespace.IsNil)
                {
                    continue;
                }
                if (!reader.StringComparer.StartsWith(def.Name, GeneratedNames.AnonymousNamePrefix))
                {
                    continue;
                }
                var   metadataName = reader.GetString(def.Name);
                short arity;
                var   name = MetadataHelpers.InferTypeArityAndUnmangleMetadataName(metadataName, out arity);
                int   index;
                if (GeneratedNames.TryParseAnonymousTypeTemplateName(name, out index))
                {
                    var builder = ArrayBuilder <AnonymousTypeKeyField> .GetInstance();

                    if (TryGetAnonymousTypeKey(reader, def, builder))
                    {
                        var type  = (NamedTypeSymbol)metadataDecoder.GetTypeOfToken(handle);
                        var key   = new AnonymousTypeKey(builder.ToImmutable());
                        var value = new AnonymousTypeValue(name, index, type);
                        result.Add(key, value);
                    }
                    builder.Free();
                }
            }
            return(result);
        }