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)); } }
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);
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); }
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); }