Beispiel #1
0
        private bool AllowImportType(EntityHandle typeHandle)
        {
            if (typeHandle.IsNil)
            {
                return(false);
            }

            if (Filter == null)
            {
                return(true);
            }

            switch (typeHandle.Kind)
            {
            case HandleKind.TypeDefinition:
                return(Filter.AllowImport(_reader.GetTypeDefinition((TypeDefinitionHandle)typeHandle), _reader));

            case HandleKind.TypeReference:
                return(true);

            case HandleKind.TypeSpecification:
                return(AllowImportType(_reader.GetGenericType((TypeSpecificationHandle)typeHandle)));

            default:
                throw new ArgumentOutOfRangeException(nameof(typeHandle));
            }
        }
Beispiel #2
0
        private BlobHandle ImportTypeSignature(BlobHandle srcHandle)
        {
            try
            {
                var blobReader  = _reader.GetBlobReader(srcHandle);
                var blobBuilder = new BlobBuilder(blobReader.Length);

                ImportTypeSignature(ref blobReader, blobBuilder);
                return(_builder.GetOrAddBlob(blobBuilder));
            }
            catch (UnknownTypeInSignature e)
            {
                if (e.Handle.Kind != HandleKind.TypeDefinition)
                {
                    throw;
                }

                var typeDef = _reader.GetTypeDefinition((TypeDefinitionHandle)e.Handle);

                if (Filter?.AllowImport(typeDef, _reader) == true)
                {
                    throw;
                }
            }
            return(default);
Beispiel #3
0
        private TypeDefinitionHandle ImportTypeDefinitionSkeleton(TypeDefinitionHandle srcHandle)
        {
            var src = _reader.GetTypeDefinition(srcHandle);

            var dstHandle = _builder.AddTypeDefinition(src.Attributes, ImportValue(src.Namespace), ImportValue(src.Name),
                                                       Import(src.BaseType), NextFieldHandle(), NextMethodHandle());

            Trace?.Invoke($"Imported {_reader.ToString(src)} -> {RowId(dstHandle):X}");

            using var _ = WithLogPrefix($"[{_reader.ToString(src)}]");

            foreach (var srcFieldHandle in src.GetFields())
            {
                var srcField = _reader.GetFieldDefinition(srcFieldHandle);

                if (Filter?.AllowImport(srcField, _reader) == false)
                {
                    Trace?.Invoke($"Not imported {_reader.ToString(srcField)}");
                    continue;
                }

                var dstFieldHandle = _builder.AddFieldDefinition(srcField.Attributes, ImportValue(srcField.Name),
                                                                 ImportSignatureWithHeader(srcField.Signature));
                _fieldDefinitionCache.Add(srcFieldHandle, dstFieldHandle);
                Trace?.Invoke($"Imported {_reader.ToString(srcFieldHandle)} -> {RowId(dstFieldHandle):X}");
            }

            var implementations = src.GetMethodImplementations()
                                  .Select(_reader.GetMethodImplementation)
                                  .Where(mi => AllowImportType(_reader.GetMethodClass(mi.MethodDeclaration)))
                                  .Select(mi => (MethodDefinitionHandle)mi.MethodBody)
                                  .ToImmutableHashSet();

            foreach (var srcMethodHandle in src.GetMethods())
            {
                var srcMethod = _reader.GetMethodDefinition(srcMethodHandle);

                if (!implementations.Contains(srcMethodHandle) && Filter?.AllowImport(srcMethod, _reader) == false)
                {
                    Trace?.Invoke($"Not imported {_reader.ToString(srcMethod)}");
                    continue;
                }

                var dstSignature = ImportSignatureWithHeader(srcMethod.Signature);

                if (dstSignature.IsNil)
                {
                    Trace?.Invoke($"Not imported because of signature {_reader.ToString(srcMethod)}");
                    continue;
                }

                var dstMethodHandle = _builder.AddMethodDefinition(srcMethod.Attributes, srcMethod.ImplAttributes,
                                                                   ImportValue(srcMethod.Name), dstSignature, -1, NextParameterHandle());
                _methodDefinitionCache.Add(srcMethodHandle, dstMethodHandle);
                Trace?.Invoke($"Imported {_reader.ToString(srcMethod)} -> {RowId(dstMethodHandle):X}");

                using var __ = WithLogPrefix($"[{_reader.ToString(srcMethod)}]");
                foreach (var srcParameterHandle in srcMethod.GetParameters())
                {
                    var srcParameter       = _reader.GetParameter(srcParameterHandle);
                    var dstParameterHandle = _builder.AddParameter(srcParameter.Attributes,
                                                                   ImportValue(srcParameter.Name), srcParameter.SequenceNumber);
                    _parameterCache.Add(srcParameterHandle, dstParameterHandle);
                    Trace?.Invoke($"Imported {_reader.ToString(srcParameter)} -> {RowId(dstParameterHandle):X}");

                    var defaultValue = srcParameter.GetDefaultValue();

                    if (!defaultValue.IsNil)
                    {
                        ImportDefaultValue(defaultValue, dstParameterHandle);
                    }


                    if (!srcParameter.GetMarshallingDescriptor().IsNil)
                    {
                        _builder.AddMarshallingDescriptor(dstParameterHandle, ImportValue(srcParameter.GetMarshallingDescriptor()));
                        Trace?.Invoke($"Imported marshalling descriptor {_reader.ToString(srcParameter.GetMarshallingDescriptor())}");
                    }
                }
            }

            return(dstHandle);
        }
Beispiel #4
0
        public ReservedBlob <GuidHandle> Import()
        {
            if (_reader.IsAssembly)
            {
                var srcAssembly = _reader.GetAssemblyDefinition();

                _builder.AddAssembly(ImportValue(srcAssembly.Name), srcAssembly.Version,
                                     ImportValue(srcAssembly.Culture),
                                     ImportValue(srcAssembly.PublicKey), srcAssembly.Flags, srcAssembly.HashAlgorithm);
                Debug?.Invoke($"Imported assembly {_reader.ToString(srcAssembly)}");
            }

            var srcModule = _reader.GetModuleDefinition();

            var mvidBlob = _builder.ReserveGuid();

            _builder.AddModule(srcModule.Generation, ImportValue(srcModule.Name), mvidBlob.Handle,
                               ImportValue(srcModule.GenerationId),
                               ImportValue(srcModule.BaseGenerationId));
            Debug?.Invoke($"Imported module {_reader.ToString(srcModule)}");

            Debug?.Invoke($"Importing assembly files");
            foreach (var srcHandle in _reader.AssemblyFiles)
            {
                Import(srcHandle);
            }

            var index = 1;

            Debug?.Invoke($"Preparing type list for import");

            var checker = new CachedAttributeChecker();

            foreach (var srcHandle in _reader.TypeDefinitions)
            {
                bool shouldImport;

                var src = _reader.GetTypeDefinition(srcHandle);
                if (checker.HasAttribute(_reader, src, AttributeNames.Embedded) &&
                    checker.HasAttribute(_reader, src, AttributeNames.CompilerGenerated))
                {
                    Trace?.Invoke($"Embedded type found {_reader.ToString(srcHandle)}");
                    shouldImport = true;
                }
                else
                {
                    shouldImport = Filter?.AllowImport(_reader.GetTypeDefinition(srcHandle), _reader) != false;
                }

                if (shouldImport)
                {
                    _typeDefinitionCache[srcHandle] = MetadataTokens.TypeDefinitionHandle(index++);
                }
                else
                {
                    Trace?.Invoke($"Type filtered and will not be imported {_reader.ToString(srcHandle)}");
                }
            }

            Debug?.Invoke($"Importing type definitions");
            foreach (var srcHandle in _reader.TypeDefinitions.Where(_typeDefinitionCache.ContainsKey))
            {
                var dstHandle = ImportTypeDefinitionSkeleton(srcHandle);
                if (dstHandle != _typeDefinitionCache[srcHandle])
                {
                    throw new Exception("WTF: type handle mismatch");
                }
            }

            Debug?.Invoke($"Importing type definition accessories");
            foreach (var(srcHandle, dstHandle) in _typeDefinitionCache)
            {
                ImportTypeDefinitionAccessories(srcHandle, dstHandle);
            }

            Debug?.Invoke($"Importing method definition accessories");
            foreach (var(srcHandle, dstHandle) in _methodDefinitionCache)
            {
                ImportMethodDefinitionAccessories(srcHandle, dstHandle);
            }

            Debug?.Invoke($"Importing field definition accessories");
            foreach (var(srcHandle, dstHandle) in _fieldDefinitionCache)
            {
                ImportFieldDefinitionAccessories(srcHandle, dstHandle);
            }

            Debug?.Invoke($"Importing nested classes");
            var nestedTypes = _typeDefinitionCache
                              .Select(kv => Tuple.Create(kv.Value, _reader.GetTypeDefinition(kv.Key).GetNestedTypes()))
                              .SelectMany(x => x.Item2.Select(y => Tuple.Create(x.Item1, y, Import(y))))
                              .Where(x => !x.Item3.IsNil)
                              .OrderBy(x => RowId(x.Item3))
                              .ToList();

            foreach (var(dstHandle, srcNested, dstNested) in nestedTypes)
            {
                _builder.AddNestedType(dstNested, dstHandle);
                Trace?.Invoke($"Imported nested type {_reader.ToString(srcNested)} -> {RowId(dstNested):X}");
            }


            var generic = _typeDefinitionCache
                          .Select(kv => Tuple.Create((EntityHandle)kv.Value, _reader.GetTypeDefinition(kv.Key).GetGenericParameters()))
                          .Concat(_methodDefinitionCache
                                  .Select(kv => Tuple.Create((EntityHandle)kv.Value, _reader.GetMethodDefinition(kv.Key).GetGenericParameters())))
                          .OrderBy(x => CodedIndex.TypeOrMethodDef(x.Item1))
                          .ToList();

            Debug?.Invoke($"Importing generic constraints");
            foreach (var(dstHandle, genericParams) in generic)
            {
                ImportGenericConstraints(dstHandle, genericParams);
            }

            Debug?.Invoke($"Importing custom attributes");
            foreach (var src in _reader.CustomAttributes)
            {
                Import(src);
            }

            Debug?.Invoke($"Importing declarative security attributes");
            foreach (var src in _reader.DeclarativeSecurityAttributes)
            {
                Import(src);
            }

            Debug?.Invoke($"Importing exported types");
            foreach (var src in _reader.ExportedTypes)
            {
                Import(src);
            }

            Debug?.Invoke($"Importing done");

            return(mvidBlob);
        }